From d1681e44dc5e1e20052f70f74fabaf49aeda2ee9 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 04:52:19 +0000 Subject: import glusterfs-3.12.2-18.el7 --- diff --git a/.gitignore b/.gitignore index 3ae0b80..138577f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/glusterfs-3.8.4.tar.gz +SOURCES/glusterfs-3.12.2.tar.gz diff --git a/.glusterfs.metadata b/.glusterfs.metadata index 91e524d..91321f9 100644 --- a/.glusterfs.metadata +++ b/.glusterfs.metadata @@ -1 +1 @@ -d2e9a4838a1bc2b4412089c5a71040fed5198079 SOURCES/glusterfs-3.8.4.tar.gz +561c9bf5aa8fb767dc51fc20a7849c8888a2e5cd SOURCES/glusterfs-3.12.2.tar.gz diff --git a/SOURCES/0002-glusterd-fix-op-versions-for-RHS-backwards-compatabi.patch b/SOURCES/0002-glusterd-fix-op-versions-for-RHS-backwards-compatabi.patch index 6e4d57e..6be9ef0 100644 --- a/SOURCES/0002-glusterd-fix-op-versions-for-RHS-backwards-compatabi.patch +++ b/SOURCES/0002-glusterd-fix-op-versions-for-RHS-backwards-compatabi.patch @@ -1,7 +1,8 @@ -From 871addd0495680e6b6406c385a0415528330ac80 Mon Sep 17 00:00:00 2001 +From 804ac051cc8be7ff0bf0791c0b53db04edce0926 Mon Sep 17 00:00:00 2001 From: Kaushal M Date: Thu, 11 Jun 2015 18:21:17 +0530 -Subject: [PATCH 02/86] glusterd: fix op-versions for RHS backwards compatability +Subject: [PATCH 02/74] glusterd: fix op-versions for RHS backwards + compatability Backport of https://code.engineering.redhat.com/gerrit/#/c/60485/ @@ -14,26 +15,27 @@ Change-Id: Icb282444da179b12fbd6ed9f491514602f1a38c2 Signed-off-by: Atin Mukherjee Reviewed-on: https://code.engineering.redhat.com/gerrit/70348 --- - libglusterfs/src/globals.h | 45 +++-- - xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 8 +- - xlators/mgmt/glusterd/src/glusterd-handler.c | 12 +- - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 16 +- - xlators/mgmt/glusterd/src/glusterd-peer-utils.c | 8 +- - xlators/mgmt/glusterd/src/glusterd-rebalance.c | 4 +- - xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 4 +- - xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 6 +- - xlators/mgmt/glusterd/src/glusterd-sm.c | 2 +- - .../mgmt/glusterd/src/glusterd-snapshot-utils.c | 12 +- - xlators/mgmt/glusterd/src/glusterd-snapshot.c | 4 +- - xlators/mgmt/glusterd/src/glusterd-store.c | 25 ++-- - xlators/mgmt/glusterd/src/glusterd-syncop.c | 2 +- - xlators/mgmt/glusterd/src/glusterd-utils.c | 8 +- - xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 12 +- - xlators/mgmt/glusterd/src/glusterd-volume-set.c | 184 ++++++++++---------- - 16 files changed, 181 insertions(+), 171 deletions(-) + libglusterfs/src/globals.h | 45 +++-- + xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 8 +- + xlators/mgmt/glusterd/src/glusterd-handler.c | 14 +- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 16 +- + xlators/mgmt/glusterd/src/glusterd-peer-utils.c | 8 +- + xlators/mgmt/glusterd/src/glusterd-rebalance.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 6 +- + xlators/mgmt/glusterd/src/glusterd-sm.c | 2 +- + .../mgmt/glusterd/src/glusterd-snapshot-utils.c | 12 +- + xlators/mgmt/glusterd/src/glusterd-snapshot.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-store.c | 27 +-- + xlators/mgmt/glusterd/src/glusterd-syncop.c | 2 +- + xlators/mgmt/glusterd/src/glusterd-tier.c | 2 +- + xlators/mgmt/glusterd/src/glusterd-utils.c | 8 +- + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 12 +- + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 198 +++++++++++---------- + 17 files changed, 193 insertions(+), 179 deletions(-) diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h -index c656bbf..5853e46 100644 +index 365183d..bd7cffe 100644 --- a/libglusterfs/src/globals.h +++ b/libglusterfs/src/globals.h @@ -18,23 +18,28 @@ @@ -95,9 +97,9 @@ index c656bbf..5853e46 100644 #define GD_OP_VERSION_3_7_0 30700 /* Op-version for GlusterFS 3.7.0 */ -@@ -68,8 +79,6 @@ +@@ -90,8 +101,6 @@ - #define GD_OP_VERSION_3_8_0 30800 /* Op-version for GlusterFS 3.8.0 */ + #define GD_OP_VERSION_3_12_2 31202 /* Op-version for GlusterFS 3.12.2 */ -#define GD_OP_VER_PERSISTENT_AFR_XATTRS GD_OP_VERSION_3_6_0 - @@ -105,10 +107,10 @@ index c656bbf..5853e46 100644 /* THIS */ diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c -index a90114a..7522003 100644 +index 6d17ff4..e88fa3f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c -@@ -1377,7 +1377,7 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, +@@ -1379,7 +1379,7 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ @@ -117,7 +119,7 @@ index a90114a..7522003 100644 brick_mount_dir = NULL; snprintf (key, sizeof(key), "brick%d.mount_dir", i); -@@ -1860,7 +1860,7 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict) +@@ -1926,7 +1926,7 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict) /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ @@ -126,7 +128,7 @@ index a90114a..7522003 100644 ret = glusterd_get_brick_mount_dir (brickinfo->path, brickinfo->hostname, brickinfo->mount_dir); -@@ -2162,12 +2162,12 @@ glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr) +@@ -2266,12 +2266,12 @@ glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr) } /* Check if the connected clients are all of version @@ -142,10 +144,10 @@ index a90114a..7522003 100644 ret = gf_asprintf (op_errstr, "Volume %s has one or " "more connected clients of a version" diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c -index bf62290..8ca9d2a 100644 +index 185186a..af9a796 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c -@@ -752,7 +752,7 @@ glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx, +@@ -754,7 +754,7 @@ glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx, } /* Based on the op_version, acquire a cluster or mgmt_v3 lock */ @@ -154,7 +156,7 @@ index bf62290..8ca9d2a 100644 ret = glusterd_lock (MY_UUID); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, -@@ -802,7 +802,7 @@ glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx, +@@ -804,7 +804,7 @@ glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx, local_locking_done: /* If no volname is given as a part of the command, locks will * not be held, hence sending stage event. */ @@ -163,7 +165,7 @@ index bf62290..8ca9d2a 100644 event_type = GD_OP_EVENT_START_LOCK; else { txn_op_info.state.state = GD_OP_STATE_LOCK_SENT; -@@ -834,7 +834,7 @@ out: +@@ -836,7 +836,7 @@ out: if (locked && ret) { /* Based on the op-version, we release the * cluster or mgmt_v3 lock */ @@ -172,7 +174,7 @@ index bf62290..8ca9d2a 100644 glusterd_unlock (MY_UUID); else { ret = glusterd_mgmt_v3_unlock (volname, MY_UUID, -@@ -4359,11 +4359,11 @@ __glusterd_handle_status_volume (rpcsvc_request_t *req) +@@ -4313,11 +4313,11 @@ __glusterd_handle_status_volume (rpcsvc_request_t *req) } if ((cmd & GF_CLI_STATUS_SNAPD) && @@ -186,8 +188,17 @@ index bf62290..8ca9d2a 100644 ret = -1; goto out; } -@@ -5219,7 +5219,7 @@ __glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, - glusterd_friend_sm_state_name_get (peerinfo->state.state)); +@@ -4337,7 +4337,7 @@ __glusterd_handle_status_volume (rpcsvc_request_t *req) + snprintf (err_str, sizeof (err_str), "The cluster is operating " + "at a lesser version than %d. Getting the status of " + "tierd is not allowed in this state", +- GD_OP_VERSION_3_6_0); ++ GD_OP_VERSION_RHS_3_0); + ret = -1; + goto out; + } +@@ -6287,7 +6287,7 @@ __glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, + glusterd_friend_sm_state_name_get (peerinfo->state.state)); if (peerinfo->connected) { - if (conf->op_version < GD_OP_VERSION_3_6_0) { @@ -196,10 +207,10 @@ index bf62290..8ca9d2a 100644 if (!gf_uuid_is_null (uuid) && !gf_uuid_compare (peerinfo->uuid, uuid)) diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index e9f261c..9194077 100644 +index 7bb3d53..6d5b8cf 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -192,7 +192,7 @@ glusterd_generate_txn_id (dict_t *dict, uuid_t **txn_id) +@@ -191,7 +191,7 @@ glusterd_generate_txn_id (dict_t *dict, uuid_t **txn_id) if (!*txn_id) goto out; @@ -208,7 +219,7 @@ index e9f261c..9194077 100644 gf_uuid_copy (**txn_id, priv->global_txn_id); else gf_uuid_generate (**txn_id); -@@ -1621,11 +1621,11 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr) +@@ -1824,11 +1824,11 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr) } if ((cmd & GF_CLI_STATUS_SNAPD) && @@ -222,7 +233,7 @@ index e9f261c..9194077 100644 ret = -1; goto out; } -@@ -3475,7 +3475,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) +@@ -3872,7 +3872,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) continue; /* Based on the op_version, acquire a cluster or mgmt_v3 lock */ @@ -231,7 +242,7 @@ index e9f261c..9194077 100644 proc = &peerinfo->mgmt->proctable [GLUSTERD_MGMT_CLUSTER_LOCK]; if (proc->fn) { -@@ -3586,7 +3586,7 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx) +@@ -3983,7 +3983,7 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx) continue; /* Based on the op_version, * release the cluster or mgmt_v3 lock */ @@ -240,7 +251,7 @@ index e9f261c..9194077 100644 proc = &peerinfo->mgmt->proctable [GLUSTERD_MGMT_CLUSTER_UNLOCK]; if (proc->fn) { -@@ -4612,7 +4612,7 @@ glusterd_op_modify_op_ctx (glusterd_op_t op, void *ctx) +@@ -5010,7 +5010,7 @@ glusterd_op_modify_op_ctx (glusterd_op_t op, void *ctx) count = brick_index_max + other_count + 1; /* @@ -249,7 +260,7 @@ index e9f261c..9194077 100644 * rdma port in older key. Changing that value from here * to support backward compatibility */ -@@ -4631,7 +4631,7 @@ glusterd_op_modify_op_ctx (glusterd_op_t op, void *ctx) +@@ -5029,7 +5029,7 @@ glusterd_op_modify_op_ctx (glusterd_op_t op, void *ctx) } } glusterd_volinfo_find (volname, &volinfo); @@ -258,7 +269,7 @@ index e9f261c..9194077 100644 volinfo->transport_type == GF_TRANSPORT_RDMA) { ret = glusterd_op_modify_port_key (op_ctx, brick_index_max); -@@ -5267,7 +5267,7 @@ glusterd_op_txn_complete (uuid_t *txn_id) +@@ -5670,7 +5670,7 @@ glusterd_op_txn_complete (uuid_t *txn_id) glusterd_op_clear_errstr (); /* Based on the op-version, we release the cluster or mgmt_v3 lock */ @@ -268,10 +279,10 @@ index e9f261c..9194077 100644 /* unlock cant/shouldnt fail here!! */ if (ret) diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c -index 4131296..72d6b17 100644 +index 31f9e87..592aa16 100644 --- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c -@@ -555,7 +555,7 @@ out: +@@ -554,7 +554,7 @@ out: * @prefix. All the parameters are compulsory. * * The complete address list is added to the dict only if the cluster op-version @@ -280,7 +291,7 @@ index 4131296..72d6b17 100644 */ int gd_add_friend_to_dict (glusterd_peerinfo_t *friend, dict_t *dict, -@@ -610,7 +610,7 @@ gd_add_friend_to_dict (glusterd_peerinfo_t *friend, dict_t *dict, +@@ -609,7 +609,7 @@ gd_add_friend_to_dict (glusterd_peerinfo_t *friend, dict_t *dict, goto out; } @@ -289,7 +300,7 @@ index 4131296..72d6b17 100644 ret = 0; goto out; } -@@ -800,7 +800,7 @@ gd_update_peerinfo_from_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict, +@@ -799,7 +799,7 @@ gd_update_peerinfo_from_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict, GF_FREE (peerinfo->hostname); peerinfo->hostname = gf_strdup (hostname); @@ -298,7 +309,7 @@ index 4131296..72d6b17 100644 ret = 0; goto out; } -@@ -914,7 +914,7 @@ gd_add_peer_hostnames_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict, +@@ -913,7 +913,7 @@ gd_add_peer_hostnames_to_dict (glusterd_peerinfo_t *peerinfo, dict_t *dict, conf = this->private; GF_VALIDATE_OR_GOTO (this->name, (conf != NULL), out); @@ -308,10 +319,10 @@ index 4131296..72d6b17 100644 goto out; } diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c -index 35fa462..9ecbdfb 100644 +index fcafb5b..76191c4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c +++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c -@@ -683,13 +683,13 @@ glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr) +@@ -678,13 +678,13 @@ glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr) case GF_DEFRAG_CMD_START: case GF_DEFRAG_CMD_START_LAYOUT_FIX: /* Check if the connected clients are all of version @@ -328,10 +339,10 @@ index 35fa462..9ecbdfb 100644 ret = gf_asprintf (op_errstr, "Volume %s has one or " "more connected clients of a version" diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -index 2b21207..7bd1de3 100644 +index 08a6df0..18fc741 100644 --- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -@@ -432,7 +432,7 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, +@@ -305,7 +305,7 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, if (ret) goto out; @@ -340,7 +351,7 @@ index 2b21207..7bd1de3 100644 /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ -@@ -572,7 +572,7 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, +@@ -389,7 +389,7 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ @@ -350,10 +361,10 @@ index 2b21207..7bd1de3 100644 if (ret) { gf_msg (this->name, GF_LOG_ERROR, errno, diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -index 890ccf0..d37a8f2 100644 +index ab52e8d..86e1256 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -@@ -292,11 +292,11 @@ __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, +@@ -302,11 +302,11 @@ __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, * we need to add the new hostname to the peer. * * This addition should only be done for cluster op-version >= @@ -367,7 +378,7 @@ index 890ccf0..d37a8f2 100644 (gf_uuid_compare (rsp.uuid, peerinfo->uuid) == 0)) { ctx = ((call_frame_t *)myframe)->local; /* Presence of ctx->req implies this probe was started by a cli -@@ -1583,7 +1583,7 @@ glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this, +@@ -1591,7 +1591,7 @@ glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this, goto out; } @@ -377,10 +388,10 @@ index 890ccf0..d37a8f2 100644 if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c -index c1fb318..2925788 100644 +index f83e851..6c56837 100644 --- a/xlators/mgmt/glusterd/src/glusterd-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-sm.c -@@ -933,7 +933,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx) +@@ -942,7 +942,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx) /* Compare missed_snapshot list with the peer * * if volume comparison is successful */ if ((op_ret == 0) && @@ -390,7 +401,7 @@ index c1fb318..2925788 100644 if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c -index 36adb7f..a4660c7 100644 +index 9e2a75f..6fb49c3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c @@ -468,7 +468,7 @@ gd_add_brick_snap_details_to_dict (dict_t *dict, char *prefix, @@ -441,10 +452,10 @@ index 36adb7f..a4660c7 100644 goto out; } diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c -index 6e4894b..85f2a3f 100644 +index 31f4d95..6306d29 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c -@@ -9219,7 +9219,7 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req) +@@ -9341,7 +9341,7 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req) goto out; } @@ -453,7 +464,7 @@ index 6e4894b..85f2a3f 100644 snprintf (err_str, sizeof (err_str), "Cluster operating version" " is lesser than the supported version " "for a snapshot"); -@@ -9227,7 +9227,7 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req) +@@ -9349,7 +9349,7 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req) gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_UNSUPPORTED_VERSION, "%s (%d < %d)", err_str, @@ -463,10 +474,10 @@ index 6e4894b..85f2a3f 100644 goto out; } diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c -index 8cf3b5d..5a86aee 100644 +index 4d22b63..229391a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c -@@ -306,7 +306,7 @@ gd_store_brick_snap_details_write (int fd, glusterd_brickinfo_t *brickinfo) +@@ -302,7 +302,7 @@ gd_store_brick_snap_details_write (int fd, glusterd_brickinfo_t *brickinfo) GF_VALIDATE_OR_GOTO (this->name, (fd > 0), out); GF_VALIDATE_OR_GOTO (this->name, (brickinfo != NULL), out); @@ -475,7 +486,7 @@ index 8cf3b5d..5a86aee 100644 ret = 0; goto out; } -@@ -792,7 +792,7 @@ glusterd_volume_write_snap_details (int fd, glusterd_volinfo_t *volinfo) +@@ -799,7 +799,7 @@ glusterd_volume_write_snap_details (int fd, glusterd_volinfo_t *volinfo) GF_VALIDATE_OR_GOTO (this->name, (fd > 0), out); GF_VALIDATE_OR_GOTO (this->name, (volinfo != NULL), out); @@ -484,7 +495,16 @@ index 8cf3b5d..5a86aee 100644 ret = 0; goto out; } -@@ -2193,7 +2193,7 @@ glusterd_store_retrieve_snapd (glusterd_volinfo_t *volinfo) +@@ -968,7 +968,7 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo) + goto out; + } + +- if (conf->op_version >= GD_OP_VERSION_3_6_0) { ++ if (conf->op_version >= GD_OP_VERSION_RHS_3_0) { + snprintf (buf, sizeof (buf), "%d", volinfo->disperse_count); + ret = gf_store_save_value (fd, + GLUSTERD_STORE_KEY_VOL_DISPERSE_CNT, +@@ -2339,7 +2339,7 @@ glusterd_store_retrieve_snapd (glusterd_volinfo_t *volinfo) conf = THIS->private; GF_ASSERT (volinfo); @@ -493,7 +513,7 @@ index 8cf3b5d..5a86aee 100644 ret = 0; goto out; } -@@ -2201,15 +2201,16 @@ glusterd_store_retrieve_snapd (glusterd_volinfo_t *volinfo) +@@ -2347,15 +2347,16 @@ glusterd_store_retrieve_snapd (glusterd_volinfo_t *volinfo) /* * This is needed for upgrade situations. Say a volume is created with * older version of glusterfs and upgraded to a glusterfs version equal @@ -520,10 +540,10 @@ index 8cf3b5d..5a86aee 100644 if (!dict_get_str_boolean (volinfo->dict, "features.uss", _gf_false)) { diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c -index 7c5721f..a233f34 100644 +index 4be3d97..066c7f9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-syncop.c +++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c -@@ -1798,7 +1798,7 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req) +@@ -1863,7 +1863,7 @@ gd_sync_task_begin (dict_t *op_ctx, rpcsvc_request_t * req) goto out; } @@ -532,11 +552,24 @@ index 7c5721f..a233f34 100644 cluster_lock = _gf_true; /* Based on the op_version, acquire a cluster or mgmt_v3 lock */ +diff --git a/xlators/mgmt/glusterd/src/glusterd-tier.c b/xlators/mgmt/glusterd/src/glusterd-tier.c +index 45f6ac3..28f02e75 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-tier.c ++++ b/xlators/mgmt/glusterd/src/glusterd-tier.c +@@ -921,7 +921,7 @@ glusterd_op_stage_tier (dict_t *dict, char **op_errstr, dict_t *rsp_dict) + * 'force' + */ + ret = glusterd_check_client_op_version_support +- (volname, GD_OP_VERSION_3_6_0, NULL); ++ (volname, GD_OP_VERSION_RHS_3_0, NULL); + if (ret) { + ret = gf_asprintf (op_errstr, "Volume %s has one or " + "more connected clients of a version" diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c -index 5bfa809..46a3509 100644 +index e38f963..f34e218 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c -@@ -10228,10 +10228,10 @@ gd_update_volume_op_versions (glusterd_volinfo_t *volinfo) +@@ -11758,10 +11758,10 @@ gd_update_volume_op_versions (glusterd_volinfo_t *volinfo) } if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE) { @@ -552,10 +585,10 @@ index 5bfa809..46a3509 100644 return; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -index 72e14b0..2b1c50a 100644 +index 9d34073..834acab 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -@@ -1283,7 +1283,7 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr, +@@ -1325,7 +1325,7 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr, /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ @@ -564,7 +597,7 @@ index 72e14b0..2b1c50a 100644 ret = glusterd_get_brick_mount_dir (brick_info->path, brick_info->hostname, brick_info->mount_dir); -@@ -1569,7 +1569,7 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr, +@@ -1611,7 +1611,7 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr, /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ @@ -573,7 +606,7 @@ index 72e14b0..2b1c50a 100644 if (strlen(brickinfo->mount_dir) < 1) { ret = glusterd_get_brick_mount_dir (brickinfo->path, brickinfo->hostname, -@@ -2253,10 +2253,10 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) +@@ -2320,10 +2320,10 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) "redundancy count for volume %s", volname); goto out; } @@ -586,7 +619,7 @@ index 72e14b0..2b1c50a 100644 ret = -1; goto out; } -@@ -2359,7 +2359,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) +@@ -2428,7 +2428,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ @@ -595,7 +628,7 @@ index 72e14b0..2b1c50a 100644 brick_mount_dir = NULL; snprintf (key, sizeof(key), "brick%d.mount_dir", i); ret = dict_get_str (dict, key, &brick_mount_dir); -@@ -2545,7 +2545,7 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) +@@ -2623,7 +2623,7 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) /* A bricks mount dir is required only by snapshots which were * introduced in gluster-3.6.0 */ @@ -605,10 +638,10 @@ index 72e14b0..2b1c50a 100644 brick_list) { brick_count++; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c -index 1e24ada..be624b7 100644 +index 14b9e21..982275e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c -@@ -1061,7 +1061,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1263,7 +1263,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "cluster.subvols-per-directory", .voltype = "cluster/distribute", .option = "directory-layout-spread", @@ -617,7 +650,7 @@ index 1e24ada..be624b7 100644 .validate_fn = validate_subvols_per_directory, .flags = OPT_FLAG_CLIENT_OPT }, -@@ -1073,27 +1073,27 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1275,27 +1275,27 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "cluster.rsync-hash-regex", .voltype = "cluster/distribute", .type = NO_DOC, @@ -649,7 +682,7 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT, }, { .key = "cluster.rebal-throttle", -@@ -1125,12 +1125,12 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1327,12 +1327,12 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "cluster/nufa", .option = "local-volume-name", .type = NO_DOC, @@ -664,7 +697,7 @@ index 1e24ada..be624b7 100644 }, /* Switch xlator options (Distribute special case) */ -@@ -1138,14 +1138,14 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1340,14 +1340,14 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "cluster/distribute", .option = "!switch", .type = NO_DOC, @@ -681,7 +714,7 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT }, -@@ -1273,18 +1273,18 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1475,18 +1475,18 @@ struct volopt_map_entry glusterd_volopt_map[] = { }, { .key = "cluster.readdir-failover", .voltype = "cluster/replicate", @@ -703,7 +736,7 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT }, { .key = "cluster.heal-wait-queue-length", -@@ -1360,45 +1360,45 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1562,45 +1562,45 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "diagnostics.brick-logger", .voltype = "debug/io-stats", .option = "!logger", @@ -757,16 +790,18 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT }, { .key = "diagnostics.stats-dump-interval", -@@ -1483,7 +1483,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { - }, - { .key = "performance.least-rate-limit", +@@ -1688,6 +1688,10 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "performance/io-threads", -- .op_version = 2 -+ .op_version = 1 + .op_version = 1 }, ++ { .key = "performance.least-rate-limit", ++ .voltype = "performance/io-threads", ++ .op_version = 1 ++ }, /* Other perf xlators' options */ -@@ -1502,7 +1502,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { + { .key = "performance.cache-size", +@@ -1705,7 +1709,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "performance.nfs.flush-behind", .voltype = "performance/write-behind", .option = "flush-behind", @@ -775,7 +810,7 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT }, { .key = "performance.write-behind-window-size", -@@ -1528,43 +1528,43 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1731,43 +1735,43 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "performance.nfs.write-behind-window-size", .voltype = "performance/write-behind", .option = "cache-size", @@ -826,16 +861,25 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT }, { .key = "performance.read-ahead-page-count", -@@ -1594,7 +1594,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { - .voltype = "encryption/crypt", - .option = "!feat", - .value = "off", -- .op_version = 3, +@@ -1815,29 +1819,29 @@ struct volopt_map_entry glusterd_volopt_map[] = { + + /* Crypt xlator options */ + +- { .key = "features.encryption", +- .voltype = "encryption/crypt", +- .option = "!feat", +- .value = "off", +- .op_version = 3, +- .description = "enable/disable client-side encryption for " ++ { .key = "features.encryption", ++ .voltype = "encryption/crypt", ++ .option = "!feat", ++ .value = "off", + .op_version = GD_OP_VERSION_RHS_3_0, - .description = "enable/disable client-side encryption for " ++ .description = "enable/disable client-side encryption for " "the volume.", - .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT -@@ -1602,17 +1602,17 @@ struct volopt_map_entry glusterd_volopt_map[] = { + .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT + }, { .key = "encryption.master-key", .voltype = "encryption/crypt", @@ -856,7 +900,7 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT }, -@@ -1655,7 +1655,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1881,7 +1885,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "network.remote-dio", .voltype = "protocol/client", .option = "filter-O_DIRECT", @@ -865,16 +909,16 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT }, { .key = "client.own-thread", -@@ -1666,7 +1666,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1892,7 +1896,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { }, { .key = "client.event-threads", .voltype = "protocol/client", - .op_version = GD_OP_VERSION_3_7_0, + .op_version = GD_OP_VERSION_RHS_3_0_4, }, - - /* Server xlator options */ -@@ -1710,17 +1710,17 @@ struct volopt_map_entry glusterd_volopt_map[] = { + { .key = "client.tcp-user-timeout", + .voltype = "protocol/client", +@@ -1960,17 +1964,17 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "server.root-squash", .voltype = "protocol/server", .option = "root-squash", @@ -895,7 +939,7 @@ index 1e24ada..be624b7 100644 }, { .key = "server.statedump-path", .voltype = "protocol/server", -@@ -1731,7 +1731,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -1981,7 +1985,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "protocol/server", .option = "rpc.outstanding-rpc-limit", .type = GLOBAL_DOC, @@ -904,7 +948,7 @@ index 1e24ada..be624b7 100644 }, { .key = "features.lock-heal", .voltype = "protocol/server", -@@ -1757,11 +1757,11 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2007,11 +2011,11 @@ struct volopt_map_entry glusterd_volopt_map[] = { .option = "!ssl-allow", .value = "*", .type = NO_DOC, @@ -918,7 +962,7 @@ index 1e24ada..be624b7 100644 }, { .key = "server.dynamic-auth", .voltype = "protocol/server", -@@ -1770,11 +1770,11 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2020,11 +2024,11 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "client.send-gids", .voltype = "protocol/client", .type = NO_DOC, @@ -932,16 +976,16 @@ index 1e24ada..be624b7 100644 }, { .key = "server.own-thread", .voltype = "protocol/server", -@@ -1784,7 +1784,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2034,7 +2038,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { }, { .key = "server.event-threads", .voltype = "protocol/server", - .op_version = GD_OP_VERSION_3_7_0, + .op_version = GD_OP_VERSION_RHS_3_0_4, }, - - /* Generic transport options */ -@@ -1811,12 +1811,12 @@ struct volopt_map_entry glusterd_volopt_map[] = { + { .key = "server.tcp-user-timeout", + .voltype = "protocol/server", +@@ -2095,12 +2099,12 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = SSL_CERT_DEPTH_OPT, .voltype = "rpc-transport/socket", .option = "!ssl-cert-depth", @@ -956,17 +1000,19 @@ index 1e24ada..be624b7 100644 }, { .key = SSL_DH_PARAM_OPT, .voltype = "rpc-transport/socket", -@@ -1857,7 +1857,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2140,8 +2144,8 @@ struct volopt_map_entry glusterd_volopt_map[] = { + { .key = "performance.readdir-ahead", .voltype = "performance/readdir-ahead", .option = "!perf", - .value = "off", +- .value = "on", - .op_version = 3, ++ .value = "off", + .op_version = GD_OP_VERSION_RHS_3_0, .description = "enable/disable readdir-ahead translator in the volume.", .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT }, -@@ -1964,7 +1964,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { - /* Feature translators */ +@@ -2263,7 +2267,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { + /* Feature translators */ { .key = "features.uss", .voltype = "features/snapview-server", - .op_version = GD_OP_VERSION_3_6_0, @@ -974,7 +1020,7 @@ index 1e24ada..be624b7 100644 .value = "off", .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT, .validate_fn = validate_uss, -@@ -1974,7 +1974,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2273,7 +2277,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "features.snapshot-directory", .voltype = "features/snapview-client", @@ -983,7 +1029,7 @@ index 1e24ada..be624b7 100644 .value = ".snaps", .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT, .validate_fn = validate_uss_dir, -@@ -1985,7 +1985,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2284,7 +2288,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "features.show-snapshot-directory", .voltype = "features/snapview-client", @@ -992,7 +1038,7 @@ index 1e24ada..be624b7 100644 .value = "off", .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT, .description = "show entry point in readdir output of " -@@ -2000,35 +2000,35 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2299,35 +2303,35 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "features/cdc", .option = "!feat", .value = "off", @@ -1034,7 +1080,7 @@ index 1e24ada..be624b7 100644 }, #endif -@@ -2051,25 +2051,25 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2342,25 +2346,25 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "features/quota", .option = "default-soft-limit", .type = NO_DOC, @@ -1064,7 +1110,7 @@ index 1e24ada..be624b7 100644 }, { .key = "features.quota-deem-statfs", .voltype = "features/quota", -@@ -2184,25 +2184,25 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2474,25 +2478,25 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "debug/error-gen", .option = "failure", .type = NO_DOC, @@ -1094,7 +1140,7 @@ index 1e24ada..be624b7 100644 }, -@@ -2253,7 +2253,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2543,7 +2547,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "nfs/server", .option = "rpc.outstanding-rpc-limit", .type = GLOBAL_DOC, @@ -1103,7 +1149,7 @@ index 1e24ada..be624b7 100644 }, { .key = "nfs.port", .voltype = "nfs/server", -@@ -2329,7 +2329,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2619,7 +2623,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "nfs/server", .option = "nfs.acl", .type = GLOBAL_DOC, @@ -1112,7 +1158,7 @@ index 1e24ada..be624b7 100644 }, { .key = "nfs.mount-udp", .voltype = "nfs/server", -@@ -2347,13 +2347,13 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2637,13 +2641,13 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "nfs/server", .option = "nfs.rpc-statd", .type = NO_DOC, @@ -1128,7 +1174,7 @@ index 1e24ada..be624b7 100644 }, { .key = "nfs.server-aux-gids", .voltype = "nfs/server", -@@ -2365,31 +2365,31 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2655,31 +2659,31 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "nfs/server", .option = "nfs.drc", .type = GLOBAL_DOC, @@ -1165,7 +1211,7 @@ index 1e24ada..be624b7 100644 }, { .key = "nfs.rdirplus", .voltype = "nfs/server", -@@ -2424,7 +2424,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2714,7 +2718,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = "features.read-only", .voltype = "features/read-only", .option = "read-only", @@ -1174,7 +1220,7 @@ index 1e24ada..be624b7 100644 .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT }, { .key = "features.worm", -@@ -2467,15 +2467,15 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2757,15 +2761,15 @@ struct volopt_map_entry glusterd_volopt_map[] = { }, { .key = "storage.batch-fsync-mode", .voltype = "storage/posix", @@ -1193,7 +1239,7 @@ index 1e24ada..be624b7 100644 }, { .key = "storage.owner-uid", .voltype = "storage/posix", -@@ -2489,20 +2489,20 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2779,16 +2783,16 @@ struct volopt_map_entry glusterd_volopt_map[] = { }, { .key = "storage.node-uuid-pathinfo", .voltype = "storage/posix", @@ -1211,6 +1257,10 @@ index 1e24ada..be624b7 100644 - .op_version = GD_OP_VERSION_3_6_0, + .op_version = GD_OP_VERSION_RHS_3_0, }, + { .option = "gfid2path", + .key = "storage.gfid2path", +@@ -2803,7 +2807,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { + }, { .key = "storage.bd-aio", .voltype = "storage/bd", - .op_version = 3 @@ -1218,7 +1268,7 @@ index 1e24ada..be624b7 100644 }, { .key = "config.memory-accounting", .voltype = "mgmt/glusterd", -@@ -2518,43 +2518,43 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2819,43 +2823,43 @@ struct volopt_map_entry glusterd_volopt_map[] = { { .key = GLUSTERD_QUORUM_TYPE_KEY, .voltype = "mgmt/glusterd", .value = "off", @@ -1270,7 +1320,7 @@ index 1e24ada..be624b7 100644 }, { .key = "changelog.capture-del-path", .voltype = "features/changelog", -@@ -2565,16 +2565,16 @@ struct volopt_map_entry glusterd_volopt_map[] = { +@@ -2866,16 +2870,16 @@ struct volopt_map_entry glusterd_volopt_map[] = { .voltype = "features/barrier", .value = "disable", .type = NO_DOC, @@ -1283,13 +1333,13 @@ index 1e24ada..be624b7 100644 - .op_version = GD_OP_VERSION_3_6_0, + .op_version = GD_OP_VERSION_RHS_3_0, }, - { .key = "cluster.op-version", + { .key = GLUSTERD_GLOBAL_OP_VERSION_KEY, .voltype = "mgmt/glusterd", - .op_version = GD_OP_VERSION_3_6_0, + .op_version = GD_OP_VERSION_RHS_3_0, }, - /*Trash translator options */ - { .key = "features.trash", + { + .key = GLUSTERD_MAX_OP_VERSION_KEY, -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0003-tier-ctr-sql-Dafault-values-for-sql-cache-and-wal-si.patch b/SOURCES/0003-tier-ctr-sql-Dafault-values-for-sql-cache-and-wal-si.patch index 6579ab8..0de06cd 100644 --- a/SOURCES/0003-tier-ctr-sql-Dafault-values-for-sql-cache-and-wal-si.patch +++ b/SOURCES/0003-tier-ctr-sql-Dafault-values-for-sql-cache-and-wal-si.patch @@ -1,7 +1,8 @@ -From 0dd60760c05f5291888a2fe4c8d2f860c97468bc Mon Sep 17 00:00:00 2001 +From 8fa58c563cf01934a64773e814f74727ee009b42 Mon Sep 17 00:00:00 2001 From: Joseph Fernandes Date: Wed, 30 Dec 2015 16:53:25 +0530 -Subject: [PATCH 03/86] tier/ctr/sql : Dafault values for sql cache and wal size +Subject: [PATCH 03/74] tier/ctr/sql : Dafault values for sql cache and wal + size Setting default values for sql cache and wal size cache : 12500 pages @@ -25,84 +26,31 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/70346 Reviewed-by: Nithya Balachandran Tested-by: Atin Mukherjee --- - libglusterfs/src/gfdb/gfdb_sqlite3.h | 4 ++-- - .../changetimerecorder/src/changetimerecorder.c | 4 ++-- - xlators/mgmt/glusterd/src/glusterd-volume-set.c | 12 ++++++------ - 3 files changed, 10 insertions(+), 10 deletions(-) + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3.h b/libglusterfs/src/gfdb/gfdb_sqlite3.h -index 9d0d996..e69251c 100644 ---- a/libglusterfs/src/gfdb/gfdb_sqlite3.h -+++ b/libglusterfs/src/gfdb/gfdb_sqlite3.h -@@ -166,8 +166,8 @@ do {\ - - #define GF_SQL_DEFAULT_DBPATH "" - #define GF_SQL_DEFAULT_PAGE_SIZE "4096" --#define GF_SQL_DEFAULT_CACHE_SIZE "1000" --#define GF_SQL_DEFAULT_WAL_AUTOCHECKPOINT "1000" -+#define GF_SQL_DEFAULT_CACHE_SIZE "12500" -+#define GF_SQL_DEFAULT_WAL_AUTOCHECKPOINT "25000" - #define GF_SQL_DEFAULT_JOURNAL_MODE GF_SQL_JM_WAL - #define GF_SQL_DEFAULT_SYNC GF_SQL_SYNC_OFF - #define GF_SQL_DEFAULT_AUTO_VACUUM GF_SQL_AV_NONE -diff --git a/xlators/features/changetimerecorder/src/changetimerecorder.c b/xlators/features/changetimerecorder/src/changetimerecorder.c -index 5f3a074..3d2e78a 100644 ---- a/xlators/features/changetimerecorder/src/changetimerecorder.c -+++ b/xlators/features/changetimerecorder/src/changetimerecorder.c -@@ -2299,11 +2299,11 @@ struct volume_options options[] = { - }, - { .key = {GFDB_SQL_PARAM_WAL_AUTOCHECK}, - .type = GF_OPTION_TYPE_INT, -- .default_value = "1000" -+ .default_value = "25000" - }, - { .key = {GFDB_SQL_PARAM_CACHE_SIZE}, - .type = GF_OPTION_TYPE_INT, -- .default_value = "1000" -+ .default_value = "12500" - }, - { .key = {GFDB_SQL_PARAM_PAGE_SIZE}, - .type = GF_OPTION_TYPE_INT, diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c -index be624b7..1f59e36 100644 +index 982275e..93ef85c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c -@@ -2797,29 +2797,29 @@ struct volopt_map_entry glusterd_volopt_map[] = { - }, - { .key = "features.ctr-sql-db-cachesize", - .voltype = "features/changetimerecorder", -- .value = "1000", -+ .value = "12500", - .option = "sql-db-cachesize", - .validate_fn = validate_ctr_sql_params, - .op_version = GD_OP_VERSION_3_7_7, - .description = "Defines the cache size of the sqlite database of " +@@ -3152,7 +3152,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { "changetimerecorder xlator." "The input to this option is in pages." -- "Each page is 4096 bytes. Default value is 1000 " -- "pages i.e ~ 4 MB. " -+ "Each page is 4096 bytes. Default value is 12500 " + "Each page is 4096 bytes. Default value is 12500 " +- "pages." + "pages i.e ~ 49 MB. " "The max value is 262144 pages i.e 1 GB and " "the min value is 1000 pages i.e ~ 4 MB. " }, - { .key = "features.ctr-sql-db-wal-autocheckpoint", - .voltype = "features/changetimerecorder", -- .value = "1000", -+ .value = "25000", - .option = "sql-db-wal-autocheckpoint", - .validate_fn = validate_ctr_sql_params, - .op_version = GD_OP_VERSION_3_7_7, - .description = "Defines the autocheckpoint of the sqlite database of " +@@ -3166,7 +3166,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { " changetimerecorder. " "The input to this option is in pages. " -- "Each page is 4096 bytes. Default value is 1000 " -- "pages i.e ~ 4 MB." -+ "Each page is 4096 bytes. Default value is 25000 " + "Each page is 4096 bytes. Default value is 25000 " +- "pages." + "pages i.e ~ 98 MB." "The max value is 262144 pages i.e 1 GB and " "the min value is 1000 pages i.e ~4 MB." }, -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0004-rpc-set-bind-insecure-to-off-by-default.patch b/SOURCES/0004-rpc-set-bind-insecure-to-off-by-default.patch index d016250..8f9feda 100644 --- a/SOURCES/0004-rpc-set-bind-insecure-to-off-by-default.patch +++ b/SOURCES/0004-rpc-set-bind-insecure-to-off-by-default.patch @@ -1,7 +1,7 @@ -From 393dc3c68f381be8ab9341689470d3c692eb95f6 Mon Sep 17 00:00:00 2001 +From b67f788dfe5855c455c8f4b41fe8159a5b41c4bd Mon Sep 17 00:00:00 2001 From: Prasanna Kumar Kalever Date: Mon, 21 Mar 2016 13:54:19 +0530 -Subject: [PATCH 04/86] rpc: set bind-insecure to off by default +Subject: [PATCH 04/74] rpc: set bind-insecure to off by default commit 243a5b429f225acb8e7132264fe0a0835ff013d5 turn's 'ON' allow-insecure and bind-insecure by default. @@ -28,14 +28,14 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/70313 Reviewed-by: Atin Mukherjee Tested-by: Atin Mukherjee --- - rpc/rpc-lib/src/rpc-transport.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) + rpc/rpc-lib/src/rpc-transport.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c -index e224dcc..a74aa22 100644 +index fc26f46..94880f4 100644 --- a/rpc/rpc-lib/src/rpc-transport.c +++ b/rpc/rpc-lib/src/rpc-transport.c -@@ -262,8 +262,8 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name) +@@ -258,8 +258,8 @@ rpc_transport_load (glusterfs_ctx_t *ctx, dict_t *options, char *trans_name) else trans->bind_insecure = 0; } else { @@ -47,5 +47,5 @@ index e224dcc..a74aa22 100644 ret = dict_get_str (options, "transport-type", &type); -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0005-glusterd-spec-fixing-autogen-issue.patch b/SOURCES/0005-glusterd-spec-fixing-autogen-issue.patch index 3075e0b..533dd5a 100644 --- a/SOURCES/0005-glusterd-spec-fixing-autogen-issue.patch +++ b/SOURCES/0005-glusterd-spec-fixing-autogen-issue.patch @@ -1,7 +1,7 @@ -From ab93e6087a3b23fd8697d47cc2d6df9afaedfaf5 Mon Sep 17 00:00:00 2001 +From 174ed444ad3b2007ecf55992acc3418455c46893 Mon Sep 17 00:00:00 2001 From: Atin Mukherjee Date: Mon, 21 Mar 2016 17:07:00 +0530 -Subject: [PATCH 05/86] glusterd/spec: fixing autogen issue +Subject: [PATCH 05/74] glusterd/spec: fixing autogen issue Backport of https://code.engineering.redhat.com/gerrit/#/c/59463/ @@ -21,14 +21,14 @@ Signed-off-by: Atin Mukherjee Reviewed-on: https://code.engineering.redhat.com/gerrit/70343 Reviewed-by: Milind Changire --- - glusterfs.spec.in | 7 +------ - 1 files changed, 1 insertions(+), 6 deletions(-) + glusterfs.spec.in | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index ca2ddb7..1d61fd7 100644 +index f68e38f..50db6cb 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -579,12 +579,7 @@ CFLAGS=-DUSE_INSECURE_OPENSSL +@@ -651,12 +651,7 @@ CFLAGS=-DUSE_INSECURE_OPENSSL export CFLAGS %endif @@ -41,7 +41,7 @@ index ca2ddb7..1d61fd7 100644 +./autogen.sh && %configure \ %{?_with_cmocka} \ %{?_with_debug} \ - %{?_with_tmpfilesdir} \ + %{?_with_firewalld} \ -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0006-libglusterfs-glusterd-Fix-compilation-errors.patch b/SOURCES/0006-libglusterfs-glusterd-Fix-compilation-errors.patch index 5faf9c9..984f34d 100644 --- a/SOURCES/0006-libglusterfs-glusterd-Fix-compilation-errors.patch +++ b/SOURCES/0006-libglusterfs-glusterd-Fix-compilation-errors.patch @@ -1,7 +1,7 @@ -From 6d4d822f45a84de2cfa6789524c63a73a3530697 Mon Sep 17 00:00:00 2001 +From 69a19b225dd5bc9fb0279ffd729dc5927548428e Mon Sep 17 00:00:00 2001 From: Atin Mukherjee Date: Mon, 21 Mar 2016 22:31:02 +0530 -Subject: [PATCH 06/86] libglusterfs/glusterd: Fix compilation errors +Subject: [PATCH 06/74] libglusterfs/glusterd: Fix compilation errors 1. Removed duplicate definition of GD_OP_VER_PERSISTENT_AFR_XATTRS introduced in d367a88 where GD_OP_VER_PERSISTENT_AFR_XATTRS was redfined @@ -15,22 +15,22 @@ Signed-off-by: Atin Mukherjee Reviewed-on: https://code.engineering.redhat.com/gerrit/70384 Reviewed-by: Nithya Balachandran --- - xlators/mgmt/glusterd/src/glusterd-store.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) + xlators/mgmt/glusterd/src/glusterd-store.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c -index 5a86aee..1d8efca 100644 +index 229391a..8a662ef 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c -@@ -961,7 +961,7 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo) +@@ -968,7 +968,7 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo) goto out; } -- if (conf->op_version >= GD_OP_VERSION_3_6_0) { +- if (conf->op_version >= GD_OP_VERSION_RHS_3_0) { + if (conf->op_version >= GD_OP_VERSION_3_7_0) { snprintf (buf, sizeof (buf), "%d", volinfo->disperse_count); ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_DISPERSE_CNT, -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0007-build-remove-ghost-directory-entries.patch b/SOURCES/0007-build-remove-ghost-directory-entries.patch index dc18b22..1ae41ce 100644 --- a/SOURCES/0007-build-remove-ghost-directory-entries.patch +++ b/SOURCES/0007-build-remove-ghost-directory-entries.patch @@ -1,7 +1,7 @@ -From 2512d876aa4358c8e68825f017d00a5bfc4056ff Mon Sep 17 00:00:00 2001 -From: Bala.FA +From 6ed11f5918cf21907df99839c9b76cf1144b2572 Mon Sep 17 00:00:00 2001 +From: "Bala.FA" Date: Mon, 7 Apr 2014 15:24:10 +0530 -Subject: [PATCH 07/86] build: remove ghost directory entries +Subject: [PATCH 07/74] build: remove ghost directory entries ovirt requires hook directories for gluster management and ghost directories are no more ghost entries @@ -13,14 +13,14 @@ Signed-off-by: Bala.FA Reviewed-on: https://code.engineering.redhat.com/gerrit/60133 Tested-by: Milind Changire --- - glusterfs.spec.in | 20 ++++++++++++++++++-- - 1 files changed, 18 insertions(+), 2 deletions(-) + glusterfs.spec.in | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 1d61fd7..011150d 100644 +index 50db6cb..3be99b6 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -682,14 +682,29 @@ install -D -p -m 0644 extras/glusterfs-logrotate \ +@@ -757,14 +757,29 @@ install -D -p -m 0644 extras/glusterfs-logrotate \ %{buildroot}%{_sysconfdir}/logrotate.d/glusterfs %if ( 0%{!?_without_georeplication:1} ) @@ -52,14 +52,14 @@ index 1d61fd7..011150d 100644 touch %{buildroot}%{_sharedstatedir}/glusterd/glusterd.info touch %{buildroot}%{_sharedstatedir}/glusterd/options subdirs=(add-brick create copy-file delete gsync-create remove-brick reset set start stop) -@@ -1108,6 +1123,7 @@ exit 0 - %{_sbindir}/snap_scheduler.py +@@ -1262,6 +1277,7 @@ exit 0 %{_sbindir}/gcron.py + %{_sbindir}/conf.py +<<<<<<< 2944c7b6656a36a79551f9f9f24ab7a10467f13a # /var/lib/glusterd, e.g. hookscripts, etc. %ghost %attr(0644,-,-) %config(noreplace) %{_sharedstatedir}/glusterd/glusterd.info %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0008-build-add-RHGS-specific-changes.patch b/SOURCES/0008-build-add-RHGS-specific-changes.patch index ef949a9..17cba78 100644 --- a/SOURCES/0008-build-add-RHGS-specific-changes.patch +++ b/SOURCES/0008-build-add-RHGS-specific-changes.patch @@ -1,7 +1,7 @@ -From cd770b8697ea79bd884925bcfdf451d98a2d5c25 Mon Sep 17 00:00:00 2001 -From: Bala.FA -Date: Fri, 28 Feb 2014 15:28:44 +0530 -Subject: [PATCH 08/86] build: add RHGS specific changes +From cac41ae2729cffa23a348c4de14486043ef08163 Mon Sep 17 00:00:00 2001 +From: "Bala.FA" +Date: Sat, 11 Nov 2017 10:32:42 +0530 +Subject: [PATCH 08/74] build: add RHGS specific changes Label: DOWNSTREAM ONLY @@ -18,14 +18,14 @@ Signed-off-by: Bala.FA Reviewed-on: https://code.engineering.redhat.com/gerrit/60134 Tested-by: Milind Changire --- - glusterfs.spec.in | 567 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 files changed, 561 insertions(+), 6 deletions(-) + glusterfs.spec.in | 605 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 597 insertions(+), 8 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 011150d..b0c4cb9 100644 +index 3be99b6..8458e8a 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -72,6 +72,23 @@ +@@ -80,6 +80,23 @@ %global _without_tiering --disable-tiering %endif @@ -49,18 +49,17 @@ index 011150d..b0c4cb9 100644 ##----------------------------------------------------------------------------- ## All %%global definitions should be placed here and keep them sorted ## -@@ -162,8 +179,8 @@ Vendor: Fedora Project +@@ -178,7 +195,8 @@ Release: 0.1%{?prereltag:.%{prereltag}}%{?dist} %else Name: @PACKAGE_NAME@ Version: @PACKAGE_VERSION@ -Release: 0.@PACKAGE_RELEASE@%{?dist} --Vendor: Gluster Community +Release: @PACKAGE_RELEASE@%{?dist} +ExclusiveArch: x86_64 aarch64 %endif License: GPLv2 or LGPLv3+ Group: System Environment/Base -@@ -298,7 +315,9 @@ Summary: Development Libraries +@@ -320,7 +338,9 @@ Summary: Development Libraries Group: Development/Libraries Requires: %{name}%{?_isa} = %{version}-%{release} # Needed for the Glupy examples to work @@ -71,7 +70,7 @@ index 011150d..b0c4cb9 100644 %description devel GlusterFS is a distributed file-system capable of scaling to several -@@ -311,6 +330,7 @@ is in user space and easily manageable. +@@ -333,6 +353,7 @@ is in user space and easily manageable. This package provides the development libraries and include files. @@ -79,7 +78,7 @@ index 011150d..b0c4cb9 100644 %package extra-xlators Summary: Extra Gluster filesystem Translators Group: Applications/File -@@ -330,6 +350,7 @@ is in user space and easily manageable. +@@ -355,6 +376,7 @@ is in user space and easily manageable. This package provides extra filesystem Translators, such as Glupy, for GlusterFS. @@ -87,33 +86,47 @@ index 011150d..b0c4cb9 100644 %package fuse Summary: Fuse client -@@ -356,6 +377,7 @@ is in user space and easily manageable. +@@ -381,6 +403,31 @@ is in user space and easily manageable. This package provides support to FUSE based clients and inlcudes the glusterfs(d) binary. +%if ( 0%{?_build_server} ) - %package ganesha - Summary: NFS-Ganesha configuration - Group: Applications/File -@@ -377,7 +399,9 @@ is in user space and easily manageable. - - This package provides the configuration and related files for using - NFS-Ganesha as the NFS server using GlusterFS ++%package ganesha ++Summary: NFS-Ganesha configuration ++Group: Applications/File ++ ++Requires: %{name}-server%{?_isa} = %{version}-%{release} ++Requires: nfs-ganesha-gluster, pcs, dbus ++%if ( 0%{?rhel} && 0%{?rhel} == 6 ) ++Requires: cman, pacemaker, corosync +%endif - ++ ++%description ganesha ++GlusterFS is a distributed file-system capable of scaling to several ++petabytes. It aggregates various storage bricks over Infiniband RDMA ++or TCP/IP interconnect into one large parallel network file ++system. GlusterFS is one of the most sophisticated file systems in ++terms of features and extensibility. It borrows a powerful concept ++called Translators from GNU Hurd kernel. Much of the code in GlusterFS ++is in user space and easily manageable. ++ ++This package provides the configuration and related files for using ++NFS-Ganesha as the NFS server using GlusterFS ++%endif ++ +%if ( 0%{?_build_server} ) %if ( 0%{!?_without_georeplication:1} ) %package geo-replication Summary: GlusterFS Geo-replication -@@ -398,6 +422,7 @@ is in userspace and easily manageable. +@@ -406,6 +453,7 @@ is in userspace and easily manageable. This package provides support to geo-replication. %endif +%endif - %package libs - Summary: GlusterFS common libraries -@@ -456,6 +481,8 @@ is in user space and easily manageable. + %if ( 0%{?_with_gnfs:1} ) + %package gnfs +@@ -498,6 +546,8 @@ is in user space and easily manageable. This package provides support to ib-verbs library. %endif @@ -122,7 +135,7 @@ index 011150d..b0c4cb9 100644 %package regression-tests Summary: Development Tools Group: Development/Tools -@@ -471,7 +498,10 @@ Requires: nfs-utils xfsprogs yajl +@@ -513,7 +563,10 @@ Requires: nfs-utils xfsprogs yajl psmisc bc %description regression-tests The Gluster Test Framework, is a suite of scripts used for regression testing of Gluster. @@ -133,7 +146,7 @@ index 011150d..b0c4cb9 100644 %if ( 0%{!?_without_ocf:1} ) %package resource-agents Summary: OCF Resource Agents for GlusterFS -@@ -504,7 +534,9 @@ This package provides the resource agents which plug glusterd into +@@ -546,7 +599,9 @@ This package provides the resource agents which plug glusterd into Open Cluster Framework (OCF) compliant cluster resource managers, like Pacemaker. %endif @@ -143,7 +156,7 @@ index 011150d..b0c4cb9 100644 %package server Summary: Clustered file-system server Group: System Environment/Daemons -@@ -554,6 +586,7 @@ called Translators from GNU Hurd kernel. Much of the code in GlusterFS +@@ -602,6 +657,7 @@ called Translators from GNU Hurd kernel. Much of the code in GlusterFS is in user space and easily manageable. This package provides the glusterfs server daemon. @@ -151,7 +164,36 @@ index 011150d..b0c4cb9 100644 %package client-xlators Summary: GlusterFS client-side translators -@@ -753,6 +786,7 @@ modprobe fuse +@@ -618,6 +674,7 @@ is in user space and easily manageable. + + This package provides the translators needed on any GlusterFS client. + ++%if ( 0%{?_build_server} ) + %if ( 0%{!?_without_events:1} ) + %package events + Summary: GlusterFS Events +@@ -641,6 +698,7 @@ Requires: python-argparse + GlusterFS Events + + %endif ++%endif + + %prep + %setup -q -n %{name}-%{version}%{?prereltag} +@@ -822,10 +880,12 @@ exit 0 + %post api + /sbin/ldconfig + ++%if ( 0%{?_build_server} ) + %if ( 0%{!?_without_events:1} ) + %post events + %_init_restart glustereventsd + %endif ++%endif + + %if ( 0%{?rhel} == 5 ) + %post fuse +@@ -833,6 +893,7 @@ modprobe fuse exit 0 %endif @@ -159,7 +201,7 @@ index 011150d..b0c4cb9 100644 %if ( 0%{!?_without_georeplication:1} ) %post geo-replication if [ $1 -ge 1 ]; then -@@ -760,10 +794,12 @@ if [ $1 -ge 1 ]; then +@@ -840,10 +901,12 @@ if [ $1 -ge 1 ]; then fi exit 0 %endif @@ -172,21 +214,24 @@ index 011150d..b0c4cb9 100644 %post server # Legacy server %_init_enable glusterd -@@ -838,11 +874,12 @@ else +@@ -914,7 +977,7 @@ else #rpm_script_t context. - rm -rf /var/run/glusterd.socket + rm -f %{_rundir}/glusterd.socket fi -exit 0 +%endif ##----------------------------------------------------------------------------- + ## All %%pre should be placed here and keep them sorted +@@ -928,6 +991,7 @@ exit 0 + ##----------------------------------------------------------------------------- ## All %%preun should be placed here and keep them sorted ## +%if ( 0%{?_build_server} ) - %preun server + %if ( 0%{!?_without_events:1} ) + %preun events if [ $1 -eq 0 ]; then - if [ -f %_init_glusterfsd ]; then -@@ -860,7 +897,7 @@ if [ $1 -ge 1 ]; then +@@ -956,7 +1020,7 @@ if [ $1 -ge 1 ]; then fi %_init_restart glusterd fi @@ -195,7 +240,7 @@ index 011150d..b0c4cb9 100644 ##----------------------------------------------------------------------------- ## All %%postun should be placed here and keep them sorted -@@ -893,6 +930,80 @@ exit 0 +@@ -986,6 +1050,73 @@ exit 0 ## All %%files should be placed here and keep them grouped ## %files @@ -203,11 +248,8 @@ index 011150d..b0c4cb9 100644 +%if ( ! 0%{!?_without_extra_xlators:1} ) +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/rot-13.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy.so -+%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/mac-compat.so -+%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/prot_client.so -+%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/prot_dht.so -+%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/prot_server.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/quiesce.so ++%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/selinux.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/testing/features/template.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/testing/performance/symlink-cache.so +%exclude %{python_sitelib}/* @@ -219,8 +261,6 @@ index 011150d..b0c4cb9 100644 +%endif +%if ( ! 0%{?_build_server} ) +# exclude ganesha files -+%exclude %{_sysconfdir}/ganesha/* -+%exclude %{_libexecdir}/ganesha/* +%exclude %{_prefix}/lib/ocf/* +# exclude geo-replication files +%exclude %{_sysconfdir}/logrotate.d/glusterfs-georep @@ -244,7 +284,6 @@ index 011150d..b0c4cb9 100644 +%exclude %_init_glusterd +%exclude %{_sysconfdir}/sysconfig/glusterd +%exclude %{_bindir}/glusterfind -+%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/pump.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/arbiter.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bit-rot.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bitrot-stub.so @@ -259,7 +298,6 @@ index 011150d..b0c4cb9 100644 +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/trash.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/upcall.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mgmt* -+%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs* +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/decompounder.so +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/server* +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/storage* @@ -276,18 +314,45 @@ index 011150d..b0c4cb9 100644 %doc ChangeLog COPYING-GPLV2 COPYING-LGPLV3 INSTALL README.md THANKS %{_mandir}/man8/*gluster*.8* %exclude %{_mandir}/man8/gluster.8* -@@ -979,6 +1090,7 @@ exit 0 - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/ganesha.so - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/client.so +@@ -1044,6 +1175,11 @@ exit 0 + %if 0%{?_tmpfilesdir:1} + %{_tmpfilesdir}/gluster.conf + %endif ++%if ( ! 0%{?_build_server} ) ++%{_libdir}/pkgconfig/libgfchangelog.pc ++%{_libdir}/pkgconfig/libgfdb.pc ++%{_sbindir}/gluster-setgfid2path ++%endif + + %files api + %exclude %{_libdir}/*.so +@@ -1078,9 +1214,11 @@ exit 0 + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/debug-trace.* + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/helloworld.* + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/negative.* +-%{_libdir}/pkgconfig/libgfchangelog.pc +-%if ( 0%{!?_without_tiering:1} ) +-%{_libdir}/pkgconfig/libgfdb.pc ++%if ( 0%{?_build_server} ) ++%exclude %{_libdir}/pkgconfig/libgfchangelog.pc ++%exclude %{_libdir}/pkgconfig/libgfdb.pc ++%exclude %{_sbindir}/gluster-setgfid2path ++%exclude %{_mandir}/man8/gluster-setgfid2path.8* + %endif + + %files client-xlators +@@ -1090,6 +1228,7 @@ exit 0 + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/client.so ++%if ( 0%{!?_without_extra_xlators:1} ) %files extra-xlators - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/rot-13.so - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy.so -@@ -991,6 +1103,11 @@ exit 0 - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/testing/performance/symlink-cache.so - # Glupy Python files - %{python_sitelib}/gluster/glupy/* + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption +@@ -1106,6 +1245,11 @@ exit 0 + %dir %{python2_sitelib}/gluster + %dir %{python2_sitelib}/gluster/glupy + %{python2_sitelib}/gluster/glupy/* +# Don't expect a .egg-info file on EL5 +%if ( ! ( 0%{?rhel} && 0%{?rhel} < 6 ) ) +%{python_sitelib}/glusterfs_glupy*.egg-info @@ -296,41 +361,47 @@ index 011150d..b0c4cb9 100644 %files fuse # glusterfs is a symlink to glusterfsd, -server depends on -fuse. -@@ -1008,13 +1125,16 @@ exit 0 +@@ -1125,6 +1269,7 @@ exit 0 %endif %endif +%if ( 0%{?_build_server} ) - %files ganesha - %{_sysconfdir}/ganesha/* - %{_libexecdir}/ganesha/* - %{_prefix}/lib/ocf/resource.d/heartbeat/* - %{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh - %{_sharedstatedir}/glusterd/hooks/1/reset/post/S31ganesha-reset.sh + %if ( 0%{?_with_gnfs:1} ) + %files gnfs + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator +@@ -1135,7 +1280,13 @@ exit 0 + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs/run + %ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/run/nfs.pid + %endif ++%endif ++ ++%if ( 0%{?_build_server} ) ++%files ganesha +%endif +%if ( 0%{?_build_server} ) %if ( 0%{!?_without_georeplication:1} ) %files geo-replication %config(noreplace) %{_sysconfdir}/logrotate.d/glusterfs-georep -@@ -1042,6 +1162,7 @@ exit 0 - %{_datadir}/glusterfs/scripts/gsync-sync-gfid - %{_datadir}/glusterfs/scripts/schedule_georep.py* +@@ -1172,6 +1323,7 @@ exit 0 + %{_datadir}/glusterfs/scripts/gsync-sync-gfid + %{_datadir}/glusterfs/scripts/schedule_georep.py* %endif +%endif %files libs %{_libdir}/*.so.* -@@ -1061,19 +1182,25 @@ exit 0 - %{_libdir}/glusterfs/%{version}%{?prereltag}/rpc-transport/rdma* +@@ -1194,19 +1346,26 @@ exit 0 + %{_libdir}/glusterfs/%{version}%{?prereltag}/rpc-transport/rdma* %endif +%if ( 0%{?_build_server} ) %files regression-tests - %{_prefix}/share/glusterfs/run-tests.sh - %{_prefix}/share/glusterfs/tests - %exclude %{_prefix}/share/glusterfs/tests/basic/rpm.t - %exclude %{_prefix}/share/glusterfs/tests/vagrant + %dir %{_datadir}/glusterfs + %{_datadir}/glusterfs/run-tests.sh + %{_datadir}/glusterfs/tests + %exclude %{_datadir}/glusterfs/tests/vagrant ++%exclude %{_datadir}/share/glusterfs/tests/basic/rpm.t +%endif +%if ( 0%{?_build_server} ) @@ -347,15 +418,15 @@ index 011150d..b0c4cb9 100644 %doc extras/clear_xattrs.sh # sysconf %config(noreplace) %{_sysconfdir}/glusterfs -@@ -1123,7 +1250,6 @@ exit 0 - %{_sbindir}/snap_scheduler.py +@@ -1277,7 +1436,6 @@ exit 0 %{_sbindir}/gcron.py + %{_sbindir}/conf.py -<<<<<<< 2944c7b6656a36a79551f9f9f24ab7a10467f13a # /var/lib/glusterd, e.g. hookscripts, etc. %ghost %attr(0644,-,-) %config(noreplace) %{_sharedstatedir}/glusterd/glusterd.info %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd -@@ -1194,6 +1320,435 @@ exit 0 +@@ -1354,8 +1512,438 @@ exit 0 %if ( 0%{?_with_firewalld:1} ) %{_prefix}/lib/firewalld/services/glusterfs.xml %endif @@ -789,8 +860,19 @@ index 011150d..b0c4cb9 100644 +end +%endif + # Events ++%if ( 0%{?_build_server} ) + %if ( 0%{!?_without_events:1} ) + %files events + %config(noreplace) %{_sysconfdir}/glusterfs/eventsconfig.json +@@ -1373,6 +1961,7 @@ exit 0 + %{_sysconfdir}/init.d/glustereventsd + %endif + %endif ++%endif + %changelog - * Mon Aug 22 2016 Milind Changire + * Tue Aug 22 2017 Kaleb S. KEITHLEY -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0009-secalert-remove-setuid-bit-for-fusermount-glusterfs.patch b/SOURCES/0009-secalert-remove-setuid-bit-for-fusermount-glusterfs.patch index ae1db4b..0a36a9a 100644 --- a/SOURCES/0009-secalert-remove-setuid-bit-for-fusermount-glusterfs.patch +++ b/SOURCES/0009-secalert-remove-setuid-bit-for-fusermount-glusterfs.patch @@ -1,7 +1,7 @@ -From 0b11ffaeee0d1ae48bf5272ea25a52e3c7cc09f5 Mon Sep 17 00:00:00 2001 -From: Bala.FA +From bfa0315b0437602ff1e568fb16c43d9937703eb4 Mon Sep 17 00:00:00 2001 +From: "Bala.FA" Date: Thu, 22 May 2014 08:37:27 +0530 -Subject: [PATCH 09/86] secalert: remove setuid bit for fusermount-glusterfs +Subject: [PATCH 09/74] secalert: remove setuid bit for fusermount-glusterfs glusterfs-fuse: File /usr/bin/fusermount-glusterfs on x86_64 is setuid root but is not on the setxid whitelist @@ -16,8 +16,8 @@ Signed-off-by: Bala.FA Reviewed-on: https://code.engineering.redhat.com/gerrit/60135 Tested-by: Milind Changire --- - contrib/fuse-util/Makefile.am | 1 - - 1 files changed, 0 insertions(+), 1 deletions(-) + contrib/fuse-util/Makefile.am | 1 - + 1 file changed, 1 deletion(-) diff --git a/contrib/fuse-util/Makefile.am b/contrib/fuse-util/Makefile.am index abbc10e..a071c81 100644 @@ -31,5 +31,5 @@ index abbc10e..a071c81 100644 CLEANFILES = -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0010-build-packaging-corrections-for-RHEL-5.patch b/SOURCES/0010-build-packaging-corrections-for-RHEL-5.patch index b39762a..ba47ddd 100644 --- a/SOURCES/0010-build-packaging-corrections-for-RHEL-5.patch +++ b/SOURCES/0010-build-packaging-corrections-for-RHEL-5.patch @@ -1,7 +1,7 @@ -From 9a6bef3ea5620221b72f76f42ba5becb656fae60 Mon Sep 17 00:00:00 2001 +From b40c05f7c099e860464faddd81722c7a3ab860a4 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 10 Jun 2015 16:16:47 +0200 -Subject: [PATCH 10/86] build: packaging corrections for RHEL-5 +Subject: [PATCH 10/74] build: packaging corrections for RHEL-5 Because the RHEL-5 version of these packages do not contain the -server bits, some additional changes for the .spec are needed. These changes @@ -16,14 +16,14 @@ Reviewed-by: Balamurugan Arumugam Reviewed-on: https://code.engineering.redhat.com/gerrit/60136 Tested-by: Milind Changire --- - glusterfs.spec.in | 18 ++++++++++-------- - 1 files changed, 10 insertions(+), 8 deletions(-) + glusterfs.spec.in | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index b0c4cb9..54f8ecd 100644 +index 8458e8a..dbdb818 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -84,6 +84,7 @@ +@@ -92,6 +92,7 @@ %global _build_server 1 %else %global _build_server 0 @@ -31,9 +31,9 @@ index b0c4cb9..54f8ecd 100644 %endif %global _without_extra_xlators 1 -@@ -953,17 +954,14 @@ exit 0 - %exclude %{_sysconfdir}/ganesha/* - %exclude %{_libexecdir}/ganesha/* +@@ -1068,17 +1069,14 @@ exit 0 + %if ( ! 0%{?_build_server} ) + # exclude ganesha files %exclude %{_prefix}/lib/ocf/* -# exclude geo-replication files -%exclude %{_sysconfdir}/logrotate.d/glusterfs-georep @@ -54,7 +54,7 @@ index b0c4cb9..54f8ecd 100644 %exclude %{_sysconfdir}/glusterfs %exclude %{_sysconfdir}/glusterfs/glusterd.vol %exclude %{_sysconfdir}/glusterfs/glusterfs-georep-logrotate -@@ -979,7 +977,9 @@ exit 0 +@@ -1093,7 +1091,9 @@ exit 0 %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/arbiter.so %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bit-rot.so %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bitrot-stub.so @@ -64,7 +64,7 @@ index b0c4cb9..54f8ecd 100644 %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/index.so %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/leases.so %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/locks.so -@@ -994,7 +994,9 @@ exit 0 +@@ -1107,7 +1107,9 @@ exit 0 %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/decompounder.so %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/server* %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/storage* @@ -75,5 +75,5 @@ index b0c4cb9..54f8ecd 100644 %exclude %{_sbindir}/glfsheal %exclude %{_sbindir}/glusterd -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0011-build-introduce-security-hardening-flags-in-gluster.patch b/SOURCES/0011-build-introduce-security-hardening-flags-in-gluster.patch index c707611..34bfd71 100644 --- a/SOURCES/0011-build-introduce-security-hardening-flags-in-gluster.patch +++ b/SOURCES/0011-build-introduce-security-hardening-flags-in-gluster.patch @@ -1,7 +1,7 @@ -From b592ce68be630892b3ffc28e1a7696c144cef3e2 Mon Sep 17 00:00:00 2001 +From ada27d07526acb0ef09f37de7f364fa3dcea0b36 Mon Sep 17 00:00:00 2001 From: Atin Mukherjee Date: Wed, 3 Jun 2015 11:09:21 +0530 -Subject: [PATCH 11/86] build: introduce security hardening flags in gluster +Subject: [PATCH 11/74] build: introduce security hardening flags in gluster This patch introduces two of the security hardening compiler flags RELRO & PIE in gluster codebase. Using _hardened_build as 1 doesn't guarantee the existance @@ -19,14 +19,14 @@ Tested-by: Balamurugan Arumugam Reviewed-on: https://code.engineering.redhat.com/gerrit/60137 Tested-by: Milind Changire --- - glusterfs.spec.in | 25 +++++++++++++++++++++++-- - 1 files changed, 23 insertions(+), 2 deletions(-) + glusterfs.spec.in | 25 +++++++++++++++++++++++-- + 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 54f8ecd..bc413b9 100644 +index dbdb818..458b8bc 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -612,6 +612,24 @@ This package provides the translators needed on any GlusterFS client. +@@ -709,6 +709,24 @@ GlusterFS Events CFLAGS=-DUSE_INSECURE_OPENSSL export CFLAGS %endif @@ -51,7 +51,7 @@ index 54f8ecd..bc413b9 100644 ./autogen.sh && %configure \ %{?_with_cmocka} \ -@@ -1802,8 +1820,11 @@ end +@@ -2110,8 +2128,11 @@ end * Fri Jun 12 2015 Aravinda VK - Added rsync as dependency to georeplication rpm (#1231205) @@ -66,5 +66,5 @@ index 54f8ecd..bc413b9 100644 * Wed May 27 2015 Aravinda VK - Added stop-all-gluster-processes.sh in glusterfs-server section (#1204641) -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0012-spec-fix-add-pre-transaction-scripts-for-geo-rep-and.patch b/SOURCES/0012-spec-fix-add-pre-transaction-scripts-for-geo-rep-and.patch index bc3dccd..0d71aeb 100644 --- a/SOURCES/0012-spec-fix-add-pre-transaction-scripts-for-geo-rep-and.patch +++ b/SOURCES/0012-spec-fix-add-pre-transaction-scripts-for-geo-rep-and.patch @@ -1,7 +1,8 @@ -From f3188b990b21903dd3304f034365e9a572bc6d55 Mon Sep 17 00:00:00 2001 +From 280eddebd49483343cc08b42c12f26d89f6d51e1 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 22 Apr 2015 15:39:59 +0200 -Subject: [PATCH 12/86] spec: fix/add pre-transaction scripts for geo-rep and cli packages +Subject: [PATCH 12/74] spec: fix/add pre-transaction scripts for geo-rep and + cli packages The cli subpackage never had a %pretrans script, this has been added now. @@ -23,14 +24,14 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/50491 Reviewed-on: https://code.engineering.redhat.com/gerrit/60138 Tested-by: Milind Changire --- - glusterfs.spec.in | 43 +++++++++++++++++++++++++++++++++++++++++-- - 1 files changed, 41 insertions(+), 2 deletions(-) + glusterfs.spec.in | 43 +++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index bc413b9..3f3d994 100644 +index 458b8bc..68eba56 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -1476,6 +1476,47 @@ end +@@ -1668,6 +1668,47 @@ end @@ -78,7 +79,7 @@ index bc413b9..3f3d994 100644 %pretrans devel -p if not posix.access("/bin/bash", "x") then -- initial installation, no shell, no running glusterfsd -@@ -1558,7 +1599,6 @@ end +@@ -1750,7 +1791,6 @@ end @@ -86,7 +87,7 @@ index bc413b9..3f3d994 100644 %if ( 0%{!?_without_georeplication:1} ) %pretrans geo-replication -p if not posix.access("/bin/bash", "x") then -@@ -1599,7 +1639,6 @@ if not (ok == 0) then +@@ -1791,7 +1831,6 @@ if not (ok == 0) then error("Detected running glusterfs processes", ok) end %endif @@ -95,5 +96,5 @@ index bc413b9..3f3d994 100644 -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0013-rpm-glusterfs-devel-for-client-builds-should-not-dep.patch b/SOURCES/0013-rpm-glusterfs-devel-for-client-builds-should-not-dep.patch index 521b018..a7a6c98 100644 --- a/SOURCES/0013-rpm-glusterfs-devel-for-client-builds-should-not-dep.patch +++ b/SOURCES/0013-rpm-glusterfs-devel-for-client-builds-should-not-dep.patch @@ -1,7 +1,8 @@ -From 4b7f0ea0d0f5665e0160dcd67f9ff521d895050e Mon Sep 17 00:00:00 2001 +From cf8f5a4e4098a6aae9b986dc2da2006eadd4fef1 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Thu, 18 Jun 2015 12:16:16 +0200 -Subject: [PATCH 13/86] rpm: glusterfs-devel for client-builds should not depend on -server +Subject: [PATCH 13/74] rpm: glusterfs-devel for client-builds should not + depend on -server glusterfs-devel for client-side packages should *not* include the libgfdb.so symlink and libgfdb.pc file or any of the libchangelog @@ -17,15 +18,29 @@ Tested-by: Balamurugan Arumugam Reviewed-on: https://code.engineering.redhat.com/gerrit/60139 Tested-by: Milind Changire --- - glusterfs.spec.in | 17 ++++++++++++++++- - 1 files changed, 16 insertions(+), 1 deletions(-) + glusterfs.spec.in | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 3f3d994..a10663f 100644 +index 68eba56..b2fb4d5 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -1094,14 +1094,26 @@ exit 0 - %{_includedir}/glusterfs/* +@@ -1196,9 +1196,10 @@ exit 0 + %{_tmpfilesdir}/gluster.conf + %endif + %if ( ! 0%{?_build_server} ) +-%{_libdir}/pkgconfig/libgfchangelog.pc +-%{_libdir}/pkgconfig/libgfdb.pc +-%{_sbindir}/gluster-setgfid2path ++%exclude %{_libdir}/pkgconfig/libgfchangelog.pc ++%exclude %{_libdir}/pkgconfig/libgfdb.pc ++%exclude %{_sbindir}/gluster-setgfid2path ++%exclude %{_mandir}/man8/gluster-setgfid2path.8* + %endif + + %files api +@@ -1226,6 +1227,12 @@ exit 0 + %{_includedir}/glusterfs/* %exclude %{_includedir}/glusterfs/api %exclude %{_libdir}/libgfapi.so +%if ( ! 0%{?_build_server} ) @@ -36,23 +51,25 @@ index 3f3d994..a10663f 100644 +%endif %{_libdir}/*.so # Glupy Translator examples - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/debug-trace.* - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/helloworld.* - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/negative.* -+%if ( 0%{?_build_server} ) - %{_libdir}/pkgconfig/libgfchangelog.pc --%if ( 0%{!?_without_tiering:1} ) + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator +@@ -1235,10 +1242,14 @@ exit 0 + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/helloworld.* + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/negative.* + %if ( 0%{?_build_server} ) ++%{_libdir}/pkgconfig/libgfchangelog.pc +%else -+%exclude %{_libdir}/pkgconfig/libgfchangelog.pc + %exclude %{_libdir}/pkgconfig/libgfchangelog.pc +%endif +%if ( 0%{!?_without_tiering:1} && 0%{?_build_server}) - %{_libdir}/pkgconfig/libgfdb.pc ++%{_libdir}/pkgconfig/libgfdb.pc +%else -+%exclude %{_libdir}/pkgconfig/libgfdb.pc + %exclude %{_libdir}/pkgconfig/libgfdb.pc +-%exclude %{_sbindir}/gluster-setgfid2path +-%exclude %{_mandir}/man8/gluster-setgfid2path.8* %endif %files client-xlators -@@ -1853,6 +1865,9 @@ end +@@ -2161,6 +2172,9 @@ end * Tue Aug 18 2015 Niels de Vos - Include missing directories for glusterfind hooks scripts (#1225465) @@ -63,5 +80,5 @@ index 3f3d994..a10663f 100644 - Replace hook script S31ganesha-set.sh by S31ganesha-start.sh (#1231738) -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0014-build-add-pretrans-check.patch b/SOURCES/0014-build-add-pretrans-check.patch index 400bce0..53b0a55 100644 --- a/SOURCES/0014-build-add-pretrans-check.patch +++ b/SOURCES/0014-build-add-pretrans-check.patch @@ -1,7 +1,7 @@ -From db766336fd658cde2beec09b68e309e8866b08aa Mon Sep 17 00:00:00 2001 -From: Bala.FA +From 59602f5c55a05b9652247803d37efa85f6e8f526 Mon Sep 17 00:00:00 2001 +From: "Bala.FA" Date: Wed, 17 Jun 2015 21:34:52 +0530 -Subject: [PATCH 14/86] build: add pretrans check +Subject: [PATCH 14/74] build: add pretrans check This patch adds pretrans check for client-xlators, ganesha and python-gluster sub-packages. @@ -14,14 +14,14 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/50967 Reviewed-on: https://code.engineering.redhat.com/gerrit/60140 Tested-by: Milind Changire --- - glusterfs.spec.in | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 127 insertions(+), 0 deletions(-) + glusterfs.spec.in | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 127 insertions(+) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index a10663f..d832235 100644 +index b2fb4d5..0d1161d 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -1529,6 +1529,47 @@ end +@@ -1720,6 +1720,47 @@ end @@ -69,7 +69,7 @@ index a10663f..d832235 100644 %pretrans devel -p if not posix.access("/bin/bash", "x") then -- initial installation, no shell, no running glusterfsd -@@ -1611,6 +1652,47 @@ end +@@ -1802,6 +1843,47 @@ end @@ -117,7 +117,7 @@ index a10663f..d832235 100644 %if ( 0%{!?_without_georeplication:1} ) %pretrans geo-replication -p if not posix.access("/bin/bash", "x") then -@@ -1695,6 +1777,47 @@ end +@@ -1886,6 +1968,47 @@ end @@ -165,7 +165,7 @@ index a10663f..d832235 100644 %if ( 0%{!?_without_rdma:1} ) %pretrans rdma -p if not posix.access("/bin/bash", "x") then -@@ -1865,6 +1988,10 @@ end +@@ -2172,6 +2295,10 @@ end * Tue Aug 18 2015 Niels de Vos - Include missing directories for glusterfind hooks scripts (#1225465) @@ -177,5 +177,5 @@ index a10663f..d832235 100644 - glusterfs-devel for client-builds should not depend on -server (#1227029) -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0015-build-exclude-libgfdb.pc-conditionally.patch b/SOURCES/0015-build-exclude-libgfdb.pc-conditionally.patch index bc30ab5..94f97ae 100644 --- a/SOURCES/0015-build-exclude-libgfdb.pc-conditionally.patch +++ b/SOURCES/0015-build-exclude-libgfdb.pc-conditionally.patch @@ -1,7 +1,7 @@ -From 78385d312c4ca2ce9266069af84dc4bddfbf8112 Mon Sep 17 00:00:00 2001 -From: Bala.FA +From 444324cfdcd8da750bc0ae04a3a416725489dd06 Mon Sep 17 00:00:00 2001 +From: "Bala.FA" Date: Fri, 19 Jun 2015 11:09:53 +0530 -Subject: [PATCH 15/86] build: exclude libgfdb.pc conditionally +Subject: [PATCH 15/74] build: exclude libgfdb.pc conditionally This patch fixes rhel-5 build failure where libgfdb.pc is not applicable. @@ -14,14 +14,14 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/51099 Reviewed-on: https://code.engineering.redhat.com/gerrit/60141 Tested-by: Milind Changire --- - glusterfs.spec.in | 11 ++++++++++- - 1 files changed, 10 insertions(+), 1 deletions(-) + glusterfs.spec.in | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index d832235..e2be3f3 100644 +index 0d1161d..f308f37 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -935,6 +935,7 @@ fi +@@ -1058,12 +1058,14 @@ fi %postun libs /sbin/ldconfig @@ -29,15 +29,14 @@ index d832235..e2be3f3 100644 %postun server /sbin/ldconfig %if (0%{?_with_firewalld:1}) -@@ -944,6 +945,7 @@ if $(systemctl is-active firewalld 1>/dev/null 2>&1); then - fi + %firewalld_reload %endif exit 0 +%endif ##----------------------------------------------------------------------------- ## All %%files should be placed here and keep them grouped -@@ -1113,8 +1115,10 @@ exit 0 +@@ -1249,8 +1251,10 @@ exit 0 %if ( 0%{!?_without_tiering:1} && 0%{?_build_server}) %{_libdir}/pkgconfig/libgfdb.pc %else @@ -47,32 +46,33 @@ index d832235..e2be3f3 100644 +%endif %files client-xlators - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/*.so -@@ -1122,7 +1126,7 @@ exit 0 - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/ganesha.so - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/client.so + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator +@@ -1259,7 +1263,7 @@ exit 0 + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/client.so -+%if ( 0%{!?_without_extra_xlators:1} ) +%if ( 0%{!?_without_extra_xlators:1} ) %files extra-xlators - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/rot-13.so - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy.so -@@ -1215,12 +1219,14 @@ exit 0 + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption +@@ -1378,6 +1382,7 @@ exit 0 %endif %if ( 0%{?_build_server} ) +%if ( 0%{!?_without_regression_tests:1} ) %files regression-tests - %{_prefix}/share/glusterfs/run-tests.sh - %{_prefix}/share/glusterfs/tests - %exclude %{_prefix}/share/glusterfs/tests/basic/rpm.t - %exclude %{_prefix}/share/glusterfs/tests/vagrant + %dir %{_datadir}/glusterfs + %{_datadir}/glusterfs/run-tests.sh +@@ -1385,6 +1390,7 @@ exit 0 + %exclude %{_datadir}/glusterfs/tests/vagrant + %exclude %{_datadir}/share/glusterfs/tests/basic/rpm.t %endif +%endif %if ( 0%{?_build_server} ) %if ( 0%{!?_without_ocf:1} ) -@@ -1988,6 +1994,9 @@ end +@@ -2295,6 +2301,9 @@ end * Tue Aug 18 2015 Niels de Vos - Include missing directories for glusterfind hooks scripts (#1225465) @@ -83,5 +83,5 @@ index d832235..e2be3f3 100644 - add pretrans check for client-xlators, ganesha and python-gluster sub-packages (#1232641) -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0016-build-exclude-glusterfs.xml-on-rhel-7-client-build.patch b/SOURCES/0016-build-exclude-glusterfs.xml-on-rhel-7-client-build.patch index f25c601..4188bac 100644 --- a/SOURCES/0016-build-exclude-glusterfs.xml-on-rhel-7-client-build.patch +++ b/SOURCES/0016-build-exclude-glusterfs.xml-on-rhel-7-client-build.patch @@ -1,7 +1,7 @@ -From c317004775bdc59e1d57252c849391cd4706cefa Mon Sep 17 00:00:00 2001 +From 5b117b1f8cf05d645512bb6f07cbe2803119652f Mon Sep 17 00:00:00 2001 From: Milind Changire Date: Thu, 29 Oct 2015 15:55:26 +0530 -Subject: [PATCH 16/86] build: exclude glusterfs.xml on rhel-7 client build +Subject: [PATCH 16/74] build: exclude glusterfs.xml on rhel-7 client build Label: DOWNSTREAM ONLY @@ -11,14 +11,14 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/60433 Reviewed-by: Balamurugan Arumugam Tested-by: Balamurugan Arumugam --- - glusterfs.spec.in | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) + glusterfs.spec.in | 3 +++ + 1 file changed, 3 insertions(+) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index e2be3f3..d5de0f2 100644 +index f308f37..85f7f21 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -1025,6 +1025,9 @@ exit 0 +@@ -1138,6 +1138,9 @@ exit 0 %if 0%{?_tmpfilesdir:1} %exclude %{_tmpfilesdir}/gluster.conf %endif @@ -29,5 +29,5 @@ index e2be3f3..d5de0f2 100644 %doc ChangeLog COPYING-GPLV2 COPYING-LGPLV3 INSTALL README.md THANKS %{_mandir}/man8/*gluster*.8* -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0017-glusterd-fix-info-file-checksum-mismatch-during-upgr.patch b/SOURCES/0017-glusterd-fix-info-file-checksum-mismatch-during-upgr.patch index 2837be3..4b491be 100644 --- a/SOURCES/0017-glusterd-fix-info-file-checksum-mismatch-during-upgr.patch +++ b/SOURCES/0017-glusterd-fix-info-file-checksum-mismatch-during-upgr.patch @@ -1,7 +1,8 @@ -From 1a5e8518d9abefb8e5c4fbc666a1939718fd6216 Mon Sep 17 00:00:00 2001 +From 5d3441530f71047483b5973bad7efd2c73ccfff9 Mon Sep 17 00:00:00 2001 From: anand Date: Wed, 18 Nov 2015 16:13:46 +0530 -Subject: [PATCH 17/86] glusterd: fix info file checksum mismatch during upgrade +Subject: [PATCH 17/74] glusterd: fix info file checksum mismatch during + upgrade peers are moving rejected state when upgrading from RHS2.1 to RHGS3.1.2 due to checksum mismatch. @@ -14,14 +15,14 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/61774 Reviewed-by: Atin Mukherjee Tested-by: Atin Mukherjee --- - xlators/mgmt/glusterd/src/glusterd-store.c | 21 ++++++++++++--------- - 1 files changed, 12 insertions(+), 9 deletions(-) + xlators/mgmt/glusterd/src/glusterd-store.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c -index 1d8efca..70627f3 100644 +index 8a662ef..42bb8ce 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c -@@ -1007,16 +1007,19 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo) +@@ -1014,16 +1014,19 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo) goto out; } @@ -51,5 +52,5 @@ index 1d8efca..70627f3 100644 snprintf (buf, sizeof (buf), "%d", volinfo->caps); ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_CAPS, -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0018-build-spec-file-conflict-resolution.patch b/SOURCES/0018-build-spec-file-conflict-resolution.patch index 84cd301..7f22b92 100644 --- a/SOURCES/0018-build-spec-file-conflict-resolution.patch +++ b/SOURCES/0018-build-spec-file-conflict-resolution.patch @@ -1,7 +1,7 @@ -From f8e9d2f1a5b1c06dea5ded48a296115f59c656bd Mon Sep 17 00:00:00 2001 +From 75d0e5c542c4d1a2df1a49a6f526ccb099f9f53f Mon Sep 17 00:00:00 2001 From: Milind Changire Date: Tue, 22 Mar 2016 23:33:13 +0530 -Subject: [PATCH 18/86] build: spec file conflict resolution +Subject: [PATCH 18/74] build: spec file conflict resolution Missed conflict resolution for removing references to gluster.conf.example as mentioned in patch titled: @@ -25,14 +25,14 @@ Reviewed-on: https://code.engineering.redhat.com/gerrit/70535 Reviewed-by: Rajesh Joseph Tested-by: Rajesh Joseph --- - glusterfs.spec.in | 17 ----------------- - 1 files changed, 0 insertions(+), 17 deletions(-) + glusterfs.spec.in | 17 ----------------- + 1 file changed, 17 deletions(-) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index d5de0f2..cd24298 100644 +index 85f7f21..fe566e5 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -740,23 +740,6 @@ install -D -p -m 0644 extras/glusterfs-georep-logrotate \ +@@ -840,23 +840,6 @@ install -D -p -m 0644 extras/glusterfs-georep-logrotate \ %{buildroot}%{_sysconfdir}/logrotate.d/glusterfs-georep %endif @@ -57,5 +57,5 @@ index d5de0f2..cd24298 100644 touch %{buildroot}%{_sharedstatedir}/glusterd/options subdirs=(add-brick create copy-file delete gsync-create remove-brick reset set start stop) -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0019-build-dependency-error-during-upgrade.patch b/SOURCES/0019-build-dependency-error-during-upgrade.patch index b5de327..560b6f0 100644 --- a/SOURCES/0019-build-dependency-error-during-upgrade.patch +++ b/SOURCES/0019-build-dependency-error-during-upgrade.patch @@ -1,7 +1,7 @@ -From 65353f6c9e399196fe4b9802e70f55c1a4f1f233 Mon Sep 17 00:00:00 2001 +From 5c5283f873e72d7305953ca357b709a3ab1919f4 Mon Sep 17 00:00:00 2001 From: Kaleb S KEITHLEY Date: Tue, 10 May 2016 12:37:23 -0400 -Subject: [PATCH 19/86] build: dependency error during upgrade +Subject: [PATCH 19/74] build: dependency error during upgrade Not sure who thought config params in the form without_foo were a good idea. Trying to parse !without_tiering conditionals makes my @@ -14,14 +14,14 @@ Signed-off-by: Kaleb S KEITHLEY Reviewed-on: https://code.engineering.redhat.com/gerrit/74041 Reviewed-by: Niels de Vos --- - glusterfs.spec.in | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) + glusterfs.spec.in | 3 +++ + 1 file changed, 3 insertions(+) diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index cd24298..7e40f75 100644 +index fe566e5..f83ae5e 100644 --- a/glusterfs.spec.in +++ b/glusterfs.spec.in -@@ -1098,6 +1098,9 @@ exit 0 +@@ -1234,6 +1234,9 @@ exit 0 %else %exclude %{_libdir}/pkgconfig/libgfchangelog.pc %endif @@ -32,5 +32,5 @@ index cd24298..7e40f75 100644 %{_libdir}/pkgconfig/libgfdb.pc %else -- -1.7.1 +1.8.3.1 diff --git a/SOURCES/0020-Revert-gfapi-upcall-Use-GF_CALLOC-while-allocating-v.patch b/SOURCES/0020-Revert-gfapi-upcall-Use-GF_CALLOC-while-allocating-v.patch deleted file mode 100644 index 63335a4..0000000 --- a/SOURCES/0020-Revert-gfapi-upcall-Use-GF_CALLOC-while-allocating-v.patch +++ /dev/null @@ -1,61 +0,0 @@ -From b945e99a6c5a9ea623b2c9d0dbc1417ef8e59d4b Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Mon, 30 May 2016 17:39:02 +0530 -Subject: [PATCH 20/86] Revert "gfapi/upcall: Use GF_CALLOC while allocating variables" - -The above fix cause another regression for ganesha mount. -The struct which allocated here is a generic structure used by -both gfapi and FSAL_GLUSTER. So allocating it using GF_CALLOC() -is wrong to do. Therefore release that variable using "free()" -instead of GF_FREE() - -So reverting that change and fix the same in another way. - -This reverts commit 60089f6e16afe6760e0db536086cea5c9ddb5b43. - -Please Note : -This is a hacky fix, so patch is sent only to downstream. -Clean fix requires changes in both ganesha and gfapi codes, -with in current time constraint which is difficult to achieve. - -Please refer following ML for more details -http://post-office.corp.redhat.com/archives/nfs-ganesha/2016-May/msg00116.html - -Label: DOWNSTREAM ONLY - -Change-Id: I9240de5666df339c794466a9aa2acc285c173cf2 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/75429 -Reviewed-by: Niels de Vos -Tested-by: Niels de Vos ---- - api/src/glfs-handleops.c | 6 +++--- - 1 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c -index f9b4ee9..221c29f 100644 ---- a/api/src/glfs-handleops.c -+++ b/api/src/glfs-handleops.c -@@ -1891,8 +1891,7 @@ glfs_h_poll_cache_invalidation (struct glfs *fs, - goto out; - } - -- up_inode_arg = GF_CALLOC (1, sizeof (struct callback_inode_arg), -- glfs_mt_upcall_entry_t); -+ up_inode_arg = calloc (1, sizeof (struct callback_inode_arg)); - GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation", - up_inode_arg, out); - -@@ -1958,7 +1957,8 @@ out: - - /* Reset event_arg as well*/ - up_arg->event_arg = NULL; -- GF_FREE (up_inode_arg); -+ free (up_inode_arg); -+ up_inode_arg = NULL; - } - return ret; - } --- -1.7.1 - diff --git a/SOURCES/0020-eventsapi-Fix-eventtypes.h-header-generation-with-Py.patch b/SOURCES/0020-eventsapi-Fix-eventtypes.h-header-generation-with-Py.patch new file mode 100644 index 0000000..e35b661 --- /dev/null +++ b/SOURCES/0020-eventsapi-Fix-eventtypes.h-header-generation-with-Py.patch @@ -0,0 +1,88 @@ +From a7570af0bc6dc53044dce2cace9a65e96c571da6 Mon Sep 17 00:00:00 2001 +From: Aravinda VK +Date: Mon, 19 Sep 2016 16:59:30 +0530 +Subject: [PATCH 20/74] eventsapi: Fix eventtypes.h header generation with + Python 2.4 + +eventskeygen.py file generates eventtypes.h and eventtypes.py files +during build. If Python version is old(Version 2.4), then Gluster +Client build will fail. eventskeygen.py uses "with" statement to +open file, which is introduced in Python 2.5 + +Label: DOWNSTREAM ONLY + +Change-Id: I995e102fad0c7bc66e840b1ab9d53ed564266253 +Signed-off-by: Aravinda VK +Reviewed-on: https://code.engineering.redhat.com/gerrit/85060 +Reviewed-by: Milind Changire +Reviewed-by: Atin Mukherjee +--- + events/eventskeygen.py | 47 +++++++++++++++++++++++++---------------------- + 1 file changed, 25 insertions(+), 22 deletions(-) + +diff --git a/events/eventskeygen.py b/events/eventskeygen.py +index 23dfb47..a9c5573 100644 +--- a/events/eventskeygen.py ++++ b/events/eventskeygen.py +@@ -207,33 +207,36 @@ ERRORS = ( + + if gen_header_type == "C_HEADER": + # Generate eventtypes.h +- with open(eventtypes_h, "w") as f: +- f.write("#ifndef __EVENTTYPES_H__\n") +- f.write("#define __EVENTTYPES_H__\n\n") +- f.write("typedef enum {\n") +- for k in ERRORS: +- f.write(" {0},\n".format(k)) +- f.write("} event_errors_t;\n") ++ f = open(eventtypes_h, "w") ++ f.write("#ifndef __EVENTTYPES_H__\n") ++ f.write("#define __EVENTTYPES_H__\n\n") ++ f.write("typedef enum {\n") ++ for k in ERRORS: ++ f.write(" %s,\n" % k) ++ f.write("} event_errors_t;\n") + +- f.write("\n") ++ f.write("\n") + +- f.write("typedef enum {\n") +- for k in keys: +- f.write(" {0},\n".format(k)) ++ f.write("typedef enum {\n") ++ for k in keys: ++ f.write(" %s,\n" % k) + +- f.write(" {0}\n".format(LAST_EVENT)) +- f.write("} eventtypes_t;\n") +- f.write("\n#endif /* __EVENTTYPES_H__ */\n") ++ f.write(" %s\n" % LAST_EVENT) ++ f.write("} eventtypes_t;\n") ++ f.write("\n#endif /* __EVENTTYPES_H__ */\n") ++ f.close() + + if gen_header_type == "PY_HEADER": + # Generate eventtypes.py +- with open(eventtypes_py, "w") as f: +- f.write("# -*- coding: utf-8 -*-\n") +- f.write("all_events = [\n") +- for ev in keys: +- f.write(' "{0}",\n'.format(ev)) ++ f = open(eventtypes_py, "w") ++ f.write("# -*- coding: utf-8 -*-\n") ++ f.write("all_events = [\n") ++ for ev in keys: ++ f.write(' "%s",\n' % ev) + +- f.write("]\n\n") ++ f.write("]\n\n") + +- for idx, ev in enumerate(keys): +- f.write("{0} = {1}\n".format(ev.replace("EVENT_", ""), idx)) ++ for idx, ev in enumerate(keys): ++ f.write("%s = %s\n" % (ev.replace("EVENT_", ""), idx)) ++ ++ f.close() +-- +1.8.3.1 + diff --git a/SOURCES/0021-logging-Change-log-file-name-for-glusterd.patch b/SOURCES/0021-logging-Change-log-file-name-for-glusterd.patch deleted file mode 100644 index 65fd2b4..0000000 --- a/SOURCES/0021-logging-Change-log-file-name-for-glusterd.patch +++ /dev/null @@ -1,159 +0,0 @@ -From eaceb4d8c5f08a97cc91843b0f80adc93fc3f391 Mon Sep 17 00:00:00 2001 -From: Vijay Bellur -Date: Wed, 10 Feb 2016 18:27:38 -0500 -Subject: [PATCH 21/86] logging: Change log file name for glusterd - -Backport of http://review.gluster.org/13426 - -log file names are based on: - - a. user provided input (through -l switch while starting a gluster process) - b. mount point paths in the case of native clients - c. volume/configuration files used for starting a gluster process - d. volume server used for starting a gluster process - -Currently glusterd uses scheme c. to have a log file name that reads as - -INSTALL_PREFIX-etc-glusterfs-glusterd.log - -Since glusterd has a well known configuration file, it does not make much -sense to have log file name based on scheme c. This patch changes the name of -glusterd's log file to "glusterd.log". Hopefully this enables users to identify -glusterd's log file more easily. - ->Reviewed-on: http://review.gluster.org/13426 ->Tested-by: Atin Mukherjee ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Atin Mukherjee - -Change-Id: I2d04179c4b9b06271b50eeee3909ee259e8cf547 -BUG: 1306120 -Signed-off-by: Vijay Bellur -Reviewed-on: https://code.engineering.redhat.com/gerrit/84621 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - api/src/glfs.c | 2 +- - glusterfsd/src/glusterfsd.c | 6 +----- - libglusterfs/src/common-utils.c | 12 +++++++++++- - libglusterfs/src/common-utils.h | 8 +++++++- - xlators/mgmt/glusterd/src/glusterd.h | 1 - - 5 files changed, 20 insertions(+), 9 deletions(-) - -diff --git a/api/src/glfs.c b/api/src/glfs.c -index ee74487..3aec115 100644 ---- a/api/src/glfs.c -+++ b/api/src/glfs.c -@@ -847,7 +847,7 @@ pub_glfs_set_logging (struct glfs *fs, const char *logfile, int loglevel) - THIS->ctx = fs->ctx; - - if (!logfile) { -- ret = gf_set_log_file_path (&fs->ctx->cmd_args); -+ ret = gf_set_log_file_path (&fs->ctx->cmd_args, fs->ctx); - if (ret) - goto out; - tmplog = fs->ctx->cmd_args.log_file; -diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c -index 4a2f7ad..e726cc5 100644 ---- a/glusterfsd/src/glusterfsd.c -+++ b/glusterfsd/src/glusterfsd.c -@@ -75,10 +75,6 @@ - #include "daemon.h" - #include "tw.h" - --/* process mode definitions */ --#define GF_SERVER_PROCESS 0 --#define GF_CLIENT_PROCESS 1 --#define GF_GLUSTERD_PROCESS 2 - - /* using argp for command line parsing */ - static char gf_doc[] = ""; -@@ -1556,7 +1552,7 @@ logging_init (glusterfs_ctx_t *ctx, const char *progpath) - cmd_args = &ctx->cmd_args; - - if (cmd_args->log_file == NULL) { -- ret = gf_set_log_file_path (cmd_args); -+ ret = gf_set_log_file_path (cmd_args, ctx); - if (ret == -1) { - fprintf (stderr, "ERROR: failed to set the log file " - "path\n"); -diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c -index 973e31c..9583352 100644 ---- a/libglusterfs/src/common-utils.c -+++ b/libglusterfs/src/common-utils.c -@@ -3413,7 +3413,7 @@ out: - - /* Sets log file path from user provided arguments */ - int --gf_set_log_file_path (cmd_args_t *cmd_args) -+gf_set_log_file_path (cmd_args_t *cmd_args, glusterfs_ctx_t *ctx) - { - int i = 0; - int j = 0; -@@ -3442,6 +3442,16 @@ gf_set_log_file_path (cmd_args_t *cmd_args) - goto done; - } - -+ if (ctx && GF_GLUSTERD_PROCESS == ctx->process_mode) { -+ ret = gf_asprintf (&cmd_args->log_file, -+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log", -+ GLUSTERD_NAME); -+ if (ret > 0) -+ ret = 0; -+ -+ goto done; -+ } -+ - if (cmd_args->volfile) { - j = 0; - i = 0; -diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h -index 93dee58..2930fea 100644 ---- a/libglusterfs/src/common-utils.h -+++ b/libglusterfs/src/common-utils.h -@@ -73,6 +73,7 @@ void trap (void); - - #define GEOREP "geo-replication" - #define GHADOOP "glusterfs-hadoop" -+#define GLUSTERD_NAME "glusterd" - - #define GF_SELINUX_XATTR_KEY "security.selinux" - -@@ -83,6 +84,11 @@ void trap (void); - !strcmp (fs_name, "ext3") || \ - !strcmp (fs_name, "ext4")) - -+/* process mode definitions */ -+#define GF_SERVER_PROCESS 0 -+#define GF_CLIENT_PROCESS 1 -+#define GF_GLUSTERD_PROCESS 2 -+ - /* Defining this here as it is needed by glusterd for setting - * nfs port in volume status. - */ -@@ -221,7 +227,7 @@ int32_t gf_resolve_ip6 (const char *hostname, uint16_t port, int family, - - void gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph); - void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx); --int gf_set_log_file_path (cmd_args_t *cmd_args); -+int gf_set_log_file_path (cmd_args_t *cmd_args, glusterfs_ctx_t *ctx); - int gf_set_log_ident (cmd_args_t *cmd_args); - - #define VECTORSIZE(count) (count * (sizeof (struct iovec))) -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index 9889565..eec1adf 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -38,7 +38,6 @@ - #include "glusterd-rcu.h" - - #define GLUSTERD_TR_LOG_SIZE 50 --#define GLUSTERD_NAME "glusterd" - #define GLUSTERD_SOCKET_LISTEN_BACKLOG 128 - #define GLUSTERD_QUORUM_TYPE_KEY "cluster.server-quorum-type" - #define GLUSTERD_QUORUM_RATIO_KEY "cluster.server-quorum-ratio" --- -1.7.1 - diff --git a/SOURCES/0021-syscall-remove-preadv-and-pwritev-sys-wrappers.patch b/SOURCES/0021-syscall-remove-preadv-and-pwritev-sys-wrappers.patch new file mode 100644 index 0000000..239cdda --- /dev/null +++ b/SOURCES/0021-syscall-remove-preadv-and-pwritev-sys-wrappers.patch @@ -0,0 +1,86 @@ +From ab44b5af9915e15dbe679ac5a16a80d7b0ae45cc Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Tue, 20 Sep 2016 03:09:08 +0530 +Subject: [PATCH 21/74] syscall: remove preadv and pwritev sys wrappers + +Commit 76f1680 introduced sys wrappers for preadv and pwritev where these +syscalls are not supported for RHEL5. These functions are of actually no use +w.r.t downstream code as sys_pwritev is used only in bd xlator which is not +supported in downstream + +Label: DOWNSTREAM ONLY +Change-Id: Ifdc798f1fa74affd77abb06dd14cf9b51f484fe7 +Signed-off-by: Atin Mukherjee +--- + libglusterfs/src/syscall.c | 14 -------------- + libglusterfs/src/syscall.h | 6 ------ + xlators/storage/bd/src/bd.c | 4 ++-- + 3 files changed, 2 insertions(+), 22 deletions(-) + +diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c +index a7d4402..90ef39a 100644 +--- a/libglusterfs/src/syscall.c ++++ b/libglusterfs/src/syscall.c +@@ -318,20 +318,6 @@ sys_write (int fd, const void *buf, size_t count) + + + ssize_t +-sys_preadv (int fd, const struct iovec *iov, int iovcnt, off_t offset) +-{ +- return preadv (fd, iov, iovcnt, offset); +-} +- +- +-ssize_t +-sys_pwritev (int fd, const struct iovec *iov, int iovcnt, off_t offset) +-{ +- return pwritev (fd, iov, iovcnt, offset); +-} +- +- +-ssize_t + sys_pread (int fd, void *buf, size_t count, off_t offset) + { + return pread (fd, buf, count, offset); +diff --git a/libglusterfs/src/syscall.h b/libglusterfs/src/syscall.h +index 0cb61b6..da816cb 100644 +--- a/libglusterfs/src/syscall.h ++++ b/libglusterfs/src/syscall.h +@@ -208,12 +208,6 @@ int + sys_fallocate(int fd, int mode, off_t offset, off_t len); + + ssize_t +-sys_preadv (int fd, const struct iovec *iov, int iovcnt, off_t offset); +- +-ssize_t +-sys_pwritev (int fd, const struct iovec *iov, int iovcnt, off_t offset); +- +-ssize_t + sys_pread(int fd, void *buf, size_t count, off_t offset); + + ssize_t +diff --git a/xlators/storage/bd/src/bd.c b/xlators/storage/bd/src/bd.c +index 07b7ecd..af3ac84 100644 +--- a/xlators/storage/bd/src/bd.c ++++ b/xlators/storage/bd/src/bd.c +@@ -1782,7 +1782,7 @@ __bd_pwritev (int fd, struct iovec *vector, int count, off_t offset, + if (!vector) + return -EFAULT; + +- retval = sys_pwritev (fd, vector, count, offset); ++ retval = pwritev (fd, vector, count, offset); + if (retval == -1) { + int64_t off = offset; + gf_log (THIS->name, GF_LOG_WARNING, +@@ -1805,7 +1805,7 @@ __bd_pwritev (int fd, struct iovec *vector, int count, off_t offset, + vector[index].iov_len = bd_size - internal_offset; + no_space = 1; + } +- retval = sys_pwritev (fd, vector[index].iov_base, ++ retval = pwritev (fd, vector[index].iov_base, + vector[index].iov_len, internal_offset); + if (retval == -1) { + gf_log (THIS->name, GF_LOG_WARNING, +-- +1.8.3.1 + diff --git a/SOURCES/0022-build-ignore-sbindir-conf.py-for-RHEL-5.patch b/SOURCES/0022-build-ignore-sbindir-conf.py-for-RHEL-5.patch new file mode 100644 index 0000000..6d32957 --- /dev/null +++ b/SOURCES/0022-build-ignore-sbindir-conf.py-for-RHEL-5.patch @@ -0,0 +1,32 @@ +From c5b4f68e24c718dcbc5f4ebe0094dcb900ac5314 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Tue, 20 Sep 2016 12:43:43 +0530 +Subject: [PATCH 22/74] build: ignore %{sbindir}/conf.py* for RHEL-5 + +commit dca6f06 has introduced this file in a very wrong location +for a Python file. And rpmbuild is behaving very differently than +RHEL-6 as regards ignoring .pyc and .pyo files. + +Label: DOWNSTREAM ONLY + +Change-Id: I574a500586162917102ae8eb32b939885d2b2d4c +Signed-off-by: Milind Changire +--- + glusterfs.spec.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index f83ae5e..8f30020 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1118,6 +1118,7 @@ exit 0 + %exclude %{_sbindir}/glusterd + %exclude %{_sbindir}/snap_scheduler.py + %exclude %{_datadir}/glusterfs/scripts/stop-all-gluster-processes.sh ++%exclude %{_sbindir}/conf.py* + %if 0%{?_tmpfilesdir:1} + %exclude %{_tmpfilesdir}/gluster.conf + %endif +-- +1.8.3.1 + diff --git a/SOURCES/0022-glusterd-search-for-free-port-from-base_port.patch b/SOURCES/0022-glusterd-search-for-free-port-from-base_port.patch deleted file mode 100644 index 6940cf1..0000000 --- a/SOURCES/0022-glusterd-search-for-free-port-from-base_port.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7e7ab869176fc7df8bc8c09a16d271ea235d7c80 Mon Sep 17 00:00:00 2001 -From: Atin Mukherjee -Date: Mon, 18 Jul 2016 12:54:38 +0530 -Subject: [PATCH 22/86] glusterd: search for free port from base_port - -Backport of http://review.gluster.org/#/c/14939/ - -When a volume is deleted, the freed up ports are never considered for further -allocation since pmap_registry_alloc () always starts scanning from last_alloc. -So in use cases where gluster volumes are frequently created and deleted -managing ports become nightmare as for every new volume creation ports need to -be opened up by the admin based on the volume topology. - -Solution: Instead of scanning from last_alloc, pmap_registry_alloc () always -starts from base_port now. What that means is glusterd will always try to find -out the ports which have been freed from earlier volumes and reallocate them for -the newer ones. There could be possibilities that when a volume is stopped and -started back their brick ports are changed which is completely acceptible IMHO. - ->Reviewed-on: http://review.gluster.org/14939 ->CentOS-regression: Gluster Build System ->NetBSD-regression: NetBSD Build System ->Reviewed-by: Jeff Darcy ->Smoke: Gluster Build System - -This BZ fixes #1263090 as well - -Change-Id: I99ccc11732b6a75527fcb6abafaf249ed02b3b78 -BUG: 1356058 -Signed-off-by: Atin Mukherjee -Reviewed-on: https://code.engineering.redhat.com/gerrit/84627 ---- - xlators/mgmt/glusterd/src/glusterd-pmap.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c -index 6a89a4f..3b9b227 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-pmap.c -+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c -@@ -184,7 +184,7 @@ pmap_registry_alloc (xlator_t *this) - - pmap = pmap_registry_get (this); - -- for (p = pmap->last_alloc; p <= GF_PORT_MAX; p++) { -+ for (p = pmap->base_port; p <= GF_PORT_MAX; p++) { - /* GF_PMAP_PORT_FOREIGN may be freed up ? */ - if ((pmap->ports[p].type == GF_PMAP_PORT_FREE) || - (pmap->ports[p].type == GF_PMAP_PORT_FOREIGN)) { -@@ -197,7 +197,7 @@ pmap_registry_alloc (xlator_t *this) - } - } - -- if (port) -+ if (port > pmap->last_alloc) - pmap->last_alloc = port; - - return port; --- -1.7.1 - diff --git a/SOURCES/0023-build-randomize-temp-file-names-in-pretrans-scriptle.patch b/SOURCES/0023-build-randomize-temp-file-names-in-pretrans-scriptle.patch new file mode 100644 index 0000000..5366d84 --- /dev/null +++ b/SOURCES/0023-build-randomize-temp-file-names-in-pretrans-scriptle.patch @@ -0,0 +1,248 @@ +From fdf4475ea3598b4287803001932f426f2c58f3b1 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Fri, 14 Oct 2016 12:53:27 +0530 +Subject: [PATCH 23/74] build: randomize temp file names in pretrans scriptlets + +Security issue CVE-2015-1795 mentions about possibility of file name +spoof attack for the %pretrans server scriptlet. +Since %pretrans scriptlets are executed only for server builds, we can +use os.tmpname() to randomize temporary file names for all %pretrans +scriptlets using this mechanism. + +Label: DOWNSTREAM ONLY + +Change-Id: Ic82433897432794b6d311d836355aa4bad886369 +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/86187 +Reviewed-by: Siddharth Sharma +Reviewed-by: Niels de Vos +Reviewed-by: Atin Mukherjee +--- + glusterfs.spec.in | 106 ++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 64 insertions(+), 42 deletions(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 8f30020..ab61688 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1579,9 +1579,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1620,9 +1621,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-api_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1661,9 +1663,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-api-devel_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1702,9 +1705,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-cli_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1743,9 +1747,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-client-xlators_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1784,9 +1789,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-devel_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1825,9 +1831,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-fuse_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1866,9 +1873,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-ganesha_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1908,9 +1916,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-geo-replication_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1950,9 +1959,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-libs_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -1991,9 +2001,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/python-gluster_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -2033,9 +2044,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-rdma_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -2076,9 +2088,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-resource-agents_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -2118,9 +2131,10 @@ if [ $? -eq 0 ]; then + fi + ]] + +--- rpm in RHEL5 does not have os.tmpname() +--- io.tmpfile() can not be resolved to a filename to pass to bash :-/ +-tmpname = "/tmp/glusterfs-server_pretrans_" .. os.date("%s") ++-- Since we run pretrans scripts only for RPMs built for a server build, ++-- we can now use os.tmpname() since it is available on RHEL6 and later ++-- platforms which are server platforms. ++tmpname = os.tmpname() + tmpfile = io.open(tmpname, "w") + tmpfile:write(script) + tmpfile:close() +@@ -2211,6 +2225,13 @@ end + * Thu Nov 24 2016 Jiffin Tony Thottan + - remove S31ganesha-reset.sh from hooks (#1397795) + ++* Fri Oct 14 2016 Milind Changire ++- Changed pretrans scripts to use os.tmpname() for enhanced security ++ for server builds only (#1362044) ++ ++* Tue Sep 27 2016 Milind Changire ++- Added systemd requirement to glusterfs-server and glusterfs-events packages ++ + * Thu Sep 22 2016 Kaleb S. KEITHLEY + - python-ctypes no long exists, now in python stdlib (#1378436) + +@@ -2330,6 +2351,7 @@ end + + * Mon May 18 2015 Milind Changire + - Move file peer_add_secret_pub to the server RPM to support glusterfind (#1221544) ++ + * Sun May 17 2015 Niels de Vos + - Fix building on RHEL-5 based distributions (#1222317) + +-- +1.8.3.1 + diff --git a/SOURCES/0023-glusterd-clean-up-old-port-and-allocate-new-one-on-e.patch b/SOURCES/0023-glusterd-clean-up-old-port-and-allocate-new-one-on-e.patch deleted file mode 100644 index 2c6e966..0000000 --- a/SOURCES/0023-glusterd-clean-up-old-port-and-allocate-new-one-on-e.patch +++ /dev/null @@ -1,297 +0,0 @@ -From 7492e5c60998786b84edb1bb3c21bba503652129 Mon Sep 17 00:00:00 2001 -From: Atin Mukherjee -Date: Mon, 25 Jul 2016 19:09:08 +0530 -Subject: [PATCH 23/86] glusterd: clean up old port and allocate new one on every restart - -Backport of http://review.gluster.org/15005 - -GlusterD as of now was blindly assuming that the brick port which was already -allocated would be available to be reused and that assumption is absolutely -wrong. - -Solution : On first attempt, we thought GlusterD should check if the already -allocated brick ports are free, if not allocate new port and pass it to the -daemon. But with that approach there is a possibility that if PMAP_SIGNOUT is -missed out, the stale port will be given back to the clients where connection -will keep on failing. Now given the port allocation always start from base_port, -if everytime a new port has to be allocated for the daemons, the port range will -still be under control. So this fix tries to clean up old port using -pmap_registry_remove () if any and then goes for pmap_registry_alloc () - -This BZ fixes #1263090 as well - ->Reviewed-on: http://review.gluster.org/15005 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Avra Sengupta - -Change-Id: If54a055d01ab0cbc06589dc1191d8fc52eb2c84f -BUG: 1356058 -Signed-off-by: Atin Mukherjee -Reviewed-on: https://code.engineering.redhat.com/gerrit/84635 ---- - .../glusterd/1313628-import-brick-ports-always.t | 47 -------------------- - tests/features/ssl-ciphers.t | 5 ++ - xlators/mgmt/glusterd/src/glusterd-messages.h | 10 ++++- - xlators/mgmt/glusterd/src/glusterd-pmap.c | 24 ++++++++++- - xlators/mgmt/glusterd/src/glusterd-pmap.h | 2 + - xlators/mgmt/glusterd/src/glusterd-snapd-svc.c | 23 +--------- - xlators/mgmt/glusterd/src/glusterd-utils.c | 12 +++--- - 7 files changed, 46 insertions(+), 77 deletions(-) - delete mode 100755 tests/bugs/glusterd/1313628-import-brick-ports-always.t - -diff --git a/tests/bugs/glusterd/1313628-import-brick-ports-always.t b/tests/bugs/glusterd/1313628-import-brick-ports-always.t -deleted file mode 100755 -index d04c429..0000000 ---- a/tests/bugs/glusterd/1313628-import-brick-ports-always.t -+++ /dev/null -@@ -1,47 +0,0 @@ --#!/bin/bash --. $(dirname $0)/../../include.rc --. $(dirname $0)/../../cluster.rc -- --## Check that brick ports are always copied on import --## -------------------------------------------------- --## This test checks that the brick ports are copied on import by checking that --## they don't change when the following happens, --## - Stop a volume --## - Stop glusterd --## - Start the stopped volume --## - Start the stopped glusterd -- --function get_brick_port() { -- local VOL=$1 -- local BRICK=$2 -- $CLI2 volume status $VOL $BRICK --xml | sed -ne 's/.*\([0-9]*\)<\/port>/\1/p' --} -- -- --cleanup -- --TEST launch_cluster 2 --TEST $CLI1 peer probe $H2 --EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count -- --# Create and start volume so that brick port assignment happens --TEST $CLI1 volume create $V0 $H1:$B1/$V0 $H2:$B2/$V0 --TEST $CLI1 volume start $V0 -- --# Save port for 2nd brick --BPORT_ORIG=$(get_brick_port $V0 $H2:$B2/$V0) -- --# Stop volume, stop 2nd glusterd, start volume, start 2nd glusterd --TEST $CLI1 volume stop $V0 --TEST kill_glusterd 2 -- --TEST $CLI1 volume start $V0 --TEST start_glusterd 2 --EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count -- --# Get new port and compare with old one --EXPECT_WITHIN $PROCESS_UP_TIMEOUT $BPORT_ORIG get_brick_port $V0 $H2:$B2/$V0 -- --$CLI1 volume stop $V0 -- --cleanup -diff --git a/tests/features/ssl-ciphers.t b/tests/features/ssl-ciphers.t -index 9ee7fc6..f5909f3 100644 ---- a/tests/features/ssl-ciphers.t -+++ b/tests/features/ssl-ciphers.t -@@ -137,6 +137,7 @@ EXPECT "`pwd`/`dirname $0`/dh1024.pem" volume_option $V0 ssl.dh-param - TEST $CLI volume stop $V0 - TEST $CLI volume start $V0 - EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count -+BRICK_PORT=`brick_port $V0` - EXPECT "Y" openssl_connect -cipher EDH -connect $H0:$BRICK_PORT - - # Test the cipher-list option -@@ -145,6 +146,7 @@ EXPECT AES256-SHA volume_option $V0 ssl.cipher-list - TEST $CLI volume stop $V0 - TEST $CLI volume start $V0 - EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count -+BRICK_PORT=`brick_port $V0` - EXPECT "Y" openssl_connect -cipher AES256-SHA -connect $H0:$BRICK_PORT - EXPECT "N" openssl_connect -cipher AES128-SHA -connect $H0:$BRICK_PORT - -@@ -154,6 +156,7 @@ EXPECT EECDH:EDH:!TLSv1 volume_option $V0 ssl.cipher-list - TEST $CLI volume stop $V0 - TEST $CLI volume start $V0 - EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count -+BRICK_PORT=`brick_port $V0` - EXPECT "N" openssl_connect -cipher AES256-SHA -connect $H0:$BRICK_PORT - EXPECT "Y" openssl_connect -cipher EECDH -connect $H0:$BRICK_PORT - -@@ -162,6 +165,7 @@ EXPECT invalid volume_option $V0 ssl.ec-curve - TEST $CLI volume stop $V0 - TEST $CLI volume start $V0 - EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count -+BRICK_PORT=`brick_port $V0` - EXPECT "N" openssl_connect -cipher EECDH -connect $H0:$BRICK_PORT - - TEST $CLI volume set $V0 ssl.ec-curve secp521r1 -@@ -169,6 +173,7 @@ EXPECT secp521r1 volume_option $V0 ssl.ec-curve - TEST $CLI volume stop $V0 - TEST $CLI volume start $V0 - EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" online_brick_count -+BRICK_PORT=`brick_port $V0` - EXPECT "Y" openssl_connect -cipher EECDH -connect $H0:$BRICK_PORT - - # test revocation -diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h -index ba40b8f..623f4dc 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-messages.h -+++ b/xlators/mgmt/glusterd/src/glusterd-messages.h -@@ -41,7 +41,7 @@ - - #define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD - --#define GLFS_NUM_MESSAGES 578 -+#define GLFS_NUM_MESSAGES 579 - - #define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1) - /* Messaged with message IDs */ -@@ -4673,6 +4673,14 @@ - */ - #define GD_MSG_DICT_GET_SUCCESS (GLUSTERD_COMP_BASE + 578) - -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendedaction -+ * -+ */ -+#define GD_MSG_PMAP_REGISTRY_REMOVE_FAIL (GLUSTERD_COMP_BASE + 579) -+ - /*------------*/ - #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" - #endif /* !_GLUSTERD_MESSAGES_H_ */ -diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c -index 3b9b227..377d206 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-pmap.c -+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c -@@ -203,6 +203,29 @@ pmap_registry_alloc (xlator_t *this) - return port; - } - -+/* pmap_assign_port does a pmap_registry_remove followed by pmap_registry_alloc, -+ * the reason for the former is to ensure we don't end up with stale ports -+ */ -+int -+pmap_assign_port (xlator_t *this, int old_port, const char *path) -+{ -+ int ret = -1; -+ int new_port = 0; -+ -+ if (old_port) { -+ ret = pmap_registry_remove (this, 0, path, -+ GF_PMAP_PORT_BRICKSERVER, NULL); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_WARNING, -+ GD_MSG_PMAP_REGISTRY_REMOVE_FAIL, 0, "Failed toi" -+ "remove pmap registry for older signin for path" -+ " %s", path); -+ } -+ } -+ new_port = pmap_registry_alloc (this); -+ return new_port; -+} -+ - int - pmap_registry_bind (xlator_t *this, int port, const char *brickname, - gf_pmap_port_type_t type, void *xprt) -@@ -452,7 +475,6 @@ __gluster_pmap_signout (rpcsvc_request_t *req) - req->rpc_err = GARBAGE_ARGS; - goto fail; - } -- - rsp.op_ret = pmap_registry_remove (THIS, args.port, args.brick, - GF_PMAP_PORT_BRICKSERVER, req->trans); - -diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.h b/xlators/mgmt/glusterd/src/glusterd-pmap.h -index 95ded04..14187da 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-pmap.h -+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.h -@@ -35,6 +35,8 @@ struct pmap_registry { - struct pmap_port_status ports[65536]; - }; - -+int pmap_assign_port (xlator_t *this, int port, const char *path); -+int pmap_mark_port_leased (xlator_t *this, int port); - int pmap_registry_alloc (xlator_t *this); - int pmap_registry_bind (xlator_t *this, int port, const char *brickname, - gf_pmap_port_type_t type, void *xprt); -diff --git a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c -index 830dc1a..36e4a19 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c -+++ b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c -@@ -295,28 +295,7 @@ glusterd_snapdsvc_start (glusterd_svc_t *svc, int flags) - "--brick-name", snapd_id, - "-S", svc->conn.sockpath, NULL); - -- /* Do a pmap registry remove on the older connected port */ -- if (volinfo->snapd.port) { -- ret = pmap_registry_remove (this, volinfo->snapd.port, -- snapd_id, GF_PMAP_PORT_BRICKSERVER, -- NULL); -- if (ret) { -- snprintf (msg, sizeof (msg), "Failed to remove pmap " -- "registry for older signin"); -- goto out; -- } -- } -- -- snapd_port = pmap_registry_alloc (THIS); -- if (!snapd_port) { -- snprintf (msg, sizeof (msg), "Could not allocate port " -- "for snapd service for volume %s", -- volinfo->volname); -- runner_log (&runner, this->name, GF_LOG_DEBUG, msg); -- ret = -1; -- goto out; -- } -- -+ snapd_port = pmap_assign_port (THIS, volinfo->snapd.port, snapd_id); - volinfo->snapd.port = snapd_port; - - runner_add_arg (&runner, "--brick-port"); -diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c -index 46a3509..44c9284 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c -@@ -1786,6 +1786,7 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo, - char socketpath[PATH_MAX] = {0}; - char glusterd_uuid[1024] = {0,}; - char valgrind_logfile[PATH_MAX] = {0}; -+ char rdma_brick_path[PATH_MAX] = {0,}; - - GF_ASSERT (volinfo); - GF_ASSERT (brickinfo); -@@ -1818,9 +1819,7 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo, - if (gf_is_service_running (pidfile, NULL)) - goto connect; - -- port = brickinfo->port; -- if (!port) -- port = pmap_registry_alloc (THIS); -+ port = pmap_assign_port (THIS, brickinfo->port, brickinfo->path); - - /* Build the exp_path, before starting the glusterfsd even in - valgrind mode. Otherwise all the glusterfsd processes start -@@ -1885,9 +1884,10 @@ retry: - if (volinfo->transport_type != GF_TRANSPORT_BOTH_TCP_RDMA) { - runner_argprintf (&runner, "%d", port); - } else { -- rdma_port = brickinfo->rdma_port; -- if (!rdma_port) -- rdma_port = pmap_registry_alloc (THIS); -+ snprintf (rdma_brick_path, sizeof(rdma_brick_path), "%s.rdma", -+ brickinfo->path); -+ rdma_port = pmap_assign_port (THIS, brickinfo->rdma_port, -+ rdma_brick_path); - runner_argprintf (&runner, "%d,%d", port, rdma_port); - runner_add_arg (&runner, "--xlator-option"); - runner_argprintf (&runner, "%s-server.transport.rdma.listen-port=%d", --- -1.7.1 - diff --git a/SOURCES/0024-glusterd-Improve-mountbroker-logs.patch b/SOURCES/0024-glusterd-Improve-mountbroker-logs.patch deleted file mode 100644 index a071775..0000000 --- a/SOURCES/0024-glusterd-Improve-mountbroker-logs.patch +++ /dev/null @@ -1,247 +0,0 @@ -From 42ddc22edb25c9666d01bd81b421d931f4a0d558 Mon Sep 17 00:00:00 2001 -From: Kotresh HR -Date: Thu, 25 Aug 2016 22:20:30 +0530 -Subject: [PATCH 24/86] glusterd: Improve mountbroker logs - -When Mountbroker mount fails, it was just returning -EPERM or EACCESS without logging exact failure. -This patch improves the logging by logging exact -failure. - ->Change-Id: I3cd905f95865153f70dfcc3bf1fa4dd19af16455 ->BUG: 1346138 ->Signed-off-by: Kotresh HR ->Reviewed-on: http://review.gluster.org/15319 ->Smoke: Gluster Build System ->CentOS-regression: Gluster Build System ->NetBSD-regression: NetBSD Build System ->Reviewed-by: Atin Mukherjee - -Change-Id: I3cd905f95865153f70dfcc3bf1fa4dd19af16455 -BUG: 1359607 -Signed-off-by: Kotresh HR -Reviewed-on: https://code.engineering.redhat.com/gerrit/84661 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - xlators/mgmt/glusterd/src/glusterd-messages.h | 34 +++++++++++++- - xlators/mgmt/glusterd/src/glusterd-mountbroker.c | 56 ++++++++++++++++++++-- - 2 files changed, 84 insertions(+), 6 deletions(-) - -diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h -index 623f4dc..2c76dbf 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-messages.h -+++ b/xlators/mgmt/glusterd/src/glusterd-messages.h -@@ -41,7 +41,7 @@ - - #define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD - --#define GLFS_NUM_MESSAGES 579 -+#define GLFS_NUM_MESSAGES 583 - - #define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1) - /* Messaged with message IDs */ -@@ -4681,6 +4681,38 @@ - */ - #define GD_MSG_PMAP_REGISTRY_REMOVE_FAIL (GLUSTERD_COMP_BASE + 579) - -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendedaction -+ * -+ */ -+#define GD_MSG_MNTBROKER_LABEL_NULL (GLUSTERD_COMP_BASE + 580) -+ -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendedaction -+ * -+ */ -+#define GD_MSG_MNTBROKER_LABEL_MISS (GLUSTERD_COMP_BASE + 581) -+ -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendedaction -+ * -+ */ -+#define GD_MSG_MNTBROKER_SPEC_MISMATCH (GLUSTERD_COMP_BASE + 582) -+ -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendedaction -+ * -+ */ -+#define GD_MSG_SYSCALL_FAIL (GLUSTERD_COMP_BASE + 583) -+ - /*------------*/ - #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" - #endif /* !_GLUSTERD_MESSAGES_H_ */ -diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c -index 7c069ce..f992adc 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c -+++ b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c -@@ -447,7 +447,7 @@ _arg_parse_uid (char *val, void *data) - } - - static int --evaluate_mount_request (gf_mount_spec_t *mspec, dict_t *argdict) -+evaluate_mount_request (xlator_t *this, gf_mount_spec_t *mspec, dict_t *argdict) - { - struct gf_set_descriptor sd = {{0,},}; - int i = 0; -@@ -476,8 +476,14 @@ evaluate_mount_request (gf_mount_spec_t *mspec, dict_t *argdict) - if (mspec->patterns[i].negative) - match = !match; - -- if (!match) -+ if (!match) { -+ gf_msg (this->name, GF_LOG_ERROR, EPERM, -+ GD_MSG_MNTBROKER_SPEC_MISMATCH, -+ "Mountbroker spec mismatch!!! SET: %d " -+ "COMPONENT: %d. Review the mount args passed", -+ mspec->patterns[i].condition, i); - return -EPERM; -+ } - } - - ret = seq_dict_foreach (argdict, _arg_parse_uid, &uid); -@@ -526,6 +532,7 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - int ret = 0; - xlator_t *this = THIS; - mode_t orig_umask = 0; -+ gf_boolean_t found_label = _gf_false; - - priv = this->private; - GF_ASSERT (priv); -@@ -536,12 +543,19 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - if (dict_get_str (this->options, "mountbroker-root", - &mountbroker_root) != 0) { - *op_errno = ENOENT; -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "'option mountbroker-root' " -+ "missing in glusterd vol file"); - goto out; - } - - GF_ASSERT (label); - if (!*label) { - *op_errno = EINVAL; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_MNTBROKER_LABEL_MISS, -+ "label is NULL (%s)", -+ strerror (*op_errno)); - goto out; - } - -@@ -550,11 +564,20 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - speclist) { - if (strcmp (mspec->label, label) != 0) - continue; -- uid = evaluate_mount_request (mspec, argdict); -+ -+ found_label = _gf_true; -+ uid = evaluate_mount_request (this, mspec, argdict); - break; - } - if (uid < 0) { - *op_errno = -uid; -+ if (!found_label) { -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_MNTBROKER_LABEL_MISS, -+ "Missing mspec: Check the corresponding option " -+ "in glusterd vol file for mountbroker user: %s", -+ label); -+ } - goto out; - } - -@@ -562,11 +585,17 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - seq_dict_foreach (argdict, _volname_get, &volname); - if (!volname) { - *op_errno = EINVAL; -+ gf_msg (this->name, GF_LOG_ERROR, EINVAL, -+ GD_MSG_DICT_GET_FAILED, -+ "Dict get failed for the key 'volname'"); - goto out; - } - if (glusterd_volinfo_find (volname, &vol) != 0 || - !glusterd_is_volume_started (vol)) { - *op_errno = ENOENT; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_MOUNT_REQ_FAIL, -+ "Either volume is not started or volinfo not found"); - goto out; - } - -@@ -596,22 +625,34 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - ret = 0; - if (ret == -1) { - *op_errno = errno; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_SYSCALL_FAIL, -+ "Mountbroker User directory creation failed"); - goto out; - } - ret = sys_lstat (mtptemp, &st); - if (ret == -1) { - *op_errno = errno; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_SYSCALL_FAIL, -+ "stat on mountbroker user directory failed"); - goto out; - } - if (!(S_ISDIR (st.st_mode) && (st.st_mode & ~S_IFMT) == 0700 && - st.st_uid == uid && st.st_gid == 0)) { - *op_errno = EACCES; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_MOUNT_REQ_FAIL, -+ "Incorrect mountbroker user directory attributes"); - goto out; - } - *sla = '/'; - - if (!mkdtemp (mtptemp)) { - *op_errno = errno; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_SYSCALL_FAIL, -+ "Mountbroker mount directory creation failed"); - goto out; - } - -@@ -630,6 +671,9 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - umask(orig_umask); - if (ret == -1) { - *op_errno = errno; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_SYSCALL_FAIL, -+ "Mountbroker cookie file creation failed"); - goto out; - } - sys_close (ret); -@@ -652,6 +696,9 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - *cookieswitch = '\0'; - if (ret == -1) { - *op_errno = errno; -+ gf_msg (this->name, GF_LOG_ERROR, *op_errno, -+ GD_MSG_SYSCALL_FAIL, -+ "symlink or rename failed"); - goto out; - } - -@@ -674,8 +721,7 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - ret = -1; - gf_msg (this->name, GF_LOG_WARNING, *op_errno, - GD_MSG_MOUNT_REQ_FAIL, -- "unsuccessful mount request (%s)", -- strerror (*op_errno)); -+ "unsuccessful mount request"); - if (mtptemp) { - *cookieswitch = '/'; - sys_unlink (mtptemp); --- -1.7.1 - diff --git a/SOURCES/0024-glusterd-gNFS-On-post-upgrade-to-3.2-disable-gNFS-fo.patch b/SOURCES/0024-glusterd-gNFS-On-post-upgrade-to-3.2-disable-gNFS-fo.patch new file mode 100644 index 0000000..fcc3532 --- /dev/null +++ b/SOURCES/0024-glusterd-gNFS-On-post-upgrade-to-3.2-disable-gNFS-fo.patch @@ -0,0 +1,80 @@ +From abd66a26f1a6fb998c0b6b60c3004ea8414ffee0 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Thu, 17 Nov 2016 12:44:38 +0530 +Subject: [PATCH 24/74] glusterd/gNFS : On post upgrade to 3.2, disable gNFS + for all volumes + +Currently on 3.2 gNFS is dsiabled for newly created volumes or old volumes +with default value. There will be volumes which have explicitly turn off +nfs.disable option. This change disable gNFS even for that volume as well. + +label : DOWNSTREAM ONLY + +Change-Id: I4ddeb23690271034b0bbb3fc50b359350b5eae87 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://code.engineering.redhat.com/gerrit/90425 +Reviewed-by: Atin Mukherjee +Tested-by: Atin Mukherjee +--- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 43 +++++++++++++++++------------- + 1 file changed, 25 insertions(+), 18 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 6d5b8cf..09be165 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -2437,26 +2437,33 @@ glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo) + GF_VALIDATE_OR_GOTO (this->name, conf, out); + + /* 3.9.0 onwards gNFS will be disabled by default. In case of an upgrade +- * from anything below than 3.9.0 to 3.9.x the volume's dictionary will +- * not have 'nfs.disable' key set which means the same will not be set +- * to on until explicitly done. setnfs.disable to 'on' at op-version +- * bump up flow is the ideal way here. The same is also applicable for +- * transport.address-family where if the transport type is set to tcp +- * then transport.address-family is defaulted to 'inet'. ++ * from anything below than 3.9.0 to 3.9.x, the value for nfs.disable is ++ * set to 'on' for all volumes even if it is explicitly set to 'off' in ++ * previous version. This change is only applicable to downstream code. ++ * Setting nfs.disable to 'on' at op-version bump up flow is the ideal ++ * way here. The same is also applicable for transport.address-family ++ * where if the transport type is set to tcp then transport.address-family ++ * is defaulted to 'inet'. + */ + if (conf->op_version >= GD_OP_VERSION_3_9_0) { +- if (dict_get_str_boolean (volinfo->dict, NFS_DISABLE_MAP_KEY, +- 1)) { +- ret = dict_set_dynstr_with_alloc (volinfo->dict, +- NFS_DISABLE_MAP_KEY, +- "on"); +- if (ret) { +- gf_msg (this->name, GF_LOG_ERROR, errno, +- GD_MSG_DICT_SET_FAILED, "Failed to set " +- "option ' NFS_DISABLE_MAP_KEY ' on " +- "volume %s", volinfo->volname); +- goto out; +- } ++ if (!(dict_get_str_boolean (volinfo->dict, NFS_DISABLE_MAP_KEY, ++ 0))) { ++ gf_msg (this->name, GF_LOG_INFO, 0, 0, "Gluster NFS is" ++ " being deprecated in favor of NFS-Ganesha, " ++ "hence setting nfs.disable to 'on' for volume " ++ "%s. Please re-enable it if requires", ++ volinfo->volname); ++ } ++ ++ ret = dict_set_dynstr_with_alloc (volinfo->dict, ++ NFS_DISABLE_MAP_KEY, ++ "on"); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, errno, ++ GD_MSG_DICT_SET_FAILED, "Failed to set " ++ "option ' NFS_DISABLE_MAP_KEY ' on " ++ "volume %s", volinfo->volname); ++ goto out; + } + ret = dict_get_str (volinfo->dict, "transport.address-family", + &address_family_str); +-- +1.8.3.1 + diff --git a/SOURCES/0025-build-Add-dependency-on-netstat-for-glusterfs-ganesh.patch b/SOURCES/0025-build-Add-dependency-on-netstat-for-glusterfs-ganesh.patch new file mode 100644 index 0000000..a84a39d --- /dev/null +++ b/SOURCES/0025-build-Add-dependency-on-netstat-for-glusterfs-ganesh.patch @@ -0,0 +1,58 @@ +From 867536a4ced38d72a7d980cd34bcbf0ce876206a Mon Sep 17 00:00:00 2001 +From: Soumya Koduri +Date: Fri, 18 Nov 2016 12:47:06 +0530 +Subject: [PATCH 25/74] build: Add dependency on netstat for glusterfs-ganesha + pkg + +portblock resource-agent needs netstat command but this dependency +should have been ideally added to resource-agents package. But the +fixes (bug1395594, bug1395596) are going to be available only +in the future RHEL 6.9 and RHEL 7.4 releases. Hence as an interim +workaround, we agreed to add this dependency for glusterfs-ganesha package. + +label : DOWNSTREAM ONLY + +Change-Id: I6ac1003103755d7534dd079c821bbaacd8dd94b8 +Signed-off-by: Soumya Koduri +Reviewed-on: https://code.engineering.redhat.com/gerrit/90529 +Reviewed-by: Jiffin Thottan +Reviewed-by: Milind Changire +Reviewed-by: Atin Mukherjee +--- + glusterfs.spec.in | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index ab61688..343e88f 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -414,6 +414,11 @@ Requires: nfs-ganesha-gluster, pcs, dbus + %if ( 0%{?rhel} && 0%{?rhel} == 6 ) + Requires: cman, pacemaker, corosync + %endif ++%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 5 ) ++# we need portblock resource-agent in 3.9.5 and later. ++Requires: resource-agents >= 3.9.5 ++Requires: net-tools ++%endif + + %description ganesha + GlusterFS is a distributed file-system capable of scaling to several +@@ -2225,6 +2230,14 @@ end + * Thu Nov 24 2016 Jiffin Tony Thottan + - remove S31ganesha-reset.sh from hooks (#1397795) + ++* Fri Nov 18 2016 Soumya Koduri ++- As an interim fix add dependency on netstat(/net-tools) for glusterfs-ganesha package (#1395574) ++ ++* Fri Nov 11 2016 Soumya Koduri ++- Add dependency on portblock resource agent for ganesha package (#1278336) ++- Fix incorrect Requires for portblock resource agent (#1278336) ++- Update version checks for portblock resource agent on RHEL (#1278336) ++ + * Fri Oct 14 2016 Milind Changire + - Changed pretrans scripts to use os.tmpname() for enhanced security + for server builds only (#1362044) +-- +1.8.3.1 + diff --git a/SOURCES/0025-glusterd-Fix-msgid-in-mountbroker-logs.patch b/SOURCES/0025-glusterd-Fix-msgid-in-mountbroker-logs.patch deleted file mode 100644 index 41713e7..0000000 --- a/SOURCES/0025-glusterd-Fix-msgid-in-mountbroker-logs.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0eeda63e0092c39a357bdf4b3e6a148623da7a96 Mon Sep 17 00:00:00 2001 -From: Kotresh HR -Date: Mon, 29 Aug 2016 12:40:48 +0530 -Subject: [PATCH 25/86] glusterd: Fix msgid in mountbroker logs - -Fix declared but not used msgid in mountbroker -logs. - ->Change-Id: I68d331f2741726624f647a8bc437e1ebcddd038f ->Signed-off-by: Kotresh HR ->BUG: 1346138 ->Reviewed-on: http://review.gluster.org/15333 ->Reviewed-by: Atin Mukherjee ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Smoke: Gluster Build System - -Change-Id: I68d331f2741726624f647a8bc437e1ebcddd038f -Signed-off-by: Kotresh HR -BUG: 1359607 -Reviewed-on: https://code.engineering.redhat.com/gerrit/84662 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - xlators/mgmt/glusterd/src/glusterd-mountbroker.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c -index f992adc..b7db3bd 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c -+++ b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c -@@ -553,7 +553,7 @@ glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno) - if (!*label) { - *op_errno = EINVAL; - gf_msg (this->name, GF_LOG_ERROR, *op_errno, -- GD_MSG_MNTBROKER_LABEL_MISS, -+ GD_MSG_MNTBROKER_LABEL_NULL, - "label is NULL (%s)", - strerror (*op_errno)); - goto out; --- -1.7.1 - diff --git a/SOURCES/0026-glusterd-gNFS-explicitly-set-nfs.disable-to-off-afte.patch b/SOURCES/0026-glusterd-gNFS-explicitly-set-nfs.disable-to-off-afte.patch new file mode 100644 index 0000000..bd5c2e2 --- /dev/null +++ b/SOURCES/0026-glusterd-gNFS-explicitly-set-nfs.disable-to-off-afte.patch @@ -0,0 +1,105 @@ +From 14bfa98824d40ff1f721a905f8e8ffd557f96eef Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Thu, 15 Dec 2016 17:14:01 +0530 +Subject: [PATCH 26/74] glusterd/gNFS : explicitly set "nfs.disable" to "off" + after 3.2 upgrade + +Gluster NFS was enabled by default for all volumes till 3.1. But 3.2 onwards +for the new volumes it will be disabled by setting "nfs.disable" to "on". +This take patch will take care of existing volume in such a way that if the +option is not configured, it will set "nfs.disable" to "off" during op-version +bump up. + +Also this patch removes the warning message while enabling gluster NFS for +a volume. + +label : DOWNSTREAM ONLY + +Change-Id: Ib199c3180204f917791b4627c58d846750d18a5a +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://code.engineering.redhat.com/gerrit/93146 +Reviewed-by: Soumya Koduri +Reviewed-by: Atin Mukherjee +--- + cli/src/cli-cmd-parser.c | 14 -------------- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 29 ++++++++++++----------------- + 2 files changed, 12 insertions(+), 31 deletions(-) + +diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c +index c8ed367..ca4d906 100644 +--- a/cli/src/cli-cmd-parser.c ++++ b/cli/src/cli-cmd-parser.c +@@ -1621,20 +1621,6 @@ cli_cmd_volume_set_parse (struct cli_state *state, const char **words, + goto out; + } + } +- if ((!strcmp (key, "nfs.disable")) && +- (!strcmp (value, "off"))) { +- question = "Gluster NFS is being deprecated in favor " +- "of NFS-Ganesha Enter \"yes\" to continue " +- "using Gluster NFS"; +- answer = cli_cmd_get_confirmation (state, question); +- if (GF_ANSWER_NO == answer) { +- gf_log ("cli", GF_LOG_ERROR, "Operation " +- "cancelled, exiting"); +- *op_errstr = gf_strdup ("Aborted by user."); +- ret = -1; +- goto out; +- } +- } + } + + ret = dict_set_int32 (dict, "count", wordcount-3); +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 09be165..0557ad8 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -2438,9 +2438,9 @@ glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo) + + /* 3.9.0 onwards gNFS will be disabled by default. In case of an upgrade + * from anything below than 3.9.0 to 3.9.x, the value for nfs.disable is +- * set to 'on' for all volumes even if it is explicitly set to 'off' in ++ * set to 'off' for all volumes even if it is not explicitly set in the + * previous version. This change is only applicable to downstream code. +- * Setting nfs.disable to 'on' at op-version bump up flow is the ideal ++ * Setting nfs.disable to 'off' at op-version bump up flow is the ideal + * way here. The same is also applicable for transport.address-family + * where if the transport type is set to tcp then transport.address-family + * is defaulted to 'inet'. +@@ -2448,23 +2448,18 @@ glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo) + if (conf->op_version >= GD_OP_VERSION_3_9_0) { + if (!(dict_get_str_boolean (volinfo->dict, NFS_DISABLE_MAP_KEY, + 0))) { +- gf_msg (this->name, GF_LOG_INFO, 0, 0, "Gluster NFS is" +- " being deprecated in favor of NFS-Ganesha, " +- "hence setting nfs.disable to 'on' for volume " +- "%s. Please re-enable it if requires", +- volinfo->volname); ++ ret = dict_set_dynstr_with_alloc (volinfo->dict, ++ NFS_DISABLE_MAP_KEY, ++ "off"); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, errno, ++ GD_MSG_DICT_SET_FAILED, "Failed to turn " ++ "off ' NFS_DISABLE_MAP_KEY ' option for " ++ "volume %s", volinfo->volname); ++ goto out; ++ } + } + +- ret = dict_set_dynstr_with_alloc (volinfo->dict, +- NFS_DISABLE_MAP_KEY, +- "on"); +- if (ret) { +- gf_msg (this->name, GF_LOG_ERROR, errno, +- GD_MSG_DICT_SET_FAILED, "Failed to set " +- "option ' NFS_DISABLE_MAP_KEY ' on " +- "volume %s", volinfo->volname); +- goto out; +- } + ret = dict_get_str (volinfo->dict, "transport.address-family", + &address_family_str); + if (ret) { +-- +1.8.3.1 + diff --git a/SOURCES/0026-mgmt-glusterd-Enable-client-io-threads-by-default.patch b/SOURCES/0026-mgmt-glusterd-Enable-client-io-threads-by-default.patch deleted file mode 100644 index df1751a..0000000 --- a/SOURCES/0026-mgmt-glusterd-Enable-client-io-threads-by-default.patch +++ /dev/null @@ -1,41 +0,0 @@ -From d872c76e0602dd629698c168ff26623f2e539107 Mon Sep 17 00:00:00 2001 -From: Pranith Kumar K -Date: Fri, 29 Jul 2016 21:55:58 +0530 -Subject: [PATCH 26/86] mgmt/glusterd: Enable client-io-threads by default - -Details of upstream patch: ->> Change-Id: Ic013a772ffc3f8c93673bbee064ff4cc372fe128 ->> Signed-off-by: Pranith Kumar K ->> Reviewed-on: http://review.gluster.org/15051 ->> NetBSD-regression: NetBSD Build System ->> CentOS-regression: Gluster Build System ->> Smoke: Gluster Build System ->> Reviewed-by: Prashanth Pai ->> Reviewed-by: Atin Mukherjee - -BUG: 1359180 -Change-Id: I0cf90b21f340a08ddcdc2c38e8e0fe5dbeaa24a2 -Signed-off-by: Ravishankar N -Reviewed-on: https://code.engineering.redhat.com/gerrit/84684 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - xlators/mgmt/glusterd/src/glusterd-volume-set.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c -index 1f59e36..a93c8d4 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c -+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c -@@ -1900,7 +1900,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { - { .key = "performance.client-io-threads", - .voltype = "performance/io-threads", - .option = "!perf", -- .value = "off", -+ .value = "on", - .op_version = 1, - .description = "enable/disable io-threads translator in the client " - "graph of volume.", --- -1.7.1 - diff --git a/SOURCES/0027-feature-bitrot-Ondemand-scrub-option-for-bitrot.patch b/SOURCES/0027-feature-bitrot-Ondemand-scrub-option-for-bitrot.patch deleted file mode 100644 index 639b009..0000000 --- a/SOURCES/0027-feature-bitrot-Ondemand-scrub-option-for-bitrot.patch +++ /dev/null @@ -1,677 +0,0 @@ -From 922a57492cd16e6c2a1105b91ff3c53f50dfde09 Mon Sep 17 00:00:00 2001 -From: Kotresh HR -Date: Fri, 5 Aug 2016 09:03:22 +0530 -Subject: [PATCH 27/86] feature/bitrot: Ondemand scrub option for bitrot - -The bitrot scrubber takes 'hourly/daily/biweekly/monthly' -as the values for 'scrub-frequency'. There is no way -to schedule the scrubbing when the admin wants it. - -Ondemand scrubbing brings in the new option 'ondemand' -with which the admin can start scrubbing ondemand. -It starts the scrubbing immediately. - -Ondemand scrubbing is successful only if the scrubber -is in 'Active (Idle)' (waiting for it's next frequency -cycle to start scrubbing). It is not entertained when -the scrubber is in 'Paused' or already running. - -Here is the command line syntax. - -gluster volume bitrot scrub ondemand - ->Change-Id: I84c28904367eed827a7dae8d6a535c14b28e9f4d ->BUG: 1366195 ->Signed-off-by: Kotresh HR ->Reviewed-on: http://review.gluster.org/15111 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Venky Shankar - -Change-Id: I84c28904367eed827a7dae8d6a535c14b28e9f4d -BUG: 1359588 -Signed-off-by: Kotresh HR -Reviewed-on: https://code.engineering.redhat.com/gerrit/84665 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - cli/src/cli-cmd-parser.c | 5 ++- - cli/src/cli-cmd-volume.c | 2 +- - doc/gluster.8 | 6 +-- - glusterfsd/src/glusterfsd-messages.h | 4 +- - glusterfsd/src/glusterfsd-mgmt.c | 24 +++++++++- - libglusterfs/src/globals.h | 4 +- - rpc/xdr/src/cli1-xdr.x | 1 + - rpc/xdr/src/glusterfs-fops.x | 1 + - tests/bitrot/bug-1207627-bitrot-scrub-status.t | 20 +++++++- - tests/volume.rc | 6 +++ - xlators/features/bit-rot/src/bitd/bit-rot-scrub.c | 50 ++++++++++++++++++++- - xlators/features/bit-rot/src/bitd/bit-rot-scrub.h | 1 + - xlators/features/bit-rot/src/bitd/bit-rot-ssm.c | 25 +++++++--- - xlators/features/bit-rot/src/bitd/bit-rot-ssm.h | 3 +- - xlators/features/bit-rot/src/bitd/bit-rot.c | 29 +++++++++++- - xlators/features/bit-rot/src/bitd/bit-rot.h | 2 +- - xlators/mgmt/glusterd/src/glusterd-bitrot.c | 29 ++++++++++++ - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 16 +++++-- - xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 1 + - xlators/mgmt/glusterd/src/glusterd-syncop.c | 4 ++ - xlators/mgmt/glusterd/src/glusterd.h | 1 + - 21 files changed, 205 insertions(+), 29 deletions(-) - -diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c -index 692bd26..b20cea6 100644 ---- a/cli/src/cli-cmd-parser.c -+++ b/cli/src/cli-cmd-parser.c -@@ -5188,7 +5188,8 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options) - "biweekly", "monthly", - "minute", NULL}; - char *scrub_values[] = {"pause", "resume", -- "status", NULL}; -+ "status", "ondemand", -+ NULL}; - dict_t *dict = NULL; - gf_bitrot_type type = GF_BITROT_OPTION_TYPE_NONE; - int32_t expiry_time = 0; -@@ -5320,6 +5321,8 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options) - } else { - if (strcmp (words[4], "status") == 0) { - type = GF_BITROT_CMD_SCRUB_STATUS; -+ } else if (strcmp (words[4], "ondemand") == 0) { -+ type = GF_BITROT_CMD_SCRUB_ONDEMAND; - } else { - type = GF_BITROT_OPTION_TYPE_SCRUB; - } -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index c721171..129d9b9 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -2703,7 +2703,7 @@ struct cli_cmd volume_cmds[] = { - "volume bitrot scrub-throttle {lazy|normal|aggressive} |\n" - "volume bitrot scrub-frequency {hourly|daily|weekly|biweekly" - "|monthly} |\n" -- "volume bitrot scrub {pause|resume|status}", -+ "volume bitrot scrub {pause|resume|status|ondemand}", - cli_cmd_bitrot_cbk, - "Bitrot translator specific operation. For more information about " - "bitrot command type 'man gluster'" -diff --git a/doc/gluster.8 b/doc/gluster.8 -index 9780264..89bf5c3 100644 ---- a/doc/gluster.8 -+++ b/doc/gluster.8 -@@ -162,11 +162,9 @@ Scrub-throttle value is a measure of how fast or slow the scrubber scrubs the fi - \fB\ volume bitrot scrub-frequency {daily|weekly|biweekly|monthly} \fR - Scrub frequency for volume - .TP --\fB\ volume bitrot scrub {pause|resume} \fR --Pause/Resume scrub. Upon resume, scrubber continues where it left off. -+\fB\ volume bitrot scrub {pause|resume|status|ondemand} \fR -+Pause/Resume scrub. Upon resume, scrubber continues where it left off. status option shows the statistics of scrubber. ondemand option starts the scrubbing immediately if the scrubber is not paused or already running. - .TP --\fB\ volume bitrot scrub status \fR --Show the statistics of scrubber status - .SS "Snapshot Commands" - .PP - .TP -diff --git a/glusterfsd/src/glusterfsd-messages.h b/glusterfsd/src/glusterfsd-messages.h -index caa9995..e9c28f7 100644 ---- a/glusterfsd/src/glusterfsd-messages.h -+++ b/glusterfsd/src/glusterfsd-messages.h -@@ -36,7 +36,7 @@ - */ - - #define GLFS_COMP_BASE GLFS_MSGID_COMP_GLUSTERFSD --#define GLFS_NUM_MESSAGES 36 -+#define GLFS_NUM_MESSAGES 37 - #define GLFS_MSGID_END (GLFS_COMP_BASE + GLFS_NUM_MESSAGES + 1) - /* Messaged with message IDs */ - #define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages" -@@ -108,6 +108,8 @@ - " unserialization failed." - #define glusterfsd_msg_36 (GLFS_COMP_BASE + 36), "problem in xlator " \ - " loading." -+#define glusterfsd_msg_37 (GLFS_COMP_BASE + 37), "failed to get dict value" -+ - /*------------*/ - #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" - -diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c -index 61309f9..e257659 100644 ---- a/glusterfsd/src/glusterfsd-mgmt.c -+++ b/glusterfsd/src/glusterfsd-mgmt.c -@@ -660,6 +660,7 @@ glusterfs_handle_bitrot (rpcsvc_request_t *req) - char xname[1024] = {0,}; - glusterfs_ctx_t *ctx = NULL; - glusterfs_graph_t *active = NULL; -+ char *scrub_opt = NULL; - - GF_ASSERT (req); - this = THIS; -@@ -713,8 +714,27 @@ glusterfs_handle_bitrot (rpcsvc_request_t *req) - goto out; - } - -- ret = xlator->notify (xlator, GF_EVENT_SCRUB_STATUS, input, -- output); -+ ret = dict_get_str (input, "scrub-value", &scrub_opt); -+ if (ret) { -+ snprintf (msg, sizeof (msg), "Failed to get scrub value"); -+ gf_msg (this->name, GF_LOG_ERROR, 0, glusterfsd_msg_37); -+ ret = -1; -+ goto out; -+ } -+ -+ if (!strncmp (scrub_opt, "status", strlen ("status"))) { -+ ret = xlator->notify (xlator, GF_EVENT_SCRUB_STATUS, input, -+ output); -+ } else if (!strncmp (scrub_opt, "ondemand", strlen ("ondemand"))) { -+ ret = xlator->notify (xlator, GF_EVENT_SCRUB_ONDEMAND, input, -+ output); -+ if (ret == -2) { -+ snprintf (msg, sizeof (msg), "Scrubber is in " -+ "Pause/Inactive/Running state"); -+ ret = -1; -+ goto out; -+ } -+ } - out: - glusterfs_translator_info_response_send (req, ret, msg, output); - -diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h -index 5853e46..b4ad9b2 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_8_0 /* MAX VERSION is the maximum -+#define GD_OP_VERSION_MAX GD_OP_VERSION_3_9_0 /* MAX VERSION is the maximum - count in VME table, should - keep changing with - introduction of newer -@@ -79,6 +79,8 @@ - - #define GD_OP_VERSION_3_8_0 30800 /* Op-version for GlusterFS 3.8.0 */ - -+#define GD_OP_VERSION_3_9_0 30900 /* Op-version for GlusterFS 3.9.0 */ -+ - #include "xlator.h" - - /* THIS */ -diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x -index 66d399b..80151d4 100644 ---- a/rpc/xdr/src/cli1-xdr.x -+++ b/rpc/xdr/src/cli1-xdr.x -@@ -45,6 +45,7 @@ enum gf_bitrot_type { - GF_BITROT_OPTION_TYPE_SCRUB, - GF_BITROT_OPTION_TYPE_EXPIRY_TIME, - GF_BITROT_CMD_SCRUB_STATUS, -+ GF_BITROT_CMD_SCRUB_ONDEMAND, - GF_BITROT_OPTION_TYPE_MAX - }; - -diff --git a/rpc/xdr/src/glusterfs-fops.x b/rpc/xdr/src/glusterfs-fops.x -index 8462dcc..3b6b649 100644 ---- a/rpc/xdr/src/glusterfs-fops.x -+++ b/rpc/xdr/src/glusterfs-fops.x -@@ -84,6 +84,7 @@ enum glusterfs_event_t { - GF_EVENT_UPCALL, - GF_EVENT_SCRUB_STATUS, - GF_EVENT_SOME_CHILD_DOWN, -+ GF_EVENT_SCRUB_ONDEMAND, - GF_EVENT_MAXVAL - }; - -diff --git a/tests/bitrot/bug-1207627-bitrot-scrub-status.t b/tests/bitrot/bug-1207627-bitrot-scrub-status.t -index bca3919..a361986 100644 ---- a/tests/bitrot/bug-1207627-bitrot-scrub-status.t -+++ b/tests/bitrot/bug-1207627-bitrot-scrub-status.t -@@ -12,7 +12,7 @@ TEST glusterd; - TEST pidof glusterd; - - ## Lets create and start the volume --TEST $CLI volume create $V0 $H0:$B0/${V0}{1..2} -+TEST $CLI volume create $V0 $H0:$B0/${V0}1 - TEST $CLI volume start $V0 - - ## Enable bitrot for volume $V0 -@@ -26,11 +26,27 @@ TEST $CLI volume bitrot $V0 scrub-frequency hourly - ## Setting scrubber throttle value lazy - TEST $CLI volume bitrot $V0 scrub-throttle lazy - -- - EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'Active' scrub_status $V0 'State of scrub' - EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'lazy' scrub_status $V0 'Scrub impact' - EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'hourly' scrub_status $V0 'Scrub frequency' - EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/bitd.log' scrub_status $V0 'Bitrot error log location' - EXPECT_WITHIN $PROCESS_UP_TIMEOUT '/var/log/glusterfs/scrub.log' scrub_status $V0 'Scrubber error log location' - -+## Set expiry-timeout to 1 sec -+TEST $CLI volume set $V0 features.expiry-time 1 -+ -+##Mount $V0 -+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0 -+ -+#Create sample file -+TEST `echo "1234" > $M0/FILE1` -+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'trusted.bit-rot.signature' check_for_xattr 'trusted.bit-rot.signature' "/$B0/${V0}1/FILE1" -+ -+##Corrupt the file -+TEST `echo "corrupt" >> /$B0/${V0}1/FILE1` -+ -+## Ondemand scrub -+TEST $CLI volume bitrot $V0 scrub ondemand -+EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'trusted.bit-rot.bad-file' check_for_xattr 'trusted.bit-rot.bad-file' "/$B0/${V0}1/FILE1" -+ - cleanup; -diff --git a/tests/volume.rc b/tests/volume.rc -index 5ea75a5..989538d 100644 ---- a/tests/volume.rc -+++ b/tests/volume.rc -@@ -579,6 +579,12 @@ else - fi - } - -+function check_for_xattr { -+ local xattr=$1 -+ local filepath=$2 -+ getfattr -n $xattr $filepath 2>/dev/null | grep "$xattr" | cut -f1 -d'=' -+} -+ - function get_bitd_count { - ps auxww | grep glusterfs | grep bitd.pid | grep -v grep | wc -l - } -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -index d50f40a..601dea9 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -+++ b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -@@ -860,6 +860,7 @@ br_fsscan_calculate_delta (uint32_t times) - return times; - } - -+#define BR_SCRUB_ONDEMAND (1) - #define BR_SCRUB_MINUTE (60) - #define BR_SCRUB_HOURLY (60 * 60) - #define BR_SCRUB_DAILY (1 * 24 * 60 * 60) -@@ -1037,6 +1038,53 @@ br_fsscan_reschedule (xlator_t *this) - return 0; - } - -+int32_t -+br_fsscan_ondemand (xlator_t *this) -+{ -+ int32_t ret = 0; -+ uint32_t timo = 0; -+ char timestr[1024] = {0,}; -+ struct timeval now = {0,}; -+ br_private_t *priv = NULL; -+ struct br_scrubber *fsscrub = NULL; -+ struct br_monitor *scrub_monitor = NULL; -+ -+ priv = this->private; -+ fsscrub = &priv->fsscrub; -+ scrub_monitor = &priv->scrub_monitor; -+ -+ if (!fsscrub->frequency_reconf) -+ return 0; -+ -+ (void) gettimeofday (&now, NULL); -+ -+ timo = BR_SCRUB_ONDEMAND; -+ -+ gf_time_fmt (timestr, sizeof (timestr), -+ (now.tv_sec + timo), gf_timefmt_FT); -+ -+ pthread_mutex_lock (&scrub_monitor->donelock); -+ { -+ scrub_monitor->done = _gf_false; -+ } -+ pthread_mutex_unlock (&scrub_monitor->donelock); -+ -+ ret = gf_tw_mod_timer_pending (priv->timer_wheel, scrub_monitor->timer, -+ timo); -+ if (ret == 0) -+ gf_msg (this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, -+ "Scrubber is currently running and would be " -+ "rescheduled after completion"); -+ else { -+ _br_monitor_set_scrub_state (scrub_monitor, -+ BR_SCRUB_STATE_PENDING); -+ gf_msg (this->name, GF_LOG_INFO, 0, BRB_MSG_SCRUB_INFO, -+ "Ondemand Scrubbing scheduled to run at %s", timestr); -+ } -+ -+ return 0; -+} -+ - #define BR_SCRUB_THREAD_SCALE_LAZY 0 - #define BR_SCRUB_THREAD_SCALE_NORMAL 0.4 - #define BR_SCRUB_THREAD_SCALE_AGGRESSIVE 1.0 -@@ -1864,7 +1912,7 @@ br_monitor_thread (void *arg) - /* this needs to be serialized with reconfigure() */ - pthread_mutex_lock (&priv->lock); - { -- ret = br_scrub_state_machine (this); -+ ret = br_scrub_state_machine (this, _gf_false); - } - pthread_mutex_unlock (&priv->lock); - if (ret) { -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.h b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.h -index 6316906..8cc88ec 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.h -+++ b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.h -@@ -20,6 +20,7 @@ int32_t br_fsscan_schedule (xlator_t *); - int32_t br_fsscan_reschedule (xlator_t *); - int32_t br_fsscan_activate (xlator_t *); - int32_t br_fsscan_deactivate (xlator_t *); -+int32_t br_fsscan_ondemand (xlator_t *); - - int32_t br_scrubber_handle_options (xlator_t *, br_private_t *, dict_t *); - -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-ssm.c b/xlators/features/bit-rot/src/bitd/bit-rot-ssm.c -index d304fc8..af887a1 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot-ssm.c -+++ b/xlators/features/bit-rot/src/bitd/bit-rot-ssm.c -@@ -84,16 +84,22 @@ br_scrub_ssm_state_stall (xlator_t *this) - - static br_scrub_ssm_call * - br_scrub_ssm[BR_SCRUB_MAXSTATES][BR_SCRUB_MAXEVENTS] = { -- {br_fsscan_schedule, br_scrub_ssm_state_ipause}, /* INACTIVE */ -- {br_fsscan_reschedule, br_fsscan_deactivate}, /* PENDING */ -- {br_scrub_ssm_noop, br_scrub_ssm_state_stall}, /* ACTIVE */ -- {br_fsscan_activate, br_scrub_ssm_noop}, /* PAUSED */ -- {br_fsscan_schedule, br_scrub_ssm_noop}, /* IPAUSED */ -- {br_scrub_ssm_state_active, br_scrub_ssm_noop}, /* STALLED */ -+ /* INACTIVE */ -+ {br_fsscan_schedule, br_scrub_ssm_state_ipause, br_scrub_ssm_noop}, -+ /* PENDING */ -+ {br_fsscan_reschedule, br_fsscan_deactivate, br_fsscan_ondemand}, -+ /* ACTIVE */ -+ {br_scrub_ssm_noop, br_scrub_ssm_state_stall, br_scrub_ssm_noop}, -+ /* PAUSED */ -+ {br_fsscan_activate, br_scrub_ssm_noop, br_scrub_ssm_noop}, -+ /* IPAUSED */ -+ {br_fsscan_schedule, br_scrub_ssm_noop, br_scrub_ssm_noop}, -+ /* STALLED */ -+ {br_scrub_ssm_state_active, br_scrub_ssm_noop, br_scrub_ssm_noop}, - }; - - int32_t --br_scrub_state_machine (xlator_t *this) -+br_scrub_state_machine (xlator_t *this, gf_boolean_t scrub_ondemand) - { - br_private_t *priv = NULL; - br_scrub_ssm_call *call = NULL; -@@ -107,7 +113,10 @@ br_scrub_state_machine (xlator_t *this) - scrub_monitor = &priv->scrub_monitor; - - currstate = scrub_monitor->state; -- event = _br_child_get_scrub_event (fsscrub); -+ if (scrub_ondemand) -+ event = BR_SCRUB_EVENT_ONDEMAND; -+ else -+ event = _br_child_get_scrub_event (fsscrub); - - call = br_scrub_ssm[currstate][event]; - return call (this); -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-ssm.h b/xlators/features/bit-rot/src/bitd/bit-rot-ssm.h -index 936ee4d..8609477 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot-ssm.h -+++ b/xlators/features/bit-rot/src/bitd/bit-rot-ssm.h -@@ -26,11 +26,12 @@ typedef enum br_scrub_state { - typedef enum br_scrub_event { - BR_SCRUB_EVENT_SCHEDULE = 0, - BR_SCRUB_EVENT_PAUSE, -+ BR_SCRUB_EVENT_ONDEMAND, - BR_SCRUB_MAXEVENTS, - } br_scrub_event_t; - - struct br_monitor; - --int32_t br_scrub_state_machine (xlator_t *); -+int32_t br_scrub_state_machine (xlator_t *, gf_boolean_t); - - #endif /* __BIT_ROT_SSM_H__ */ -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c -index 174af2b..ab32925 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot.c -+++ b/xlators/features/bit-rot/src/bitd/bit-rot.c -@@ -1534,7 +1534,6 @@ _br_qchild_event (xlator_t *this, br_child_t *child, br_child_handler *call) - int - br_scrubber_status_get (xlator_t *this, dict_t **dict) - { -- - int ret = -1; - br_private_t *priv = NULL; - struct br_scrub_stats *scrub_stats = NULL; -@@ -1600,9 +1599,11 @@ notify (xlator_t *this, int32_t event, void *data, ...) - br_private_t *priv = NULL; - dict_t *output = NULL; - va_list ap; -+ struct br_monitor *scrub_monitor = NULL; - - subvol = (xlator_t *)data; - priv = this->private; -+ scrub_monitor = &priv->scrub_monitor; - - gf_msg_trace (this->name, 0, "Notification received: %d", event); - -@@ -1676,6 +1677,30 @@ notify (xlator_t *this, int32_t event, void *data, ...) - ret = br_scrubber_status_get (this, &output); - gf_msg_debug (this->name, 0, "returning %d", ret); - break; -+ -+ case GF_EVENT_SCRUB_ONDEMAND: -+ gf_log (this->name, GF_LOG_INFO, "BitRot scrub ondemand " -+ "called"); -+ -+ if (scrub_monitor->state != BR_SCRUB_STATE_PENDING) -+ return -2; -+ -+ /* Needs synchronization with reconfigure thread */ -+ pthread_mutex_lock (&priv->lock); -+ { -+ ret = br_scrub_state_machine (this, _gf_true); -+ } -+ pthread_mutex_unlock (&priv->lock); -+ -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ BRB_MSG_RESCHEDULE_SCRUBBER_FAILED, -+ "Could not schedule ondemand scrubbing. " -+ "Scrubbing will continue according to " -+ "old frequency."); -+ } -+ gf_msg_debug (this->name, 0, "returning %d", ret); -+ break; - default: - default_notify (this, event, data); - } -@@ -2027,7 +2052,7 @@ br_reconfigure_monitor (xlator_t *this) - { - int32_t ret = 0; - -- ret = br_scrub_state_machine (this); -+ ret = br_scrub_state_machine (this, _gf_false); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - BRB_MSG_RESCHEDULE_SCRUBBER_FAILED, -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.h b/xlators/features/bit-rot/src/bitd/bit-rot.h -index 8e92670..a729f81 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot.h -+++ b/xlators/features/bit-rot/src/bitd/bit-rot.h -@@ -297,7 +297,7 @@ static inline br_scrub_event_t - _br_child_get_scrub_event (struct br_scrubber *fsscrub) - { - return (fsscrub->frequency == BR_FSSCRUB_FREQ_STALLED) -- ? BR_SCRUB_EVENT_PAUSE : BR_SCRUB_EVENT_SCHEDULE; -+ ? BR_SCRUB_EVENT_PAUSE : BR_SCRUB_EVENT_SCHEDULE; - } - - int32_t -diff --git a/xlators/mgmt/glusterd/src/glusterd-bitrot.c b/xlators/mgmt/glusterd/src/glusterd-bitrot.c -index 6e91106..8c5ddfd 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-bitrot.c -+++ b/xlators/mgmt/glusterd/src/glusterd-bitrot.c -@@ -138,6 +138,34 @@ __glusterd_handle_bitrot (rpcsvc_request_t *req) - } - } - -+ if (type == GF_BITROT_CMD_SCRUB_ONDEMAND) { -+ /* Backward compatibility handling for scrub status command*/ -+ if (conf->op_version < GD_OP_VERSION_3_9_0) { -+ snprintf (msg, sizeof (msg), "Cannot execute command. " -+ "The cluster is operating at version %d. " -+ "Bitrot scrub ondemand command unavailable in " -+ "this version", conf->op_version); -+ ret = -1; -+ goto out; -+ } -+ -+ ret = dict_get_str (dict, "scrub-value", &scrub); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, -+ "Failed to get scrub value."); -+ ret = -1; -+ goto out; -+ } -+ -+ if (!strncmp (scrub, "ondemand", strlen ("ondemand"))) { -+ ret = glusterd_op_begin_synctask (req, -+ GD_OP_SCRUB_ONDEMAND, -+ dict); -+ goto out; -+ } -+ } -+ - ret = glusterd_op_begin_synctask (req, GD_OP_BITROT, dict); - - out: -@@ -572,6 +600,7 @@ glusterd_op_bitrot (dict_t *dict, char **op_errstr, dict_t *rsp_dict) - if (ret) - goto out; - case GF_BITROT_CMD_SCRUB_STATUS: -+ case GF_BITROT_CMD_SCRUB_ONDEMAND: - break; - - default: -diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index 9194077..409a205 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c -+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -714,6 +714,7 @@ glusterd_node_op_build_payload (glusterd_op_t op, gd1_mgmt_brick_op_req **req, - break; - - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - brick_req = GF_CALLOC (1, sizeof(*brick_req), - gf_gld_mt_mop_brick_req_t); - if (!brick_req) -@@ -4113,6 +4114,7 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx) - case GD_OP_BARRIER: - case GD_OP_BITROT: - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - { - do_common = _gf_true; - } -@@ -4707,6 +4709,7 @@ glusterd_op_modify_op_ctx (glusterd_op_t op, void *ctx) - */ - case GD_OP_DEFRAG_BRICK_VOLUME: - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - ret = dict_get_int32 (op_ctx, "count", &count); - if (ret) { - gf_msg_debug (this->name, 0, -@@ -4754,10 +4757,11 @@ glusterd_op_modify_op_ctx (glusterd_op_t op, void *ctx) - GD_MSG_CONVERSION_FAILED, - "Failed uuid to hostname conversion"); - -- /* Since Both rebalance and bitrot scrub status are going to -- * use same code path till here, we should break in case -- * of scrub status */ -- if (op == GD_OP_SCRUB_STATUS) { -+ /* Since Both rebalance and bitrot scrub status/ondemand -+ * are going to use same code path till here, we should -+ * break in case of scrub status. -+ */ -+ if (op == GD_OP_SCRUB_STATUS || op == GD_OP_SCRUB_ONDEMAND) { - break; - } - -@@ -5424,6 +5428,7 @@ glusterd_need_brick_op (glusterd_op_t op) - case GD_OP_DEFRAG_BRICK_VOLUME: - case GD_OP_HEAL_VOLUME: - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - ret = _gf_true; - break; - default: -@@ -5695,6 +5700,7 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr, - - case GD_OP_BITROT: - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - ret = glusterd_op_stage_bitrot (dict, op_errstr, - rsp_dict); - break; -@@ -5820,6 +5826,7 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr, - - case GD_OP_BITROT: - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - ret = glusterd_op_bitrot (dict, op_errstr, rsp_dict); - break; - -@@ -7270,6 +7277,7 @@ glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr, - ret = glusterd_bricks_select_snap (dict, op_errstr, selected); - break; - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - ret = glusterd_bricks_select_scrub (dict, op_errstr, selected); - break; - default: -diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -index d37a8f2..c87a6da 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -@@ -143,6 +143,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret, - case GD_OP_BARRIER: - case GD_OP_BITROT: - case GD_OP_SCRUB_STATUS: -+ case GD_OP_SCRUB_ONDEMAND: - { - /*nothing specific to be done*/ - break; -diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c -index a233f34..64a0aeb 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-syncop.c -+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c -@@ -309,6 +309,10 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp) - case GD_OP_SCRUB_STATUS: - ret = glusterd_volume_bitrot_scrub_use_rsp_dict (aggr, rsp); - break; -+ -+ case GD_OP_SCRUB_ONDEMAND: -+ break; -+ - default: - break; - } -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index eec1adf..3aaedbc 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -116,6 +116,7 @@ typedef enum glusterd_op_ { - GD_OP_DETACH_TIER, - GD_OP_TIER_MIGRATE, - GD_OP_SCRUB_STATUS, -+ GD_OP_SCRUB_ONDEMAND, - GD_OP_MAX, - } glusterd_op_t; - --- -1.7.1 - diff --git a/SOURCES/0027-glusterd-spawn-nfs-daemon-in-op-version-bump-if-nfs..patch b/SOURCES/0027-glusterd-spawn-nfs-daemon-in-op-version-bump-if-nfs..patch new file mode 100644 index 0000000..ae4bab5 --- /dev/null +++ b/SOURCES/0027-glusterd-spawn-nfs-daemon-in-op-version-bump-if-nfs..patch @@ -0,0 +1,132 @@ +From 52798b6934ea584b25b1ade64cb52a7439c1b113 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Tue, 3 Jan 2017 18:13:29 +0530 +Subject: [PATCH 27/74] glusterd: spawn nfs daemon in op-version bump if + nfs.disable key is absent + +3.2.0 onwards gNFS will be disabled by default. However any cluster +upgraded to 3.2.0 with existing volumes exposed over gNFS should +continue to have gNFS access and hence post upgrade gNFS service should +come up after bumping up the op-version. Although the key nfs.disable +was handled and managed correctly in the upgrade path but gNFS daemon +was never spawned in this case. + +Fix is to spawn gNFS daemon in op-version bump up code path if +nfs.disable option is not set. + +Label : DOWNSTREAM ONLY + +Change-Id: Icac6f3653160f79b271f25f5df0c89690917e702 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/94006 +Reviewed-by: Jiffin Thottan +Reviewed-by: Samikshan Bairagya +--- + xlators/mgmt/glusterd/src/glusterd-messages.h | 8 ++++++ + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 35 ++++++++++++++++++++++++--- + 2 files changed, 40 insertions(+), 3 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h +index 65d4353..8bb4c43 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-messages.h ++++ b/xlators/mgmt/glusterd/src/glusterd-messages.h +@@ -4937,6 +4937,14 @@ + */ + #define GD_MSG_GARBAGE_ARGS (GLUSTERD_COMP_BASE + 611) + ++/*! ++ * @messageid ++ * @diagnosis ++ * @recommendedaction ++ * ++ */ ++#define GD_MSG_SVC_START_FAIL (GLUSTERD_COMP_BASE + 590) ++ + /*------------*/ + + #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 0557ad8..4fc719a 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -2423,7 +2423,8 @@ out: + } + + static int +-glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo) ++glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo, ++ gf_boolean_t *start_nfs_svc) + { + int ret = -1; + xlator_t *this = NULL; +@@ -2436,6 +2437,8 @@ glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo) + conf = this->private; + GF_VALIDATE_OR_GOTO (this->name, conf, out); + ++ ret = 0; ++ + /* 3.9.0 onwards gNFS will be disabled by default. In case of an upgrade + * from anything below than 3.9.0 to 3.9.x, the value for nfs.disable is + * set to 'off' for all volumes even if it is not explicitly set in the +@@ -2458,6 +2461,12 @@ glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo) + "volume %s", volinfo->volname); + goto out; + } ++ /* If the volume is started then mark start_nfs_svc to ++ * true such that nfs daemon can be spawned up ++ */ ++ if (GLUSTERD_STATUS_STARTED == volinfo->status) ++ *start_nfs_svc = _gf_true; ++ + } + + ret = dict_get_str (volinfo->dict, "transport.address-family", +@@ -2478,9 +2487,12 @@ glusterd_update_volumes_dict (glusterd_volinfo_t *volinfo) + } + } + } ++ ret = glusterd_store_volinfo (volinfo, ++ GLUSTERD_VOLINFO_VER_AC_INCREMENT); ++ if (ret) ++ goto out; ++ + } +- ret = glusterd_store_volinfo (volinfo, +- GLUSTERD_VOLINFO_VER_AC_INCREMENT); + + out: + return ret; +@@ -2529,6 +2541,7 @@ glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict, + uint32_t op_version = 0; + glusterd_volinfo_t *volinfo = NULL; + glusterd_svc_t *svc = NULL; ++ gf_boolean_t start_nfs_svc = _gf_false; + + conf = this->private; + ret = dict_get_str (dict, "key1", &key); +@@ -2645,6 +2658,22 @@ glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict, + "Failed to store op-version."); + } + } ++ cds_list_for_each_entry (volinfo, &conf->volumes, vol_list) { ++ ret = glusterd_update_volumes_dict (volinfo, ++ &start_nfs_svc); ++ if (ret) ++ goto out; ++ } ++ if (start_nfs_svc) { ++ ret = conf->nfs_svc.manager (&(conf->nfs_svc), NULL, ++ PROC_START_NO_WAIT); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_SVC_START_FAIL, ++ "unable to start nfs service"); ++ goto out; ++ } ++ } + /* No need to save cluster.op-version in conf->opts + */ + goto out; +-- +1.8.3.1 + diff --git a/SOURCES/0028-glusterd-cli-cli-to-get-local-state-representation-f.patch b/SOURCES/0028-glusterd-cli-cli-to-get-local-state-representation-f.patch deleted file mode 100644 index d44cdf1..0000000 --- a/SOURCES/0028-glusterd-cli-cli-to-get-local-state-representation-f.patch +++ /dev/null @@ -1,1861 +0,0 @@ -From db9066b2c7a2a66e7aec334ccf834d1c95ef715b Mon Sep 17 00:00:00 2001 -From: Samikshan Bairagya -Date: Thu, 7 Jul 2016 20:33:02 +0530 -Subject: [PATCH 28/79] glusterd/cli: cli to get local state representation from glusterd - -Backport of http://review.gluster.org/14873 - -Currently there is no existing CLI that can be used to get the -local state representation of the cluster as maintained in glusterd -in a readable as well as parseable format. - -The CLI added has the following usage: - - # gluster get-state [daemon] [odir ] [file ] - -This would dump data points that reflect the local state -representation of the cluster as maintained in glusterd (no other -daemons are supported as of now) to a file inside the specified -output directory. The default output directory and filename is -/var/run/gluster and glusterd_state_ respectively. The -option for specifying the daemon name leaves room to add support for -other daemons in the future. Following are the data points captured -as of now to represent the state from the local glusterd pov: - - * Peer: - - Primary hostname - - uuid - - state - - connection status - - List of hostnames - - * Volumes: - - name, id, transport type, status - - counts: bricks, snap, subvol, stripe, arbiter, disperse, - redundancy - - snapd status - - quorum status - - tiering related information - - rebalance status - - replace bricks status - - snapshots - - * Bricks: - - Path, hostname (for all bricks these info will be shown) - - port, rdma port, status, mount options, filesystem type and -signed in status for bricks running locally. - - * Services: - - name, online status for initialised services - - * Others: - - Base port, last allocated port - - op-version - - MYUUID - -> Reviewed-on: http://review.gluster.org/14873 -> Reviewed-by: Avra Sengupta -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Atin Mukherjee - -Change-Id: I4a45cc5407ab92d8afdbbd2098ece851f7e3d618 -BUG: 1353427 -Signed-off-by: Samikshan Bairagya -Reviewed-on: https://code.engineering.redhat.com/gerrit/84660 -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-cmd-global.c | 57 +++- - cli/src/cli-cmd-parser.c | 114 +++++ - cli/src/cli-rpc-ops.c | 135 ++++-- - cli/src/cli-xml-output.c | 26 +- - cli/src/cli.h | 5 +- - doc/gluster.8 | 3 + - libglusterfs/src/Makefile.am | 17 +- - libglusterfs/src/common-utils.c | 23 + - libglusterfs/src/common-utils.h | 3 + - rpc/rpc-lib/src/protocol-common.h | 1 + - .../cli/bug-1353156-get-state-cli-validations.t | 141 ++++++ - xlators/mgmt/glusterd/src/glusterd-handler.c | 516 ++++++++++++++++++++ - xlators/mgmt/glusterd/src/glusterd-messages.h | 19 +- - xlators/mgmt/glusterd/src/glusterd-peer-utils.c | 51 ++ - xlators/mgmt/glusterd/src/glusterd-peer-utils.h | 3 + - .../mgmt/glusterd/src/glusterd-snapshot-utils.c | 36 ++ - .../mgmt/glusterd/src/glusterd-snapshot-utils.h | 2 + - xlators/mgmt/glusterd/src/glusterd-utils.c | 194 ++++++++ - xlators/mgmt/glusterd/src/glusterd-utils.h | 26 + - xlators/mgmt/glusterd/src/glusterd.h | 1 + - 21 files changed, 1321 insertions(+), 53 deletions(-) - create mode 100644 tests/bugs/cli/bug-1353156-get-state-cli-validations.t - -diff --git a/cli/src/cli-cmd-global.c b/cli/src/cli-cmd-global.c -index 53ee0ab..f4544da 100644 ---- a/cli/src/cli-cmd-global.c -+++ b/cli/src/cli-cmd-global.c -@@ -34,7 +34,9 @@ cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, - const char **words, int wordcount); - int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word, - const char **words, int wordcount); -- -+int -+cli_cmd_get_state_cbk (struct cli_state *state, struct cli_cmd_word *word, -+ const char **words, int wordcount); - - struct cli_cmd global_cmds[] = { - { "global help", -@@ -45,6 +47,10 @@ struct cli_cmd global_cmds[] = { - cli_cmd_ganesha_cbk, - "Enable/disable NFS-Ganesha support", - }, -+ { "get-state [] [odir ] [file ]", -+ cli_cmd_get_state_cbk, -+ "Get local state representation of mentioned daemon", -+ }, - {NULL, NULL, NULL} - }; - -@@ -133,3 +139,52 @@ out: - return ret; - } - -+int -+cli_cmd_get_state_cbk (struct cli_state *state, struct cli_cmd_word *word, -+ const char **words, int wordcount) -+{ -+ int sent = 0; -+ int parse_error = 0; -+ int ret = -1; -+ rpc_clnt_procedure_t *proc = NULL; -+ call_frame_t *frame = NULL; -+ dict_t *options = NULL; -+ cli_local_t *local = NULL; -+ char *op_errstr = NULL; -+ -+ frame = create_frame (THIS, THIS->ctx->pool); -+ if (!frame) -+ goto out; -+ -+ ret = cli_cmd_get_state_parse (state, words, wordcount, &options, -+ &op_errstr); -+ -+ if (ret) { -+ if (op_errstr) { -+ cli_err ("%s", op_errstr); -+ cli_usage_out (word->pattern); -+ GF_FREE (op_errstr); -+ } else -+ cli_usage_out (word->pattern); -+ -+ parse_error = 1; -+ goto out; -+ } -+ -+ CLI_LOCAL_INIT (local, words, frame, options); -+ -+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_STATE]; -+ if (proc->fn) -+ ret = proc->fn (frame, THIS, options); -+out: -+ if (ret) { -+ cli_cmd_sent_status_get (&sent); -+ if ((sent == 0) && (parse_error == 0)) -+ cli_out ("Getting daemon state failed"); -+ } -+ -+ CLI_STACK_DESTROY (frame); -+ -+ return ret; -+} -+ -diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c -index b20cea6..836a464 100644 ---- a/cli/src/cli-cmd-parser.c -+++ b/cli/src/cli-cmd-parser.c -@@ -936,6 +936,120 @@ out: - } - - int32_t -+cli_cmd_get_state_parse (struct cli_state *state, -+ const char **words, int wordcount, -+ dict_t **options, char **op_errstr) -+{ -+ dict_t *dict = NULL; -+ int ret = -1; -+ uint32_t cmd = 0; -+ char *odir = NULL; -+ char *filename = NULL; -+ char *daemon_name = NULL; -+ int count = 0; -+ -+ GF_VALIDATE_OR_GOTO ("cli", options, out); -+ GF_VALIDATE_OR_GOTO ("cli", words, out); -+ -+ dict = dict_new (); -+ if (!dict) -+ goto out; -+ -+ if (wordcount < 1 || wordcount > 6) { -+ *op_errstr = gf_strdup ("Problem parsing arguments." -+ " Check usage."); -+ goto out; -+ } -+ -+ if (wordcount >= 1) { -+ gf_asprintf (&daemon_name, "%s", "glusterd"); -+ -+ for (count = 1; count < wordcount; count++) { -+ if (strcmp (words[count], "odir") == 0 || -+ strcmp (words[count], "file") == 0) { -+ if (strcmp (words[count], "odir") == 0) { -+ if (++count < wordcount) { -+ odir = (char *) words[count]; -+ continue; -+ } else { -+ ret = -1; -+ goto out; -+ } -+ } else if (strcmp (words[count], "file") == 0) { -+ if (++count < wordcount) { -+ filename = (char *) words[count]; -+ continue; -+ } else { -+ ret = -1; -+ goto out; -+ } -+ } -+ } else { -+ if (count > 1) { -+ *op_errstr = gf_strdup ("Problem " -+ "parsing arguments. " -+ "Check usage."); -+ ret = -1; -+ goto out; -+ -+ } -+ if (strcmp (words[count], "glusterd") == 0) { -+ continue; -+ } else { -+ *op_errstr = gf_strdup ("glusterd is " -+ "the only supported daemon."); -+ ret = -1; -+ goto out; -+ } -+ } -+ } -+ -+ ret = dict_set_str (dict, "daemon", daemon_name); -+ if (ret) { -+ *op_errstr = gf_strdup ("Command failed. Please check " -+ " log file for more details."); -+ gf_log (THIS->name, GF_LOG_ERROR, -+ "Setting daemon name to dictionary failed"); -+ goto out; -+ } -+ -+ if (odir) { -+ ret = dict_set_str (dict, "odir", odir); -+ if (ret) { -+ *op_errstr = gf_strdup ("Command failed. Please" -+ " check log file for" -+ " more details."); -+ gf_log (THIS->name, GF_LOG_ERROR, -+ "Setting output directory to" -+ "dictionary failed"); -+ goto out; -+ } -+ } -+ -+ if (filename) { -+ ret = dict_set_str (dict, "filename", filename); -+ if (ret) { -+ *op_errstr = gf_strdup ("Command failed. Please" -+ " check log file for" -+ " more details."); -+ gf_log (THIS->name, GF_LOG_ERROR, -+ "Setting filename to dictionary failed"); -+ goto out; -+ } -+ } -+ } -+ -+ out: -+ if (dict) -+ *options = dict; -+ -+ if (ret && dict) -+ dict_unref (dict); -+ -+ return ret; -+} -+ -+int32_t - cli_cmd_inode_quota_parse (const char **words, int wordcount, dict_t **options) - { - dict_t *dict = NULL; -diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c -index d88ddd7..77a2e24 100644 ---- a/cli/src/cli-rpc-ops.c -+++ b/cli/src/cli-rpc-ops.c -@@ -55,17 +55,6 @@ int32_t - gf_cli_remove_brick (call_frame_t *frame, xlator_t *this, - void *data); - --char *cli_vol_type_str[] = {"Distribute", -- "Stripe", -- "Replicate", -- "Striped-Replicate", -- "Disperse", -- "Tier", -- "Distributed-Stripe", -- "Distributed-Replicate", -- "Distributed-Striped-Replicate", -- "Distributed-Disperse", -- }; - - char *cli_vol_status_str[] = {"Created", - "Started", -@@ -503,6 +492,73 @@ out: - return ret; - } - -+int -+gf_cli_get_state_cbk (struct rpc_req *req, struct iovec *iov, -+ int count, void *myframe) -+{ -+ gf_cli_rsp rsp = {0,}; -+ int ret = -1; -+ dict_t *dict = NULL; -+ char *daemon_name = NULL; -+ char *ofilepath = NULL; -+ -+ GF_VALIDATE_OR_GOTO ("cli", myframe, out); -+ -+ if (-1 == req->rpc_status) { -+ goto out; -+ } -+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp); -+ if (ret < 0) { -+ gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR, -+ "Failed to decode xdr response"); -+ goto out; -+ } -+ -+ dict = dict_new (); -+ -+ if (!dict) { -+ ret = -1; -+ goto out; -+ } -+ -+ ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict); -+ if (ret) -+ goto out; -+ -+ if (rsp.op_ret) { -+ if (strcmp (rsp.op_errstr, "")) -+ cli_err ("Failed to get daemon state: %s", rsp.op_errstr); -+ else -+ cli_err ("Failed to get daemon state. Check glusterd" -+ " log file for more details"); -+ } else { -+ ret = dict_get_str (dict, "daemon", &daemon_name); -+ if (ret) -+ gf_log ("cli", GF_LOG_ERROR, "Couldn't get daemon name"); -+ -+ ret = dict_get_str (dict, "ofilepath", &ofilepath); -+ if (ret) -+ gf_log ("cli", GF_LOG_ERROR, "Couldn't get filepath"); -+ -+ if (daemon_name && ofilepath) -+ cli_out ("%s state dumped to %s", -+ daemon_name, ofilepath); -+ } -+ -+ ret = rsp.op_ret; -+ -+out: -+ free (rsp.dict.dict_val); -+ free (rsp.op_errstr); -+ -+ if (dict) -+ dict_unref (dict); -+ -+ cli_cmd_broadcast_response (ret); -+ -+ return ret; -+} -+ - void - cli_out_options ( char *substr, char *optstr, char *valstr) - { -@@ -725,13 +781,11 @@ gf_cli_print_tier_info (dict_t *dict, int i, int brick_count) - vol_type = hot_type; - hot_dist_count = (hot_replica_count ? - hot_replica_count : 1); -- if ((hot_type != GF_CLUSTER_TYPE_TIER) && -- (hot_type > 0) && -- (hot_dist_count < hot_brick_count)) -- vol_type = hot_type + GF_CLUSTER_TYPE_MAX - 1; - -+ vol_type = get_vol_type (hot_type, hot_dist_count, hot_brick_count); - cli_out ("Hot Tier Type : %s", -- cli_vol_type_str[vol_type]); -+ vol_type_str[vol_type]); -+ - gf_cli_print_number_of_bricks (hot_type, - hot_brick_count, hot_dist_count, 0, - hot_replica_count, 0, 0, 0); -@@ -742,14 +796,11 @@ gf_cli_print_tier_info (dict_t *dict, int i, int brick_count) - goto out; - - cli_out ("Cold Tier:"); -- vol_type = cold_type; -- if ((cold_type != GF_CLUSTER_TYPE_TIER) && -- (cold_type > 0) && -- (cold_dist_count < cold_brick_count)) -- vol_type = cold_type + GF_CLUSTER_TYPE_MAX - 1; - -+ vol_type = get_vol_type (cold_type, cold_dist_count, cold_brick_count); - cli_out ("Cold Tier Type : %s", -- cli_vol_type_str[vol_type]); -+ vol_type_str[vol_type]); -+ - gf_cli_print_number_of_bricks (cold_type, - cold_brick_count, - cold_dist_count, 0, cold_replica_count, -@@ -973,15 +1024,11 @@ xml_output: - if (ret) - goto out; - -- vol_type = type; -- - // Distributed (stripe/replicate/stripe-replica) setups -- if ((type != GF_CLUSTER_TYPE_TIER) && (type > 0) && -- (dist_count < brick_count)) -- vol_type = type + GF_CLUSTER_TYPE_MAX - 1; -+ vol_type = get_vol_type (type, dist_count, brick_count); - - cli_out ("Volume Name: %s", volname); -- cli_out ("Type: %s", cli_vol_type_str[vol_type]); -+ cli_out ("Type: %s", vol_type_str[vol_type]); - cli_out ("Volume ID: %s", volume_id_str); - cli_out ("Status: %s", cli_vol_status_str[status]); - cli_out ("Snapshot Count: %d", snap_count); -@@ -4153,6 +4200,32 @@ out: - } - - int32_t -+gf_cli_get_state (call_frame_t *frame, xlator_t *this, void *data) -+{ -+ gf_cli_req req = {{0,},}; -+ int ret = 0; -+ dict_t *dict = NULL; -+ -+ char *odir = NULL; -+ -+ if (!frame || !this || !data) { -+ ret = -1; -+ goto out; -+ } -+ -+ dict = data; -+ -+ ret = cli_to_glusterd (&req, frame, gf_cli_get_state_cbk, -+ (xdrproc_t) xdr_gf_cli_req, dict, -+ GLUSTER_CLI_GET_STATE, this, cli_rpc_prog, -+ NULL); -+out: -+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); -+ -+ return ret; -+} -+ -+int32_t - gf_cli_get_next_volume (call_frame_t *frame, xlator_t *this, - void *data) - { -@@ -10922,7 +10995,6 @@ cli_to_glusterd (gf_cli_req *req, call_frame_t *frame, - - ret = cli_cmd_submit (NULL, req, frame, prog, procnum, iobref, this, - cbkfn, (xdrproc_t) xdrproc); -- - out: - return ret; - -@@ -11260,7 +11332,7 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = { - [GLUSTER_CLI_DEPROBE] = {"DEPROBE_QUERY", gf_cli_deprobe}, - [GLUSTER_CLI_LIST_FRIENDS] = {"LIST_FRIENDS", gf_cli_list_friends}, - [GLUSTER_CLI_UUID_RESET] = {"UUID_RESET", gf_cli3_1_uuid_reset}, -- [GLUSTER_CLI_UUID_GET] = {"UUID_GET", gf_cli3_1_uuid_get}, -+ [GLUSTER_CLI_UUID_GET] = {"UUID_GET", gf_cli3_1_uuid_get}, - [GLUSTER_CLI_CREATE_VOLUME] = {"CREATE_VOLUME", gf_cli_create_volume}, - [GLUSTER_CLI_DELETE_VOLUME] = {"DELETE_VOLUME", gf_cli_delete_volume}, - [GLUSTER_CLI_START_VOLUME] = {"START_VOLUME", gf_cli_start_volume}, -@@ -11301,7 +11373,8 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = { - [GLUSTER_CLI_BITROT] = {"BITROT", gf_cli_bitrot}, - [GLUSTER_CLI_ATTACH_TIER] = {"ATTACH_TIER", gf_cli_attach_tier}, - [GLUSTER_CLI_DETACH_TIER] = {"DETACH_TIER", gf_cli_detach_tier}, -- [GLUSTER_CLI_TIER] = {"TIER", gf_cli_tier} -+ [GLUSTER_CLI_TIER] = {"TIER", gf_cli_tier}, -+ [GLUSTER_CLI_GET_STATE] = {"GET_STATE", gf_cli_get_state} - }; - - struct rpc_clnt_program cli_prog = { -diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c -index dbc8aa7..34f85f2 100644 ---- a/cli/src/cli-xml-output.c -+++ b/cli/src/cli-xml-output.c -@@ -2720,9 +2720,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) - /* For Distributed-(stripe,replicate,stipe-replicate,disperse) - types - */ -- if ((type != GF_CLUSTER_TYPE_TIER) && (type > 0) && -- (dist_count < brick_count)) -- type = type + GF_CLUSTER_TYPE_MAX - 1; -+ type = get_vol_type (type, dist_count, brick_count); - - ret = xmlTextWriterWriteFormatElement (local->writer, - (xmlChar *)"type", -@@ -2732,7 +2730,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) - ret = xmlTextWriterWriteFormatElement (local->writer, - (xmlChar *)"typeStr", - "%s", -- cli_vol_type_str[type]); -+ vol_type_str[type]); - XML_RET_CHECK_AND_GOTO (ret, out); - - memset (key, 0, sizeof (key)); -@@ -2819,9 +2817,13 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) - goto out; - } - -- tier_vol_type = value[HOT_TYPE]; - hot_dist_count = (value[HOT_REPLICA_COUNT] ? - value[HOT_REPLICA_COUNT] : 1); -+ -+ tier_vol_type = get_vol_type (value[HOT_TYPE], -+ hot_dist_count, -+ value[HOT_BRICK_COUNT]); -+ - if ((value[HOT_TYPE] != GF_CLUSTER_TYPE_TIER) && - (value[HOT_TYPE] > 0) && - (hot_dist_count < value[HOT_BRICK_COUNT])) -@@ -2835,7 +2837,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) - - ret = xmlTextWriterWriteFormatElement - (local->writer, (xmlChar *)"hotBrickType", -- "%s", cli_vol_type_str[tier_vol_type]); -+ "%s", vol_type_str[tier_vol_type]); - - ret = xmlTextWriterWriteFormatElement (local->writer, - (xmlChar *)"hotreplicaCount", -@@ -2912,13 +2914,9 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) - ret = xmlTextWriterEndElement (local->writer); - XML_RET_CHECK_AND_GOTO (ret, out); - -- tier_vol_type = value[COLD_TYPE]; -- if ((value[COLD_TYPE] != GF_CLUSTER_TYPE_TIER) && -- (value[COLD_TYPE] > 0) && -- (value[COLD_DIST_COUNT] < value[COLD_BRICK_COUNT])) -- tier_vol_type = value[COLD_TYPE] + -- GF_CLUSTER_TYPE_MAX - 1; -- -+ tier_vol_type = get_vol_type (value[COLD_TYPE], -+ value[COLD_DIST_COUNT], -+ value[COLD_BRICK_COUNT]); - - ret = xmlTextWriterStartElement (local->writer, - (xmlChar *) -@@ -2927,7 +2925,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) - - ret = xmlTextWriterWriteFormatElement - (local->writer, (xmlChar *)"coldBrickType", -- "%s", cli_vol_type_str[tier_vol_type]); -+ "%s", vol_type_str[tier_vol_type]); - - ret = xmlTextWriterWriteFormatElement (local->writer, - (xmlChar *)"coldreplicaCount", -diff --git a/cli/src/cli.h b/cli/src/cli.h -index 73fb672..f9c642e 100644 ---- a/cli/src/cli.h -+++ b/cli/src/cli.h -@@ -71,7 +71,6 @@ struct cli_cmd_word; - struct cli_cmd_tree; - struct cli_cmd; - --extern char *cli_vol_type_str[]; - extern char *cli_vol_status_str[]; - extern char *cli_vol_task_status_str[]; - -@@ -261,6 +260,10 @@ cli_cmd_ganesha_parse (struct cli_state *state, const char **words, - int wordcount, dict_t **options, char **op_errstr); - - int32_t -+cli_cmd_get_state_parse (struct cli_state *state, const char **words, -+ int wordcount, dict_t **options, char **op_errstr); -+ -+int32_t - cli_cmd_volume_add_brick_parse (const char **words, int wordcount, - dict_t **options, int *type); - -diff --git a/doc/gluster.8 b/doc/gluster.8 -index 89bf5c3..c9a9d50 100644 ---- a/doc/gluster.8 -+++ b/doc/gluster.8 -@@ -269,6 +269,9 @@ Selects as the source for all the files that are in split-b - Selects the split-brained present in as source and completes heal. - .SS "Other Commands" - .TP -+\fB\ get-state [] [odir ] [file ] \fR -+Get local state representation of mentioned daemon and store data in provided path information -+.TP - \fB\ help \fR - Display the command options. - .TP -diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am -index 2a4f764..89c7fa0 100644 ---- a/libglusterfs/src/Makefile.am -+++ b/libglusterfs/src/Makefile.am -@@ -6,9 +6,10 @@ libglusterfs_la_CFLAGS = $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \ - libglusterfs_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \ - -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \ - -DXLATORPARENTDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)\" \ -- -I$(top_srcdir)/rpc/rpc-lib/src/ -I$(CONTRIBDIR)/rbtree \ -- -I$(CONTRIBDIR)/libexecinfo ${ARGP_STANDALONE_CPPFLAGS} \ -- -DSBIN_DIR=\"$(sbindir)\" -I$(CONTRIBDIR)/timer-wheel -+ -I$(top_srcdir)/rpc/xdr/src/ -I$(top_srcdir)/rpc/rpc-lib/src/ \ -+ -I$(CONTRIBDIR)/rbtree -I$(CONTRIBDIR)/libexecinfo \ -+ ${ARGP_STANDALONE_CPPFLAGS} -DSBIN_DIR=\"$(sbindir)\" \ -+ -I$(CONTRIBDIR)/timer-wheel - - libglusterfs_la_LIBADD = @LEXLIB@ $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS) - libglusterfs_la_LDFLAGS = -version-info $(LIBGLUSTERFS_LT_VERSION) -@@ -35,9 +36,9 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \ - compound-fop-utils.c - - nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c defaults.c --nodist_libglusterfs_la_HEADERS = y.tab.h glusterfs-fops.h -+nodist_libglusterfs_la_HEADERS = y.tab.h glusterfs-fops.h cli1-xdr.h - --BUILT_SOURCES = graph.lex.c defaults.c glusterfs-fops.h -+BUILT_SOURCES = graph.lex.c defaults.c glusterfs-fops.h cli1-xdr.h - - libglusterfs_la_HEADERS = common-utils.h defaults.h default-args.h \ - dict.h glusterfs.h hashfn.h timespec.h logging.h xlator.h \ -@@ -91,6 +92,12 @@ $(top_srcdir)/rpc/xdr/src/glusterfs-fops.h: $(top_srcdir)/rpc/xdr/src/glusterfs- - glusterfs-fops.h: $(top_srcdir)/rpc/xdr/src/glusterfs-fops.h - cp $(top_srcdir)/rpc/xdr/src/glusterfs-fops.h . - -+$(top_srcdir)/rpc/xdr/src/cli1-xdr.h: $(top_srcdir)/rpc/xdr/src/cli1-xdr.x -+ $(MAKE) -C $(top_builddir)/rpc/xdr/src/ `basename $@` -+ -+cli1-xdr.h: $(top_srcdir)/rpc/xdr/src/cli1-xdr.h -+ cp $(top_srcdir)/rpc/xdr/src/cli1-xdr.h . -+ - CLEANFILES = $(nodist_libglusterfs_la_SOURCES) $(nodist_libglusterfs_la_HEADERS) - - if UNITTEST -diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c -index 9583352..e51933d 100644 ---- a/libglusterfs/src/common-utils.c -+++ b/libglusterfs/src/common-utils.c -@@ -45,6 +45,7 @@ - #include "globals.h" - #include "lkowner.h" - #include "syscall.h" -+#include "cli1-xdr.h" - #include - #include "libglusterfs-messages.h" - -@@ -52,6 +53,18 @@ - #define AI_ADDRCONFIG 0 - #endif /* AI_ADDRCONFIG */ - -+char *vol_type_str[] = {"Distribute", -+ "Stripe", -+ "Replicate", -+ "Striped-Replicate", -+ "Disperse", -+ "Tier", -+ "Distributed-Stripe", -+ "Distributed-Replicate", -+ "Distributed-Striped-Replicate", -+ "Distributed-Disperse", -+ }; -+ - 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); - -@@ -2722,6 +2735,16 @@ out: - } - - int -+get_vol_type (int type, int dist_count, int brick_count) -+{ -+ if ((type != GF_CLUSTER_TYPE_TIER) && (type > 0) && -+ (dist_count < brick_count)) -+ type = type + GF_CLUSTER_TYPE_MAX - 1; -+ -+ return type; -+} -+ -+int - validate_brick_name (char *brick) - { - char *delimiter = NULL; -diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h -index 2930fea..d71c143 100644 ---- a/libglusterfs/src/common-utils.h -+++ b/libglusterfs/src/common-utils.h -@@ -207,6 +207,8 @@ struct list_node { - struct list_head list; - }; - -+extern char *vol_type_str[]; -+ - struct list_node *list_node_add (void *ptr, struct list_head *list); - struct list_node *list_node_add_order (void *ptr, struct list_head *list, - int (*compare)(struct list_head *, -@@ -757,6 +759,7 @@ void gf_array_insertionsort (void *a, int l, int r, size_t elem_size, - int gf_is_str_int (const char *value); - - char *gf_uint64_2human_readable (uint64_t); -+int get_vol_type (int type, int dist_count, int brick_count); - int validate_brick_name (char *brick); - char *get_host_name (char *word, char **host); - char *get_path_name (char *word, char **path); -diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h -index 915d358..c1a488e 100644 ---- a/rpc/rpc-lib/src/protocol-common.h -+++ b/rpc/rpc-lib/src/protocol-common.h -@@ -192,6 +192,7 @@ enum gluster_cli_procnum { - GLUSTER_CLI_ATTACH_TIER, - GLUSTER_CLI_DETACH_TIER, - GLUSTER_CLI_TIER, -+ GLUSTER_CLI_GET_STATE, - GLUSTER_CLI_MAXVALUE, - }; - -diff --git a/tests/bugs/cli/bug-1353156-get-state-cli-validations.t b/tests/bugs/cli/bug-1353156-get-state-cli-validations.t -new file mode 100644 -index 0000000..9dc1f07 ---- /dev/null -+++ b/tests/bugs/cli/bug-1353156-get-state-cli-validations.t -@@ -0,0 +1,141 @@ -+#!/bin/bash -+ -+. $(dirname $0)/../../include.rc -+. $(dirname $0)/../../volume.rc -+. $(dirname $0)/../../fileio.rc -+. $(dirname $0)/../../snapshot.rc -+ -+cleanup; -+ -+ODIR="/var/tmp/gdstates/" -+NOEXDIR="/var/tmp/gdstatesfoo/" -+ -+function get_daemon_not_supported_part { -+ echo $1 -+} -+ -+function get_usage_part { -+ echo $7 -+} -+ -+function get_directory_doesnt_exist_part { -+ echo $1 -+} -+ -+function get_parsing_arguments_part { -+ echo $1 -+} -+ -+TEST glusterd -+TEST pidof glusterd -+TEST mkdir $ODIR -+ -+TEST $CLI volume create $V0 disperse $H0:$B0/b1 $H0:$B0/b2 $H0:$B0/b3 -+TEST $CLI volume start $V0 -+TEST $CLI volume tier $V0 attach replica 2 $H0:$B1/b4 $H0:$B1/b5 -+ -+TEST setup_lvm 1 -+TEST $CLI volume create $V1 $H0:$L1; -+TEST $CLI volume start $V1 -+ -+TEST $CLI snapshot create ${V1}_snap $V1 -+ -+OPATH=$(echo `$CLI get-state` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+OPATH=$(echo `$CLI get-state glusterd` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+TEST ! $CLI get-state glusterfsd; -+ERRSTR=$($CLI get-state glusterfsd 2>&1 >/dev/null); -+EXPECT 'glusterd' get_daemon_not_supported_part $ERRSTR; -+EXPECT 'Usage:' get_usage_part $ERRSTR; -+ -+OPATH=$(echo `$CLI get-state file gdstate` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+OPATH=$(echo `$CLI get-state glusterd file gdstate` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+TEST ! $CLI get-state glusterfsd file gdstate; -+ERRSTR=$($CLI get-state glusterfsd file gdstate 2>&1 >/dev/null); -+EXPECT 'glusterd' get_daemon_not_supported_part $ERRSTR; -+EXPECT 'Usage:' get_usage_part $ERRSTR; -+ -+OPATH=$(echo `$CLI get-state odir $ODIR` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+OPATH=$(echo `$CLI get-state glusterd odir $ODIR` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+OPATH=$(echo `$CLI get-state odir $ODIR file gdstate` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+OPATH=$(echo `$CLI get-state glusterd odir $ODIR file gdstate` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+OPATH=$(echo `$CLI get-state glusterd odir $ODIR file gdstate` | awk '{print $5}' | tr -d '\n') -+TEST fd=`fd_available` -+TEST fd_open $fd "r" $OPATH; -+TEST fd_close $fd; -+rm $OPATH -+ -+TEST ! $CLI get-state glusterfsd odir $ODIR; -+ERRSTR=$($CLI get-state glusterfsd odir $ODIR 2>&1 >/dev/null); -+EXPECT 'glusterd' get_daemon_not_supported_part $ERRSTR; -+EXPECT 'Usage:' get_usage_part $ERRSTR; -+ -+TEST ! $CLI get-state glusterfsd odir $ODIR file gdstate; -+ERRSTR=$($CLI get-state glusterfsd odir $ODIR file gdstate 2>&1 >/dev/null); -+EXPECT 'glusterd' get_daemon_not_supported_part $ERRSTR; -+EXPECT 'Usage:' get_usage_part $ERRSTR; -+ -+TEST ! $CLI get-state glusterfsd odir $NOEXDIR file gdstate; -+ERRSTR=$($CLI get-state glusterfsd odir $NOEXDIR file gdstate 2>&1 >/dev/null); -+EXPECT 'glusterd' get_daemon_not_supported_part $ERRSTR; -+EXPECT 'Usage:' get_usage_part $ERRSTR; -+ -+TEST ! $CLI get-state odir $NOEXDIR; -+ERRSTR=$($CLI get-state odir $NOEXDIR 2>&1 >/dev/null); -+EXPECT 'Failed' get_directory_doesnt_exist_part $ERRSTR; -+ -+TEST ! $CLI get-state odir $NOEXDIR file gdstate; -+ERRSTR=$($CLI get-state odir $NOEXDIR 2>&1 >/dev/null); -+EXPECT 'Failed' get_directory_doesnt_exist_part $ERRSTR; -+ -+TEST ! $CLI get-state foo bar; -+ERRSTR=$($CLI get-state foo bar 2>&1 >/dev/null); -+EXPECT 'glusterd' get_daemon_not_supported_part $ERRSTR; -+EXPECT 'Usage:' get_usage_part $ERRSTR; -+ -+TEST ! $CLI get-state glusterd foo bar; -+ERRSTR=$($CLI get-state glusterd foo bar 2>&1 >/dev/null); -+EXPECT 'Problem' get_parsing_arguments_part $ERRSTR; -+ -+rm -Rf $ODIR -+cleanup; -+ -diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c -index 8ca9d2a..7009231 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-handler.c -+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c -@@ -4936,6 +4936,521 @@ glusterd_handle_get_vol_opt (rpcsvc_request_t *req) - { - return glusterd_big_locked_handler (req, __glusterd_handle_get_vol_opt); - } -+ -+static int -+glusterd_print_global_options (dict_t *opts, char *key, data_t *val, void *data) -+{ -+ FILE *fp = NULL; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, key, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, val, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, data, out); -+ -+ fp = (FILE *) data; -+ fprintf (fp, "%s: %s\n", key, val->data); -+out: -+ return 0; -+} -+ -+static int -+glusterd_print_snapinfo_by_vol (FILE *fp, glusterd_volinfo_t *volinfo, int volcount) -+{ -+ int ret = -1; -+ glusterd_volinfo_t *snap_vol = NULL; -+ glusterd_volinfo_t *tmp_vol = NULL; -+ glusterd_snap_t *snapinfo = NULL; -+ int snapcount = 0; -+ char timestr[64] = {0,}; -+ char snap_status_str[STATUS_STRLEN] = {0,}; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, fp, out); -+ -+ cds_list_for_each_entry_safe (snap_vol, tmp_vol, &volinfo->snap_volumes, -+ snapvol_list) { -+ snapcount++; -+ snapinfo = snap_vol->snapshot; -+ -+ ret = glusterd_get_snap_status_str (snapinfo, snap_status_str); -+ if (ret) { -+ gf_msg (THIS->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get status for snapshot: %s", -+ snapinfo->snapname); -+ -+ goto out; -+ } -+ gf_time_fmt (timestr, sizeof timestr, snapinfo->time_stamp, -+ gf_timefmt_FT); -+ -+ fprintf (fp, "Volume%d.snapshot%d.name: %s\n", -+ volcount, snapcount, snapinfo->snapname); -+ fprintf (fp, "Volume%d.snapshot%d.id: %s\n", volcount, snapcount, -+ gf_strdup (uuid_utoa (snapinfo->snap_id))); -+ fprintf (fp, "Volume%d.snapshot%d.time: %s\n", -+ volcount, snapcount, timestr); -+ -+ if (snapinfo->description) -+ fprintf (fp, "Volume%d.snapshot%d.description: %s\n", -+ volcount, snapcount, snapinfo->description); -+ fprintf (fp, "Volume%d.snapshot%d.status: %s\n", -+ volcount, snapcount, snap_status_str); -+ } -+ -+ ret = 0; -+out: -+ return ret; -+} -+ -+static int -+glusterd_get_state (rpcsvc_request_t *req, dict_t *dict) -+{ -+ int32_t ret = -1; -+ gf_cli_rsp rsp = {0,}; -+ int fd = -1; -+ FILE *fp = NULL; -+ DIR *dp = NULL; -+ char err_str[2048] = {0,}; -+ glusterd_conf_t *priv = NULL; -+ glusterd_peerinfo_t *peerinfo = NULL; -+ glusterd_peer_hostname_t *peer_hostname_info = NULL; -+ glusterd_volinfo_t *volinfo = NULL; -+ glusterd_brickinfo_t *brickinfo = NULL; -+ glusterd_snap_t *snapinfo = NULL; -+ xlator_t *this = NULL; -+ char *odir = NULL; -+ char *filename = NULL; -+ char *ofilepath = NULL; -+ int count = 0; -+ int count_bkp = 0; -+ int odirlen = 0; -+ time_t now = 0; -+ char timestamp[16] = {0,}; -+ -+ char *vol_type_str = NULL; -+ char *hot_tier_type_str = NULL; -+ char *cold_tier_type_str = NULL; -+ -+ char transport_type_str[STATUS_STRLEN] = {0,}; -+ char quorum_status_str[STATUS_STRLEN] = {0,}; -+ char rebal_status_str[STATUS_STRLEN] = {0,}; -+ char peer_state_str[STATUS_STRLEN] = {0,}; -+ char vol_status_str[STATUS_STRLEN] = {0,}; -+ -+ this = THIS; -+ GF_VALIDATE_OR_GOTO (THIS->name, this, out); -+ -+ priv = THIS->private; -+ GF_VALIDATE_OR_GOTO (this->name, priv, out); -+ -+ GF_VALIDATE_OR_GOTO (this->name, dict, out); -+ -+ ret = dict_get_str (dict, "odir", &odir); -+ if (ret) { -+ gf_asprintf (&odir, "%s", "/var/run/gluster/"); -+ gf_msg (this->name, GF_LOG_INFO, 0, -+ GD_MSG_DICT_GET_FAILED, -+ "Default output directory: %s", odir); -+ } -+ -+ dp = sys_opendir (odir); -+ if (dp) { -+ sys_closedir (dp); -+ } else { -+ if (errno == ENOENT) { -+ snprintf (err_str, sizeof (err_str), -+ "Output directory %s does not exist.", odir); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "%s", err_str); -+ } else if (errno == ENOTDIR) { -+ snprintf (err_str, sizeof (err_str), "Output directory " -+ "does not exist. %s points to a file.", odir); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "%s", err_str); -+ } -+ -+ ret = -1; -+ goto out; -+ } -+ -+ ret = dict_get_str (dict, "filename", &filename); -+ if (ret) { -+ now = time (NULL); -+ strftime (timestamp, sizeof (timestamp), -+ "%Y%m%d_%H%M%S", localtime (&now)); -+ gf_asprintf (&filename, "%s_%s", "glusterd_state", timestamp); -+ -+ gf_msg (this->name, GF_LOG_INFO, 0, -+ GD_MSG_DICT_GET_FAILED, -+ "Default filename: %s", filename); -+ } -+ -+ odirlen = strlen (odir); -+ if (odir[odirlen-1] != '/') -+ strcat (odir, "/"); -+ -+ gf_asprintf (&ofilepath, "%s%s", odir, filename); -+ -+ ret = dict_set_str (dict, "ofilepath", ofilepath); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_SET_FAILED, "Unable to set output path"); -+ goto out; -+ } -+ -+ fp = fopen (ofilepath, "w"); -+ if (!fp) { -+ snprintf (err_str, sizeof (err_str), -+ "Failed to open file at %s", ofilepath); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "%s", err_str); -+ ret = -1; -+ goto out; -+ } -+ -+ fprintf (fp, "[Global]\n"); -+ -+ fprintf (fp, "MYUUID: %s\n", gf_strdup (uuid_utoa (priv->uuid))); -+ fprintf (fp, "op-version: %d\n", priv->op_version); -+ -+ fprintf (fp, "\n[Global options]\n"); -+ -+ if (priv->opts) -+ dict_foreach (priv->opts, glusterd_print_global_options, fp); -+ -+ rcu_read_lock (); -+ fprintf (fp, "\n[Peers]\n"); -+ -+ cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { -+ ret = gd_peer_state_str (peerinfo, peer_state_str); -+ if (ret) { -+ rcu_read_unlock (); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get peer state"); -+ goto out; -+ } -+ -+ fprintf (fp, "Peer%d.primary_hostname: %s\n", ++count, -+ peerinfo->hostname); -+ fprintf (fp, "Peer%d.uuid: %s\n", count, gd_peer_uuid_str (peerinfo)); -+ fprintf (fp, "Peer%d.state: %s\n", count, peer_state_str); -+ fprintf (fp, "Peer%d.connected: %d\n", count, peerinfo->connected); -+ -+ fprintf (fp, "Peer%d.hostnames: ", count); -+ cds_list_for_each_entry (peer_hostname_info, -+ &peerinfo->hostnames, hostname_list) -+ fprintf (fp, "%s, ", peer_hostname_info->hostname); -+ fprintf (fp, "\n"); -+ } -+ rcu_read_unlock (); -+ -+ count = 0; -+ fprintf (fp, "\n[Volumes]\n"); -+ -+ cds_list_for_each_entry (volinfo, &priv->volumes, vol_list) { -+ ret = glusterd_volume_get_type_str (volinfo, &vol_type_str); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get type for volume: %s", -+ volinfo->volname); -+ goto out; -+ } -+ -+ ret = glusterd_volume_get_status_str (volinfo, vol_status_str); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get status for volume: %s", -+ volinfo->volname); -+ goto out; -+ } -+ -+ ret = glusterd_volume_get_transport_type_str (volinfo, -+ transport_type_str); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get transport type for volume: %s", -+ volinfo->volname); -+ goto out; -+ } -+ -+ ret = glusterd_volume_get_quorum_status_str (volinfo, -+ quorum_status_str); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get quorum status for volume: %s", -+ volinfo->volname); -+ goto out; -+ } -+ -+ ret = glusterd_volume_get_rebalance_status_str (volinfo, -+ rebal_status_str); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get rebalance status for volume: %s", -+ volinfo->volname); -+ goto out; -+ } -+ -+ fprintf (fp, "Volume%d.name: %s\n", ++count, volinfo->volname); -+ fprintf (fp, "Volume%d.id: %s\n", count, -+ gf_strdup (uuid_utoa (volinfo->volume_id))); -+ fprintf (fp, "Volume%d.type: %s\n", count, vol_type_str); -+ fprintf (fp, "Volume%d.transport_type: %s\n", count, -+ transport_type_str); -+ fprintf (fp, "Volume%d.status: %s\n", count, vol_status_str); -+ fprintf (fp, "Volume%d.brickcount: %d\n", count, -+ volinfo->brick_count); -+ -+ count_bkp = count; -+ count = 0; -+ cds_list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { -+ fprintf (fp, "Volume%d.Brick%d.path: %s:%s\n", -+ count_bkp, ++count, brickinfo->hostname, -+ brickinfo->path); -+ fprintf (fp, "Volume%d.Brick%d.hostname: %s\n", -+ count_bkp, count, brickinfo->hostname); -+ -+ /* Add following information only for bricks -+ * local to current node */ -+ if (gf_uuid_compare (brickinfo->uuid, MY_UUID)) -+ continue; -+ fprintf (fp, "Volume%d.Brick%d.port: %d\n", count_bkp, -+ count, brickinfo->port); -+ fprintf (fp, "Volume%d.Brick%d.rdma_port: %d\n", count_bkp, -+ count, brickinfo->rdma_port); -+ fprintf (fp, "Volume%d.Brick%d.status: %s\n", count_bkp, -+ count, brickinfo->status ? "Started" : "Stopped"); -+ fprintf (fp, "Volume%d.Brick%d.filesystem_type: %s\n", -+ count_bkp, count, brickinfo->fstype); -+ fprintf (fp, "Volume%d.Brick%d.mount_options: %s\n", -+ count_bkp, count, brickinfo->mnt_opts); -+ fprintf (fp, "Volume%d.Brick%d.signedin: %s\n", count_bkp, -+ count, brickinfo->signed_in ? "True" : "False"); -+ } -+ -+ count = count_bkp; -+ -+ ret = glusterd_print_snapinfo_by_vol (fp, volinfo, count); -+ if (ret) -+ goto out; -+ -+ fprintf (fp, "Volume%d.snap_count: %"PRIu64"\n", count, -+ volinfo->snap_count); -+ fprintf (fp, "Volume%d.stripe_count: %d\n", count, -+ volinfo->stripe_count); -+ fprintf (fp, "Volume%d.subvol_count: %d\n", count, -+ volinfo->subvol_count); -+ fprintf (fp, "Volume%d.arbiter_count: %d\n", count, -+ volinfo->arbiter_count); -+ fprintf (fp, "Volume%d.disperse_count: %d\n", count, -+ volinfo->disperse_count); -+ fprintf (fp, "Volume%d.redundancy_count: %d\n", count, -+ volinfo->redundancy_count); -+ fprintf (fp, "Volume%d.quorum_status: %s\n", count, -+ quorum_status_str); -+ -+ fprintf (fp, "Volume%d.snapd_svc.online_status: %s\n", count, -+ volinfo->snapd.svc.online ? "Online" : "Offline"); -+ fprintf (fp, "Volume%d.snapd_svc.inited: %s\n", count, -+ volinfo->snapd.svc.inited ? "True" : "False"); -+ -+ fprintf (fp, "Volume%d.rebalance.id: %s\n", count, -+ gf_strdup (uuid_utoa (volinfo->rebal.rebalance_id))); -+ fprintf (fp, "Volume%d.rebalance.status: %s\n", count, -+ rebal_status_str); -+ fprintf (fp, "Volume%d.rebalance.failures: %"PRIu64"\n", count, -+ volinfo->rebal.rebalance_failures); -+ fprintf (fp, "Volume%d.rebalance.skipped: %"PRIu64"\n", count, -+ volinfo->rebal.skipped_files); -+ fprintf (fp, "Volume%d.rebalance.lookedup: %"PRIu64"\n", count, -+ volinfo->rebal.lookedup_files); -+ fprintf (fp, "Volume%d.rebalance.files: %"PRIu64"\n", count, -+ volinfo->rebal.rebalance_files); -+ fprintf (fp, "Volume%d.rebalance.data: %"PRIu64"\n", count, -+ volinfo->rebal.rebalance_data); -+ fprintf (fp, "Volume%d.rebalance.data: %"PRIu64"\n", count, -+ volinfo->rebal.rebalance_data); -+ -+ if (volinfo->type == GF_CLUSTER_TYPE_TIER) { -+ ret = glusterd_volume_get_hot_tier_type_str ( -+ volinfo, &hot_tier_type_str); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get hot tier type for " -+ "volume: %s", volinfo->volname); -+ goto out; -+ } -+ -+ ret = glusterd_volume_get_cold_tier_type_str ( -+ volinfo, &cold_tier_type_str); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_STATE_STR_GET_FAILED, -+ "Failed to get cold tier type for " -+ "volume: %s", volinfo->volname); -+ goto out; -+ } -+ -+ fprintf (fp, "Volume%d.tier_info.cold_tier_type: %s\n", -+ count, cold_tier_type_str); -+ fprintf (fp, "Volume%d.tier_info.cold_brick_count: %d\n", -+ count, volinfo->tier_info.cold_brick_count); -+ fprintf (fp, "Volume%d.tier_info.cold_replica_count: %d\n", -+ count, volinfo->tier_info.cold_replica_count); -+ fprintf (fp, "Volume%d.tier_info.cold_disperse_count: %d\n", -+ count, volinfo->tier_info.cold_disperse_count); -+ fprintf (fp, "Volume%d.tier_info.cold_dist_leaf_count: %d\n", -+ count, volinfo->tier_info.cold_dist_leaf_count); -+ fprintf (fp, "Volume%d.tier_info.cold_redundancy_count: %d\n", -+ count, volinfo->tier_info.cold_redundancy_count); -+ fprintf (fp, "Volume%d.tier_info.hot_tier_type: %s\n", -+ count, hot_tier_type_str); -+ fprintf (fp, "Volume%d.tier_info.hot_brick_count: %d\n", -+ count, volinfo->tier_info.hot_brick_count); -+ fprintf (fp, "Volume%d.tier_info.hot_replica_count: %d\n", -+ count, volinfo->tier_info.hot_replica_count); -+ fprintf (fp, "Volume%d.tier_info.promoted: %d\n", -+ count, volinfo->tier_info.promoted); -+ fprintf (fp, "Volume%d.tier_info.demoted: %d\n", -+ count, volinfo->tier_info.demoted); -+ } -+ -+ if (volinfo->rep_brick.src_brick && volinfo->rep_brick.dst_brick) { -+ fprintf (fp, "Volume%d.replace_brick.src: %s:%s\n", count, -+ volinfo->rep_brick.src_brick->hostname, -+ volinfo->rep_brick.src_brick->path); -+ fprintf (fp, "Volume%d.replace_brick.dest: %s:%s\n", count, -+ volinfo->rep_brick.dst_brick->hostname, -+ volinfo->rep_brick.dst_brick->path); -+ } -+ -+ fprintf (fp, "\n"); -+ } -+ -+ count = 0; -+ -+ fprintf (fp, "\n[Services]\n"); -+ -+ if (priv->shd_svc.inited) { -+ fprintf (fp, "svc%d.name: %s\n", ++count, priv->shd_svc.name); -+ fprintf (fp, "svc%d.online_status: %s\n\n", count, -+ priv->shd_svc.online ? "Online" : "Offline"); -+ } -+ -+ if (priv->nfs_svc.inited) { -+ fprintf (fp, "svc%d.name: %s\n", ++count, priv->nfs_svc.name); -+ fprintf (fp, "svc%d.online_status: %s\n\n", count, -+ priv->nfs_svc.online ? "Online" : "Offline"); -+ } -+ -+ if (priv->bitd_svc.inited) { -+ fprintf (fp, "svc%d.name: %s\n", ++count, priv->bitd_svc.name); -+ fprintf (fp, "svc%d.online_status: %s\n\n", count, -+ priv->bitd_svc.online ? "Online" : "Offline"); -+ } -+ -+ if (priv->scrub_svc.inited) { -+ fprintf (fp, "svc%d.name: %s\n", ++count, priv->scrub_svc.name); -+ fprintf (fp, "svc%d.online_status: %s\n\n", count, -+ priv->scrub_svc.online ? "Online" : "Offline"); -+ } -+ -+ if (priv->quotad_svc.inited) { -+ fprintf (fp, "svc%d.name: %s\n", ++count, priv->quotad_svc.name); -+ fprintf (fp, "svc%d.online_status: %s\n\n", count, -+ priv->quotad_svc.online ? "Online" : "Offline"); -+ } -+ -+ fprintf (fp, "\n[Misc]\n"); -+ if (priv->pmap) { -+ fprintf (fp, "Base port: %d\n", priv->pmap->base_port); -+ fprintf (fp, "Last allocated port: %d\n", -+ priv->pmap->last_alloc); -+ } -+out: -+ -+ if (fp) -+ fclose(fp); -+ -+ rsp.op_ret = ret; -+ rsp.op_errstr = err_str; -+ -+ ret = dict_allocate_and_serialize (dict, &rsp.dict.dict_val, -+ &rsp.dict.dict_len); -+ glusterd_to_cli (req, &rsp, NULL, 0, NULL, -+ (xdrproc_t)xdr_gf_cli_rsp, dict); -+ -+ return ret; -+} -+ -+static int -+__glusterd_handle_get_state (rpcsvc_request_t *req) -+{ -+ int32_t ret = -1; -+ gf_cli_req cli_req = {{0,},}; -+ dict_t *dict = NULL; -+ char err_str[2048] = {0,}; -+ xlator_t *this = NULL; -+ -+ this = THIS; -+ GF_VALIDATE_OR_GOTO (THIS->name, this, out); -+ GF_VALIDATE_OR_GOTO (this->name, req, out); -+ -+ ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); -+ if (ret < 0) { -+ snprintf (err_str, sizeof (err_str), "Failed to decode " -+ "request received from cli"); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_REQ_DECODE_FAIL, "%s", err_str); -+ req->rpc_err = GARBAGE_ARGS; -+ goto out; -+ } -+ -+ if (cli_req.dict.dict_len) { -+ /* Unserialize the dictionary */ -+ dict = dict_new (); -+ -+ ret = dict_unserialize (cli_req.dict.dict_val, -+ cli_req.dict.dict_len, -+ &dict); -+ if (ret < 0) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_UNSERIALIZE_FAIL, -+ "failed to " -+ "unserialize req-buffer to dictionary"); -+ snprintf (err_str, sizeof (err_str), "Unable to decode" -+ " the command"); -+ goto out; -+ } else { -+ dict->extra_stdfree = cli_req.dict.dict_val; -+ } -+ } -+ -+ gf_msg (this->name, GF_LOG_INFO, 0, GD_MSG_DAEMON_STATE_REQ_RCVD, -+ "Received request to get state for glusterd"); -+ -+ ret = glusterd_get_state (req, dict); -+ -+out: -+ if (dict) -+ dict_unref (dict); -+ return ret; -+} -+ -+int -+glusterd_handle_get_state (rpcsvc_request_t *req) -+{ -+ return glusterd_big_locked_handler (req, -+ __glusterd_handle_get_state); -+} -+ - static int - get_brickinfo_from_brickid (char *brickid, glusterd_brickinfo_t **brickinfo) - { -@@ -5373,6 +5888,7 @@ rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = { - [GLUSTER_CLI_GANESHA] = { "GANESHA" , GLUSTER_CLI_GANESHA, glusterd_handle_ganesha_cmd, NULL, 0, DRC_NA}, - [GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", GLUSTER_CLI_GET_VOL_OPT, glusterd_handle_get_vol_opt, NULL, 0, DRC_NA}, - [GLUSTER_CLI_BITROT] = {"BITROT", GLUSTER_CLI_BITROT, glusterd_handle_bitrot, NULL, 0, DRC_NA}, -+ [GLUSTER_CLI_GET_STATE] = {"GET_STATE", GLUSTER_CLI_GET_STATE, glusterd_handle_get_state, NULL, 0, DRC_NA}, - }; - - struct rpcsvc_program gd_svc_cli_prog = { -diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h -index 2c76dbf..af492e0 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-messages.h -+++ b/xlators/mgmt/glusterd/src/glusterd-messages.h -@@ -41,7 +41,7 @@ - - #define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD - --#define GLFS_NUM_MESSAGES 583 -+#define GLFS_NUM_MESSAGES 585 - - #define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1) - /* Messaged with message IDs */ -@@ -4689,6 +4689,7 @@ - */ - #define GD_MSG_MNTBROKER_LABEL_NULL (GLUSTERD_COMP_BASE + 580) - -+ - /*! - * @messageid - * @diagnosis -@@ -4713,6 +4714,22 @@ - */ - #define GD_MSG_SYSCALL_FAIL (GLUSTERD_COMP_BASE + 583) - -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendation -+ * -+ */ -+#define GD_MSG_DAEMON_STATE_REQ_RCVD (GLUSTERD_COMP_BASE + 584) -+ -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendation -+ * -+ */ -+#define GD_MSG_STATE_STR_GET_FAILED (GLUSTERD_COMP_BASE + 585) -+ - /*------------*/ - #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" - #endif /* !_GLUSTERD_MESSAGES_H_ */ -diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c -index 72d6b17..509efb7 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c -@@ -393,6 +393,57 @@ gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo) - return peerinfo->uuid_str; - } - -+int -+gd_peer_state_str (glusterd_peerinfo_t *peerinfo, char *state_str) -+{ -+ int ret = -1; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, peerinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, state_str, out); -+ -+ switch (peerinfo->state.state) { -+ case GD_FRIEND_STATE_DEFAULT: -+ gf_asprintf (&state_str, "%s", "default"); -+ break; -+ case GD_FRIEND_STATE_REQ_SENT: -+ gf_asprintf (&state_str, "%s", "request sent"); -+ break; -+ case GD_FRIEND_STATE_REQ_RCVD: -+ gf_asprintf (&state_str, "%s", "request received"); -+ break; -+ case GD_FRIEND_STATE_BEFRIENDED: -+ gf_asprintf (&state_str, "%s", "befriended"); -+ break; -+ case GD_FRIEND_STATE_REQ_ACCEPTED: -+ gf_asprintf (&state_str, "%s", "request accepted"); -+ break; -+ case GD_FRIEND_STATE_REQ_SENT_RCVD: -+ gf_asprintf (&state_str, "%s", "request sent received"); -+ break; -+ case GD_FRIEND_STATE_REJECTED: -+ gf_asprintf (&state_str, "%s", "rejected"); -+ break; -+ case GD_FRIEND_STATE_UNFRIEND_SENT: -+ gf_asprintf (&state_str, "%s", "unfriend sent"); -+ break; -+ case GD_FRIEND_STATE_PROBE_RCVD: -+ gf_asprintf (&state_str, "%s", "probe received"); -+ break; -+ case GD_FRIEND_STATE_CONNECTED_RCVD: -+ gf_asprintf (&state_str, "%s", "connected received"); -+ break; -+ case GD_FRIEND_STATE_CONNECTED_ACCEPTED: -+ gf_asprintf (&state_str, "%s", "connected accepted"); -+ break; -+ case GD_FRIEND_STATE_MAX: -+ goto out; -+ } -+ -+ ret = 0; -+out: -+ return ret; -+} -+ - gf_boolean_t - glusterd_are_all_peers_up () - { -diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.h b/xlators/mgmt/glusterd/src/glusterd-peer-utils.h -index 9332cf2..ee78b03 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.h -+++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.h -@@ -42,6 +42,9 @@ glusterd_uuid_to_hostname (uuid_t uuid); - char* - gd_peer_uuid_str (glusterd_peerinfo_t *peerinfo); - -+int -+gd_peer_state_str (glusterd_peerinfo_t *peerinfo, char *state_str); -+ - gf_boolean_t - glusterd_are_all_peers_up (); - -diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c -index a4660c7..2fa9a59 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c -@@ -4087,3 +4087,39 @@ gd_get_snap_conf_values_if_present (dict_t *dict, uint64_t *sys_hard_limit, - GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT); - } - } -+ -+int -+glusterd_get_snap_status_str (glusterd_snap_t *snapinfo, char *snap_status_str) -+{ -+ int ret = -1; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, snapinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, snap_status_str, out); -+ -+ switch (snapinfo->snap_status) { -+ case GD_SNAP_STATUS_NONE: -+ sprintf (snap_status_str, "%s", "none"); -+ break; -+ case GD_SNAP_STATUS_INIT: -+ sprintf (snap_status_str, "%s", "init"); -+ break; -+ case GD_SNAP_STATUS_IN_USE: -+ sprintf (snap_status_str, "%s", "in_use"); -+ break; -+ case GD_SNAP_STATUS_DECOMMISSION: -+ sprintf (snap_status_str, "%s", "decommissioned"); -+ break; -+ case GD_SNAP_STATUS_UNDER_RESTORE: -+ sprintf (snap_status_str, "%s", "under_restore"); -+ break; -+ case GD_SNAP_STATUS_RESTORED: -+ sprintf (snap_status_str, "%s", "restored"); -+ break; -+ default: -+ goto out; -+ } -+ ret = 0; -+out: -+ return ret; -+} -+ -diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h -index c0e7e8e..b964a43 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h -+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h -@@ -161,6 +161,8 @@ glusterd_is_snap_soft_limit_reached (glusterd_volinfo_t *volinfo, - void - gd_get_snap_conf_values_if_present (dict_t *opts, uint64_t *sys_hard_limit, - uint64_t *sys_soft_limit); -+int -+glusterd_get_snap_status_str (glusterd_snap_t *snapinfo, char *snap_status_str); - - #endif - -diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c -index 44c9284..66c8b63 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c -@@ -59,6 +59,7 @@ - #include "glusterd-bitd-svc.h" - #include "glusterd-server-quorum.h" - #include "quota-common-utils.h" -+#include "common-utils.h" - - #include "xdr-generic.h" - #include -@@ -11219,6 +11220,199 @@ glusterd_is_volume_started (glusterd_volinfo_t *volinfo) - return (volinfo->status == GLUSTERD_STATUS_STARTED); - } - -+int -+glusterd_volume_get_type_str (glusterd_volinfo_t *volinfo, char **voltype_str) -+{ -+ int ret = -1; -+ int type = 0; -+ int brick_count = 0; -+ int dist_count = 0; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ -+ type = get_vol_type (volinfo->type, volinfo->brick_count, -+ volinfo->dist_leaf_count); -+ -+ *voltype_str = vol_type_str[type]; -+ -+ ret = 0; -+out: -+ return ret; -+} -+ -+int -+glusterd_volume_get_status_str (glusterd_volinfo_t *volinfo, char *status_str) -+{ -+ int ret = -1; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, status_str, out); -+ -+ switch (volinfo->status) { -+ case GLUSTERD_STATUS_NONE: -+ sprintf (status_str, "%s", "Created"); -+ break; -+ case GLUSTERD_STATUS_STARTED: -+ sprintf (status_str, "%s", "Started"); -+ break; -+ case GLUSTERD_STATUS_STOPPED: -+ sprintf (status_str, "%s", "Stopped"); -+ break; -+ default: -+ goto out; -+ -+ } -+ ret = 0; -+out: -+ return ret; -+} -+ -+int -+glusterd_volume_get_transport_type_str (glusterd_volinfo_t *volinfo, -+ char *transport_type_str) -+{ -+ int ret = -1; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, transport_type_str, out); -+ -+ switch (volinfo->transport_type) { -+ case GF_TRANSPORT_TCP: -+ sprintf (transport_type_str, "%s", "tcp"); -+ break; -+ case GF_TRANSPORT_RDMA: -+ sprintf (transport_type_str, "%s", "rdma"); -+ break; -+ case GF_TRANSPORT_BOTH_TCP_RDMA: -+ sprintf (transport_type_str, "%s", "tcp_rdma_both"); -+ break; -+ default: -+ goto out; -+ -+ } -+ ret = 0; -+out: -+ return ret; -+} -+ -+int -+glusterd_volume_get_quorum_status_str (glusterd_volinfo_t *volinfo, -+ char *quorum_status_str) -+{ -+ int ret = -1; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, quorum_status_str, out); -+ -+ switch (volinfo->quorum_status) { -+ case NOT_APPLICABLE_QUORUM: -+ sprintf (quorum_status_str, "%s", "not_applicable"); -+ break; -+ case MEETS_QUORUM: -+ sprintf (quorum_status_str, "%s", "meets"); -+ break; -+ case DOESNT_MEET_QUORUM: -+ sprintf (quorum_status_str, "%s", "does_not_meet"); -+ break; -+ default: -+ goto out; -+ -+ } -+ ret = 0; -+out: -+ return ret; -+} -+ -+int -+glusterd_volume_get_rebalance_status_str (glusterd_volinfo_t *volinfo, -+ char *rebal_status_str) -+{ -+ int ret = -1; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, rebal_status_str, out); -+ -+ switch (volinfo->rebal.defrag_status) { -+ case GF_DEFRAG_STATUS_NOT_STARTED: -+ sprintf (rebal_status_str, "%s", "not_started"); -+ break; -+ case GF_DEFRAG_STATUS_STARTED: -+ sprintf (rebal_status_str, "%s", "started"); -+ break; -+ case GF_DEFRAG_STATUS_STOPPED: -+ sprintf (rebal_status_str, "%s", "stopped"); -+ break; -+ case GF_DEFRAG_STATUS_COMPLETE: -+ sprintf (rebal_status_str, "%s", "completed"); -+ break; -+ case GF_DEFRAG_STATUS_FAILED: -+ sprintf (rebal_status_str, "%s", "failed"); -+ break; -+ case GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED: -+ sprintf (rebal_status_str, "%s", "layout_fix_started"); -+ break; -+ case GF_DEFRAG_STATUS_LAYOUT_FIX_STOPPED: -+ sprintf (rebal_status_str, "%s", "layout_fix_stopped"); -+ break; -+ case GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE: -+ sprintf (rebal_status_str, "%s", "layout_fix_complete"); -+ break; -+ case GF_DEFRAG_STATUS_LAYOUT_FIX_FAILED: -+ sprintf (rebal_status_str, "%s", "layout_fix_failed"); -+ break; -+ default: -+ goto out; -+ } -+ ret = 0; -+out: -+ return ret; -+} -+ -+int -+glusterd_volume_get_hot_tier_type_str (glusterd_volinfo_t *volinfo, -+ char **hot_tier_type_str) -+{ -+ int ret = -1; -+ int hot_tier_type = 0; -+ int hot_dist_count = 0; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, hot_tier_type_str, out); -+ -+ hot_dist_count = volinfo->tier_info.hot_replica_count ? -+ volinfo->tier_info.hot_replica_count : 1; -+ -+ hot_tier_type = get_vol_type (volinfo->tier_info.hot_type, hot_dist_count, -+ volinfo->tier_info.hot_brick_count); -+ -+ *hot_tier_type_str = vol_type_str[hot_tier_type]; -+ -+ ret = 0; -+out: -+ return ret; -+} -+ -+int -+glusterd_volume_get_cold_tier_type_str (glusterd_volinfo_t *volinfo, -+ char **cold_tier_type_str) -+{ -+ int ret = -1; -+ int cold_tier_type = 0; -+ -+ GF_VALIDATE_OR_GOTO (THIS->name, volinfo, out); -+ GF_VALIDATE_OR_GOTO (THIS->name, cold_tier_type_str, out); -+ -+ cold_tier_type = get_vol_type (volinfo->tier_info.cold_type, -+ volinfo->tier_info.cold_dist_leaf_count, -+ volinfo->tier_info.cold_brick_count); -+ -+ *cold_tier_type_str = vol_type_str[cold_tier_type]; -+ -+ ret = 0; -+out: -+ return ret; -+} -+ - /* This function will insert the element to the list in a order. - Order will be based on the compare function provided as a input. - If element to be inserted in ascending order compare should return: -diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h -index f4c4138..ca07efd 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-utils.h -+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h -@@ -678,6 +678,32 @@ glusterd_nfs_pmap_deregister (); - gf_boolean_t - glusterd_is_volume_started (glusterd_volinfo_t *volinfo); - -+int -+glusterd_volume_get_type_str (glusterd_volinfo_t *volinfo, char **vol_type_str); -+ -+int -+glusterd_volume_get_status_str (glusterd_volinfo_t *volinfo, char *status_str); -+ -+int -+glusterd_volume_get_transport_type_str (glusterd_volinfo_t *volinfo, -+ char *transport_type_str); -+ -+int -+glusterd_volume_get_quorum_status_str (glusterd_volinfo_t *volinfo, -+ char *quorum_status_str); -+ -+int -+glusterd_volume_get_rebalance_status_str (glusterd_volinfo_t *volinfo, -+ char *rebal_status_str); -+ -+int -+glusterd_volume_get_hot_tier_type_str (glusterd_volinfo_t *volinfo, -+ char **hot_tier_type_str); -+ -+int -+glusterd_volume_get_cold_tier_type_str (glusterd_volinfo_t *volinfo, -+ char **cold_tier_type_str); -+ - void - glusterd_list_add_order (struct cds_list_head *new, struct cds_list_head *head, - int (*compare)(struct cds_list_head *, -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index 3aaedbc..29aaf64 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -55,6 +55,7 @@ - #define GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT 90 - #define GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT 100 - #define GLUSTERD_SERVER_QUORUM "server" -+#define STATUS_STRLEN 128 - - #define FMTSTR_CHECK_VOL_EXISTS "Volume %s does not exist" - #define FMTSTR_RESOLVE_BRICK "Could not find peer on which brick %s:%s resides" --- -1.7.1 - diff --git a/SOURCES/0028-glusterd-parallel-readdir-Change-the-op-version-of-p.patch b/SOURCES/0028-glusterd-parallel-readdir-Change-the-op-version-of-p.patch new file mode 100644 index 0000000..a40db89 --- /dev/null +++ b/SOURCES/0028-glusterd-parallel-readdir-Change-the-op-version-of-p.patch @@ -0,0 +1,42 @@ +From 91489431c48f6fa9bce3ee6f377bc9702602b18d Mon Sep 17 00:00:00 2001 +From: Poornima G +Date: Wed, 26 Apr 2017 14:07:58 +0530 +Subject: [PATCH 28/74] glusterd, parallel-readdir: Change the op-version of + parallel-readdir to 31100 + +Issue: Downstream 3.2 was released with op-version 31001, parallel-readdir +feature in upstream was released in 3.10 and hence with op-version 31000. +With this, parallel-readdir will be allowed in 3.2 cluster/clients as well. +But 3.2 didn't have parallel-readdir feature backported. + +Fix: +Increase the op-version of parallel-readdir feature only in downstream +to 31100(3.3 highest op-version) + +Label: DOWNSTREAM ONLY + +Change-Id: I2640520985627f3a1cb4fb96e28350f8bb9b146c +Signed-off-by: Poornima G +Reviewed-on: https://code.engineering.redhat.com/gerrit/104403 +Reviewed-by: Atin Mukherjee +Tested-by: Atin Mukherjee +--- + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +index 93ef85c..9729767 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +@@ -3376,7 +3376,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { + .option = "parallel-readdir", + .value = "off", + .type = DOC, +- .op_version = GD_OP_VERSION_3_10_0, ++ .op_version = GD_OP_VERSION_3_11_0, + .validate_fn = validate_parallel_readdir, + .description = "If this option is enabled, the readdir operation " + "is performed in parallel on all the bricks, thus " +-- +1.8.3.1 + diff --git a/SOURCES/0029-build-exclude-glusterfssharedstorage.service-and-mou.patch b/SOURCES/0029-build-exclude-glusterfssharedstorage.service-and-mou.patch new file mode 100644 index 0000000..366df42 --- /dev/null +++ b/SOURCES/0029-build-exclude-glusterfssharedstorage.service-and-mou.patch @@ -0,0 +1,68 @@ +From 7562ffbce9d768d5af9d23361cf6dd6ef992bead Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Fri, 10 Nov 2017 23:38:14 +0530 +Subject: [PATCH 29/74] build: exclude glusterfssharedstorage.service and + mount-shared-storage.sh from client builds + +Label: DOWNSTREAM ONLY + +Change-Id: I7d76ba0742b5c6a44505eb883eacda0c91efbe51 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://code.engineering.redhat.com/gerrit/109684 +Reviewed-by: Milind Changire +Tested-by: Milind Changire +Reviewed-by: Atin Mukherjee +--- + glusterfs.spec.in | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 343e88f..4596e3f 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1083,6 +1083,20 @@ exit 0 + %exclude %{_libexecdir}/glusterfs/glusterfind + %exclude %{_bindir}/glusterfind + %exclude %{_libexecdir}/glusterfs/peer_add_secret_pub ++# exclude eventsapi files ++%exclude %{_sysconfdir}/glusterfs/eventsconfig.json ++%exclude %{_sharedstatedir}/glusterd/events ++%exclude %{_libexecdir}/glusterfs/events ++%exclude %{_libexecdir}/glusterfs/peer_eventsapi.py* ++%exclude %{_sbindir}/glustereventsd ++%exclude %{_sbindir}/gluster-eventsapi ++%exclude %{_datadir}/glusterfs/scripts/eventsdash.py* ++%if ( 0%{?_with_systemd:1} ) ++%exclude %{_unitdir}/glustereventsd.service ++%exclude %_init_glusterfssharedstorage ++%else ++%exclude %{_sysconfdir}/init.d/glustereventsd ++%endif + # exclude server files + %exclude %{_sharedstatedir}/glusterd/* + %exclude %{_sysconfdir}/glusterfs +@@ -1123,6 +1137,9 @@ exit 0 + %exclude %{_sbindir}/glusterd + %exclude %{_sbindir}/snap_scheduler.py + %exclude %{_datadir}/glusterfs/scripts/stop-all-gluster-processes.sh ++%if ( 0%{?_with_systemd:1} ) ++%exclude %{_libexecdir}/glusterfs/mount-shared-storage.sh ++%endif + %exclude %{_sbindir}/conf.py* + %if 0%{?_tmpfilesdir:1} + %exclude %{_tmpfilesdir}/gluster.conf +@@ -2181,7 +2198,10 @@ end + * Thu Jul 13 2017 Kaleb S. KEITHLEY + - various directories not owned by any package + +-* Fri Jun 16 2017 Jiffin Tony Thottan ++* Wed Jun 21 2017 Jiffin Tony Thottan ++- Exclude glusterfssharedstorage.service and mount-shared-storage.sh from client builds ++ ++* Tue Jun 20 2017 Jiffin Tony Thottan + - Add glusterfssharedstorage.service systemd file + + * Fri Jun 9 2017 Poornima G +-- +1.8.3.1 + diff --git a/SOURCES/0029-eventsapi-Gluster-Eventing-Feature-implementation.patch b/SOURCES/0029-eventsapi-Gluster-Eventing-Feature-implementation.patch deleted file mode 100644 index f3ab2db..0000000 --- a/SOURCES/0029-eventsapi-Gluster-Eventing-Feature-implementation.patch +++ /dev/null @@ -1,1793 +0,0 @@ -From 2be99b28595ffab1d503354db832f981ded2671f Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Thu, 5 May 2016 18:34:41 +0530 -Subject: [PATCH 29/79] eventsapi: Gluster Eventing Feature implementation - -[Depends on http://review.gluster.org/14627] - -Design is available in `glusterfs-specs`, A change from the design -is support of webhook instead of Websockets as discussed in the design - -http://review.gluster.org/13115 - -Since Websocket support depends on REST APIs, I will add Websocket support -once REST APIs patch gets merged - -Usage: -Run following command to start/stop Eventsapi server in all Peers, -which will collect the notifications from any Gluster daemon and emits -to configured client. - - gluster-eventsapi start|stop|restart|reload - -Status of running services can be checked using, - - gluster-eventsapi status - -Events listener is a HTTP(S) server which listens to events emited by -the Gluster. Create a HTTP Server to listen on POST and register that -URL using, - - gluster-eventsapi webhook-add [--bearer-token ] - -For example, if HTTP Server running in `http://192.168.122.188:9000` -then add that URL using, - - gluster-eventsapi webhook-add http://192.168.122.188:9000 - -If it expects a Token then specify it using `--bearer-token` or `-t` - -We can also test Webhook if all peer nodes can send message or not -using, - - gluster-eventsapi webhook-test [--bearer-token ] - -Configurations can be viewed/updated using, - - gluster-eventsapi config-get [--name] - gluster-eventsapi config-set - gluster-eventsapi config-reset - -If any one peer node was down during config-set/reset or webhook -modifications, Run sync command from good node when a peer node comes -back. Automatic update is not yet implemented. - - gluster-eventsapi sync - -Basic Events Client(HTTP Server) is included with the code, Start -running the client with required port and start listening to the -events. - - /usr/share/glusterfs/scripts/eventsdash.py --port 8080 - -Default port is 9000, if no port is specified, once it started running -then configure gluster-eventsapi to send events to that client. - -Eventsapi Client can be outside of the Cluster, it can be run event on -Windows. But only requirement is the client URL should be accessible -by all peer nodes.(Or ngrok(https://ngrok.com) like tools can be used) - -Events implemented with this patch, -- Volume Create -- Volume Start -- Volume Stop -- Volume Delete -- Peer Attach -- Peer Detach - -It is easy to add/support more events, since it touches Gluster cmd -code and to avoid merge conflicts I will add support for more events -once this patch merges. - -> Reviewed-on: http://review.gluster.org/14248 -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Jeff Darcy - -BUG: 1351589 -Change-Id: I316827ac9dd1443454df7deffe4f54835f7f6a08 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84620 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - Makefile.am | 2 +- - cli/src/cli-cmd-peer.c | 12 + - cli/src/cli-cmd-volume.c | 24 ++- - configure.ac | 49 +++ - events/Makefile.am | 6 + - events/eventskeygen.py | 65 ++++ - events/src/Makefile.am | 24 ++ - events/src/__init__.py | 10 + - events/src/eventsapiconf.py.in | 22 ++ - events/src/eventsconfig.json | 3 + - events/src/eventtypes.py | 9 + - events/src/glustereventsd.py | 151 +++++++++ - events/src/handlers.py | 21 ++ - events/src/peer_eventsapi.py | 521 ++++++++++++++++++++++++++++++ - events/src/utils.py | 150 +++++++++ - events/tools/Makefile.am | 3 + - events/tools/eventsdash.py | 74 +++++ - extras/systemd/Makefile.am | 8 +- - extras/systemd/glustereventsd.service.in | 12 + - glusterfs.spec.in | 59 ++++- - libglusterfs/src/Makefile.am | 6 + - libglusterfs/src/events.c | 83 +++++ - libglusterfs/src/events.h.in | 23 ++ - libglusterfs/src/eventtypes.h | 22 ++ - libglusterfs/src/glusterfs.h | 4 + - 27 files changed, 1378 insertions(+), 5 deletions(-) - create mode 100644 events/Makefile.am - create mode 100644 events/eventskeygen.py - create mode 100644 events/src/Makefile.am - create mode 100644 events/src/__init__.py - create mode 100644 events/src/eventsapiconf.py.in - create mode 100644 events/src/eventsconfig.json - create mode 100644 events/src/eventtypes.py - create mode 100644 events/src/glustereventsd.py - create mode 100644 events/src/handlers.py - create mode 100644 events/src/peer_eventsapi.py - create mode 100644 events/src/utils.py - create mode 100644 events/tools/Makefile.am - create mode 100644 events/tools/eventsdash.py - create mode 100644 extras/systemd/glustereventsd.service.in - create mode 100644 libglusterfs/src/events.c - create mode 100644 libglusterfs/src/events.h.in - create mode 100644 libglusterfs/src/eventtypes.h - -diff --git a/Makefile.am b/Makefile.am -index d36f530..37cbb86 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -12,7 +12,7 @@ EXTRA_DIST = autogen.sh \ - - SUBDIRS = $(ARGP_STANDALONE_DIR) libglusterfs rpc api xlators glusterfsd \ - $(FUSERMOUNT_SUBDIR) doc extras cli heal @SYNCDAEMON_SUBDIR@ \ -- @UMOUNTD_SUBDIR@ tools -+ @UMOUNTD_SUBDIR@ tools @EVENTS_SUBDIR@ - - pkgconfigdir = @pkgconfigdir@ - pkgconfig_DATA = glusterfs-api.pc libgfchangelog.pc -diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c -index d6b4ab1..36c328a 100644 ---- a/cli/src/cli-cmd-peer.c -+++ b/cli/src/cli-cmd-peer.c -@@ -90,6 +90,12 @@ out: - - CLI_STACK_DESTROY (frame); - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ gf_event (EVENT_PEER_ATTACH, "host=%s", (char *)words[2]); -+ } -+#endif -+ - return ret; - } - -@@ -160,6 +166,12 @@ out: - - CLI_STACK_DESTROY (frame); - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ gf_event (EVENT_PEER_DETACH, "host=%s", (char *)words[2]); -+ } -+#endif -+ - return ret; - } - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 129d9b9..5296093 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -243,7 +243,11 @@ out: - } - - CLI_STACK_DESTROY (frame); -- -+#if (USE_EVENTS) -+ if (ret == 0) { -+ gf_event (EVENT_VOLUME_CREATE, "name=%s", (char *)words[2]); -+ } -+#endif - return ret; - } - -@@ -318,6 +322,12 @@ out: - - CLI_STACK_DESTROY (frame); - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ gf_event (EVENT_VOLUME_DELETE, "name=%s", (char *)words[2]); -+ } -+#endif -+ - return ret; - } - -@@ -392,6 +402,12 @@ out: - - CLI_STACK_DESTROY (frame); - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ gf_event (EVENT_VOLUME_START, "name=%s", (char *)words[2]); -+ } -+#endif -+ - return ret; - } - -@@ -524,6 +540,12 @@ out: - - CLI_STACK_DESTROY (frame); - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ gf_event (EVENT_VOLUME_STOP, "name=%s", (char *)words[2]); -+ } -+#endif -+ - return ret; - } - -diff --git a/configure.ac b/configure.ac -index 9025114..2e0323d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -38,6 +38,7 @@ AC_CONFIG_HEADERS([config.h]) - AC_CONFIG_FILES([Makefile - libglusterfs/Makefile - libglusterfs/src/Makefile -+ libglusterfs/src/events.h - libglusterfs/src/gfdb/Makefile - geo-replication/src/peer_gsec_create - geo-replication/src/peer_mountbroker -@@ -206,6 +207,7 @@ AC_CONFIG_FILES([Makefile - extras/ganesha/ocf/Makefile - extras/systemd/Makefile - extras/systemd/glusterd.service -+ extras/systemd/glustereventsd.service - extras/run-gluster.tmpfiles - extras/benchmarking/Makefile - extras/hook-scripts/Makefile -@@ -229,6 +231,10 @@ AC_CONFIG_FILES([Makefile - extras/hook-scripts/reset/post/Makefile - extras/hook-scripts/reset/pre/Makefile - extras/snap_scheduler/Makefile -+ events/Makefile -+ events/src/Makefile -+ events/src/eventsapiconf.py -+ events/tools/Makefile - contrib/fuse-util/Makefile - contrib/umountd/Makefile - contrib/uuid/uuid_types.h -@@ -700,6 +706,43 @@ fi - AC_SUBST(GEOREP_EXTRAS_SUBDIR) - AM_CONDITIONAL(USE_GEOREP, test "x$enable_georeplication" != "xno") - -+# Events section -+AC_ARG_ENABLE([events], -+ AC_HELP_STRING([--disable-events], -+ [Do not install Events components])) -+ -+BUILD_EVENTS=no -+EVENTS_ENABLED=0 -+EVENTS_SUBDIR= -+have_python2=no -+if test "x$enable_events" != "xno"; then -+ EVENTS_SUBDIR=events -+ EVENTS_ENABLED=1 -+ -+ BUILD_EVENTS="yes" -+ AM_PATH_PYTHON() -+ dnl Check if version matches that we require -+ if echo $PYTHON_VERSION | grep ^2; then -+ have_python2=yes -+ fi -+ -+ if test "x$have_python2" = "xno"; then -+ if test "x$enable_events" = "xyes"; then -+ AC_MSG_ERROR([python 2.x packages required. exiting..]) -+ fi -+ AC_MSG_WARN([python 2.x not found, disabling events]) -+ EVENTS_SUBDIR= -+ EVENTS_ENABLED=0 -+ BUILD_EVENTS="no" -+ else -+ AC_DEFINE(USE_EVENTS, 1, [define if events enabled]) -+ fi -+fi -+AC_SUBST(EVENTS_ENABLED) -+AC_SUBST(EVENTS_SUBDIR) -+AM_CONDITIONAL([BUILD_EVENTS], [test x$BUILD_EVENTS = xyes]) -+# end Events section -+ - # CDC xlator - check if libz is present if so enable HAVE_LIB_Z - BUILD_CDC=yes - PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.0],, -@@ -1079,10 +1122,15 @@ eval sbintemp=\"${sbintemp}\" - eval sbintemp=\"${sbintemp}\" - SBIN_DIR=${sbintemp} - -+sysconfdirtemp="${sysconfdir}" -+eval sysconfdirtemp=\"${sysconfdirtemp}\" -+SYSCONF_DIR=${sysconfdirtemp} -+ - prefix=$prefix_temp - exec_prefix=$exec_prefix_temp - - AC_SUBST(SBIN_DIR) -+AC_SUBST(SYSCONF_DIR) - - # lazy umount emulation - UMOUNTD_SUBDIR="" -@@ -1359,4 +1407,5 @@ echo "POSIX ACLs : $BUILD_POSIX_ACLS" - echo "Data Classification : $BUILD_GFDB" - echo "firewalld-config : $BUILD_FIREWALLD" - echo "Experimental xlators : $BUILD_EXPERIMENTAL" -+echo "Events : $BUILD_EVENTS" - echo -diff --git a/events/Makefile.am b/events/Makefile.am -new file mode 100644 -index 0000000..04a74ef ---- /dev/null -+++ b/events/Makefile.am -@@ -0,0 +1,6 @@ -+SUBDIRS = src tools -+ -+noinst_PYTHON = eventskeygen.py -+ -+install-data-hook: -+ $(INSTALL) -d -m 755 $(DESTDIR)@GLUSTERD_WORKDIR@/events -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -new file mode 100644 -index 0000000..656a7dc ---- /dev/null -+++ b/events/eventskeygen.py -@@ -0,0 +1,65 @@ -+#!/usr/bin/env python -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+import os -+ -+GLUSTER_SRC_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -+eventtypes_h = os.path.join(GLUSTER_SRC_ROOT, "libglusterfs/src/eventtypes.h") -+eventtypes_py = os.path.join(GLUSTER_SRC_ROOT, "events/src/eventtypes.py") -+ -+# When adding new keys add it to the END -+keys = ( -+ "EVENT_PEER_ATTACH", -+ "EVENT_PEER_DETACH", -+ -+ "EVENT_VOLUME_CREATE", -+ "EVENT_VOLUME_START", -+ "EVENT_VOLUME_STOP", -+ "EVENT_VOLUME_DELETE", -+) -+ -+LAST_EVENT = "EVENT_LAST" -+ -+ERRORS = ( -+ "EVENT_SEND_OK", -+ "EVENT_ERROR_INVALID_INPUTS", -+ "EVENT_ERROR_SOCKET", -+ "EVENT_ERROR_CONNECT", -+ "EVENT_ERROR_SEND" -+) -+ -+# Generate eventtypes.h -+with open(eventtypes_h, "w") as f: -+ f.write("#ifndef __EVENTTYPES_H__\n") -+ f.write("#define __EVENTTYPES_H__\n\n") -+ f.write("typedef enum {\n") -+ for k in ERRORS: -+ f.write(" {0},\n".format(k)) -+ f.write("} event_errors_t;\n") -+ -+ f.write("\n") -+ -+ f.write("typedef enum {\n") -+ for k in keys: -+ f.write(" {0},\n".format(k)) -+ -+ f.write(" {0}\n".format(LAST_EVENT)) -+ f.write("} eventtypes_t;\n") -+ f.write("\n#endif /* __EVENTTYPES_H__ */\n") -+ -+# Generate eventtypes.py -+with open(eventtypes_py, "w") as f: -+ f.write("# -*- coding: utf-8 -*-\n") -+ f.write("all_events = [\n") -+ for ev in keys: -+ f.write(' "{0}",\n'.format(ev)) -+ f.write("]\n") -diff --git a/events/src/Makefile.am b/events/src/Makefile.am -new file mode 100644 -index 0000000..528f020 ---- /dev/null -+++ b/events/src/Makefile.am -@@ -0,0 +1,24 @@ -+EXTRA_DIST = glustereventsd.py __init__.py eventsapiconf.py.in eventtypes.py \ -+ handlers.py utils.py peer_eventsapi.py eventsconfig.json -+ -+eventsdir = $(libexecdir)/glusterfs/events -+eventspeerscriptdir = $(libexecdir)/glusterfs -+eventsconfdir = $(sysconfdir)/glusterfs -+eventsconf_DATA = eventsconfig.json -+ -+events_PYTHON = __init__.py eventsapiconf.py eventtypes.py handlers.py utils.py -+events_SCRIPTS = glustereventsd.py -+eventspeerscript_SCRIPTS = peer_eventsapi.py -+ -+install-exec-hook: -+ $(mkdir_p) $(DESTDIR)$(sbindir) -+ rm -f $(DESTDIR)$(sbindir)/glustereventsd -+ ln -s $(libexecdir)/glusterfs/events/glustereventsd.py \ -+ $(DESTDIR)$(sbindir)/glustereventsd -+ rm -f $(DESTDIR)$(sbindir)/gluster-eventing -+ ln -s $(libexecdir)/glusterfs/peer_eventsapi.py \ -+ $(DESTDIR)$(sbindir)/gluster-eventsapi -+ -+uninstall-hook: -+ rm -f $(DESTDIR)$(sbindir)/glustereventsd -+ rm -f $(DESTDIR)$(sbindir)/gluster-eventsapi -diff --git a/events/src/__init__.py b/events/src/__init__.py -new file mode 100644 -index 0000000..f27c53a ---- /dev/null -+++ b/events/src/__init__.py -@@ -0,0 +1,10 @@ -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -diff --git a/events/src/eventsapiconf.py.in b/events/src/eventsapiconf.py.in -new file mode 100644 -index 0000000..702e1d2 ---- /dev/null -+++ b/events/src/eventsapiconf.py.in -@@ -0,0 +1,22 @@ -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+SERVER_ADDRESS = "@localstatedir@/run/gluster/events.sock" -+DEFAULT_CONFIG_FILE = "@SYSCONF_DIR@/glusterfs/eventsconfig.json" -+CUSTOM_CONFIG_FILE_TO_SYNC = "/events/config.json" -+CUSTOM_CONFIG_FILE = "@GLUSTERD_WORKDIR@" + CUSTOM_CONFIG_FILE_TO_SYNC -+WEBHOOKS_FILE_TO_SYNC = "/events/webhooks.json" -+WEBHOOKS_FILE = "@GLUSTERD_WORKDIR@" + WEBHOOKS_FILE_TO_SYNC -+LOG_FILE = "@localstatedir@/log/glusterfs/events.log" -+EVENTSD = "glustereventsd" -+CONFIG_KEYS = ["log_level"] -+BOOL_CONFIGS = [] -+RESTART_CONFIGS = [] -diff --git a/events/src/eventsconfig.json b/events/src/eventsconfig.json -new file mode 100644 -index 0000000..ce2c775 ---- /dev/null -+++ b/events/src/eventsconfig.json -@@ -0,0 +1,3 @@ -+{ -+ "log_level": "INFO" -+} -diff --git a/events/src/eventtypes.py b/events/src/eventtypes.py -new file mode 100644 -index 0000000..4812e65 ---- /dev/null -+++ b/events/src/eventtypes.py -@@ -0,0 +1,9 @@ -+# -*- coding: utf-8 -*- -+all_events = [ -+ "EVENT_PEER_ATTACH", -+ "EVENT_PEER_DETACH", -+ "EVENT_VOLUME_CREATE", -+ "EVENT_VOLUME_START", -+ "EVENT_VOLUME_STOP", -+ "EVENT_VOLUME_DELETE", -+] -diff --git a/events/src/glustereventsd.py b/events/src/glustereventsd.py -new file mode 100644 -index 0000000..3fa5768 ---- /dev/null -+++ b/events/src/glustereventsd.py -@@ -0,0 +1,151 @@ -+#!/usr/bin/env python -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+from __future__ import print_function -+import asyncore -+import socket -+import os -+from multiprocessing import Process, Queue -+import sys -+import signal -+ -+from eventtypes import all_events -+import handlers -+import utils -+from eventsapiconf import SERVER_ADDRESS -+from utils import logger -+ -+# Global Queue, EventsHandler will add items to the queue -+# and process_event will gets each item and handles it -+events_queue = Queue() -+events_server_pid = None -+ -+ -+def process_event(): -+ """ -+ Seperate process which handles all the incoming events from Gluster -+ processes. -+ """ -+ while True: -+ data = events_queue.get() -+ logger.debug("EVENT: {0}".format(repr(data))) -+ try: -+ # Event Format -+ ts, key, value = data.split(" ", 2) -+ except ValueError: -+ logger.warn("Invalid Event Format {0}".format(data)) -+ continue -+ -+ data_dict = {} -+ try: -+ # Format key=value;key=value -+ data_dict = dict(x.split('=') for x in value.split(';')) -+ except ValueError: -+ logger.warn("Unable to parse Event {0}".format(data)) -+ continue -+ -+ try: -+ # Event Type to Function Map, Recieved event data will be in -+ # the form , Get Event name for the -+ # recieved Type/Key and construct a function name starting with -+ # handle_ For example: handle_event_volume_create -+ func_name = "handle_" + all_events[int(key)].lower() -+ except IndexError: -+ # This type of Event is not handled? -+ logger.warn("Unhandled Event: {0}".format(key)) -+ func_name = None -+ -+ if func_name is not None: -+ # Get function from handlers module -+ func = getattr(handlers, func_name, None) -+ # If func is None, then handler unimplemented for that event. -+ if func is not None: -+ func(ts, int(key), data_dict) -+ else: -+ # Generic handler, broadcast whatever received -+ handlers.generic_handler(ts, int(key), data_dict) -+ -+ -+def process_event_wrapper(): -+ try: -+ process_event() -+ except KeyboardInterrupt: -+ return -+ -+ -+class GlusterEventsHandler(asyncore.dispatcher_with_send): -+ -+ def handle_read(self): -+ data = self.recv(8192) -+ if data: -+ events_queue.put(data) -+ self.send(data) -+ -+ -+class GlusterEventsServer(asyncore.dispatcher): -+ -+ def __init__(self): -+ global events_server_pid -+ asyncore.dispatcher.__init__(self) -+ # Start the Events listener process which listens to -+ # the global queue -+ p = Process(target=process_event_wrapper) -+ p.start() -+ events_server_pid = p.pid -+ -+ # Create UNIX Domain Socket, bind to path -+ self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM) -+ self.bind(SERVER_ADDRESS) -+ self.listen(5) -+ -+ def handle_accept(self): -+ pair = self.accept() -+ if pair is not None: -+ sock, addr = pair -+ GlusterEventsHandler(sock) -+ -+ -+def signal_handler_sigusr2(sig, frame): -+ if events_server_pid is not None: -+ os.kill(events_server_pid, signal.SIGUSR2) -+ utils.load_all() -+ -+ -+def init_event_server(): -+ utils.setup_logger() -+ -+ # Delete Socket file if Exists -+ try: -+ os.unlink(SERVER_ADDRESS) -+ except OSError: -+ if os.path.exists(SERVER_ADDRESS): -+ print ("Failed to cleanup socket file {0}".format(SERVER_ADDRESS), -+ file=sys.stderr) -+ sys.exit(1) -+ -+ utils.load_all() -+ -+ # Start the Eventing Server, UNIX DOMAIN SOCKET Server -+ GlusterEventsServer() -+ asyncore.loop() -+ -+ -+def main(): -+ try: -+ init_event_server() -+ except KeyboardInterrupt: -+ sys.exit(1) -+ -+ -+if __name__ == "__main__": -+ signal.signal(signal.SIGUSR2, signal_handler_sigusr2) -+ main() -diff --git a/events/src/handlers.py b/events/src/handlers.py -new file mode 100644 -index 0000000..9b756a9 ---- /dev/null -+++ b/events/src/handlers.py -@@ -0,0 +1,21 @@ -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+import utils -+ -+ -+def generic_handler(ts, key, data): -+ """ -+ Generic handler to broadcast message to all peers, custom handlers -+ can be created by func name handler_ -+ Ex: handle_event_volume_create(ts, key, data) -+ """ -+ utils.publish(ts, key, data) -diff --git a/events/src/peer_eventsapi.py b/events/src/peer_eventsapi.py -new file mode 100644 -index 0000000..7887d77 ---- /dev/null -+++ b/events/src/peer_eventsapi.py -@@ -0,0 +1,521 @@ -+#!/usr/bin/env python -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+from __future__ import print_function -+import os -+import json -+from errno import EEXIST -+ -+import requests -+import fasteners -+from prettytable import PrettyTable -+ -+from gluster.cliutils import (Cmd, execute, node_output_ok, node_output_notok, -+ sync_file_to_peers, GlusterCmdException, -+ output_error, execute_in_peers, runcli) -+ -+from events.eventsapiconf import (WEBHOOKS_FILE_TO_SYNC, -+ WEBHOOKS_FILE, -+ DEFAULT_CONFIG_FILE, -+ CUSTOM_CONFIG_FILE, -+ CUSTOM_CONFIG_FILE_TO_SYNC, -+ EVENTSD, -+ CONFIG_KEYS, -+ BOOL_CONFIGS, -+ RESTART_CONFIGS) -+ -+ -+def file_content_overwrite(fname, data): -+ with open(fname + ".tmp", "w") as f: -+ f.write(json.dumps(data)) -+ -+ os.rename(fname + ".tmp", fname) -+ -+ -+def create_custom_config_file_if_not_exists(): -+ mkdirp(os.path.dirname(CUSTOM_CONFIG_FILE)) -+ if not os.path.exists(CUSTOM_CONFIG_FILE): -+ with open(CUSTOM_CONFIG_FILE, "w") as f: -+ f.write("{}") -+ -+ -+def create_webhooks_file_if_not_exists(): -+ mkdirp(os.path.dirname(WEBHOOKS_FILE)) -+ if not os.path.exists(WEBHOOKS_FILE): -+ with open(WEBHOOKS_FILE, "w") as f: -+ f.write("{}") -+ -+ -+def boolify(value): -+ val = False -+ if value.lower() in ["enabled", "true", "on", "yes"]: -+ val = True -+ return val -+ -+ -+def mkdirp(path, exit_on_err=False, logger=None): -+ """ -+ Try creating required directory structure -+ ignore EEXIST and raise exception for rest of the errors. -+ Print error in stderr and exit -+ """ -+ try: -+ os.makedirs(path) -+ except (OSError, IOError) as e: -+ if e.errno == EEXIST and os.path.isdir(path): -+ pass -+ else: -+ output_error("Fail to create dir %s: %s" % (path, e)) -+ -+ -+def is_enabled(service): -+ rc, out, err = execute(["systemctl", "is-enabled", service]) -+ return rc == 0 -+ -+ -+def is_active(service): -+ rc, out, err = execute(["systemctl", "is-active", service]) -+ return rc == 0 -+ -+ -+def enable_service(service): -+ if not is_enabled(service): -+ cmd = ["systemctl", "enable", service] -+ return execute(cmd) -+ -+ return (0, "", "") -+ -+ -+def disable_service(service): -+ if is_enabled(service): -+ cmd = ["systemctl", "disable", service] -+ return execute(cmd) -+ -+ return (0, "", "") -+ -+ -+def start_service(service): -+ rc, out, err = enable_service(service) -+ if rc != 0: -+ return (rc, out, err) -+ -+ cmd = ["systemctl", "start", service] -+ return execute(cmd) -+ -+ -+def stop_service(service): -+ rc, out, err = disable_service(service) -+ if rc != 0: -+ return (rc, out, err) -+ -+ cmd = ["systemctl", "stop", service] -+ return execute(cmd) -+ -+ -+def restart_service(service): -+ rc, out, err = stop_service(service) -+ if rc != 0: -+ return (rc, out, err) -+ -+ return start_service(service) -+ -+ -+def reload_service(service): -+ if is_active(service): -+ cmd = ["systemctl", "reload", service] -+ return execute(cmd) -+ -+ return (0, "", "") -+ -+ -+def sync_to_peers(restart=False): -+ if os.path.exists(WEBHOOKS_FILE): -+ try: -+ sync_file_to_peers(WEBHOOKS_FILE_TO_SYNC) -+ except GlusterCmdException as e: -+ output_error("Failed to sync Webhooks file: [Error: {0}]" -+ "{1}".format(e[0], e[2])) -+ -+ if os.path.exists(CUSTOM_CONFIG_FILE): -+ try: -+ sync_file_to_peers(CUSTOM_CONFIG_FILE_TO_SYNC) -+ except GlusterCmdException as e: -+ output_error("Failed to sync Config file: [Error: {0}]" -+ "{1}".format(e[0], e[2])) -+ -+ action = "node-reload" -+ if restart: -+ action = "node-restart" -+ -+ out = execute_in_peers(action) -+ table = PrettyTable(["NODE", "NODE STATUS", "SYNC STATUS"]) -+ table.align["NODE STATUS"] = "r" -+ table.align["SYNC STATUS"] = "r" -+ -+ for p in out: -+ table.add_row([p.hostname, -+ "UP" if p.node_up else "DOWN", -+ "OK" if p.ok else "NOT OK: {0}".format( -+ p.error)]) -+ -+ print (table) -+ -+ -+def node_output_handle(resp): -+ rc, out, err = resp -+ if rc == 0: -+ node_output_ok(out) -+ else: -+ node_output_notok(err) -+ -+ -+def action_handle(action): -+ out = execute_in_peers("node-" + action) -+ column_name = action.upper() -+ if action == "status": -+ column_name = EVENTSD.upper() -+ -+ table = PrettyTable(["NODE", "NODE STATUS", column_name + " STATUS"]) -+ table.align["NODE STATUS"] = "r" -+ table.align[column_name + " STATUS"] = "r" -+ -+ for p in out: -+ status_col_val = "OK" if p.ok else "NOT OK: {0}".format( -+ p.error) -+ if action == "status": -+ status_col_val = "DOWN" -+ if p.ok: -+ status_col_val = p.output -+ -+ table.add_row([p.hostname, -+ "UP" if p.node_up else "DOWN", -+ status_col_val]) -+ -+ print (table) -+ -+ -+class NodeStart(Cmd): -+ name = "node-start" -+ -+ def run(self, args): -+ node_output_handle(start_service(EVENTSD)) -+ -+ -+class StartCmd(Cmd): -+ name = "start" -+ -+ def run(self, args): -+ action_handle("start") -+ -+ -+class NodeStop(Cmd): -+ name = "node-stop" -+ -+ def run(self, args): -+ node_output_handle(stop_service(EVENTSD)) -+ -+ -+class StopCmd(Cmd): -+ name = "stop" -+ -+ def run(self, args): -+ action_handle("stop") -+ -+ -+class NodeRestart(Cmd): -+ name = "node-restart" -+ -+ def run(self, args): -+ node_output_handle(restart_service(EVENTSD)) -+ -+ -+class RestartCmd(Cmd): -+ name = "restart" -+ -+ def run(self, args): -+ action_handle("restart") -+ -+ -+class NodeReload(Cmd): -+ name = "node-reload" -+ -+ def run(self, args): -+ node_output_handle(reload_service(EVENTSD)) -+ -+ -+class ReloadCmd(Cmd): -+ name = "reload" -+ -+ def run(self, args): -+ action_handle("reload") -+ -+ -+class NodeStatus(Cmd): -+ name = "node-status" -+ -+ def run(self, args): -+ node_output_ok("UP" if is_active(EVENTSD) else "DOWN") -+ -+ -+class StatusCmd(Cmd): -+ name = "status" -+ -+ def run(self, args): -+ webhooks = {} -+ if os.path.exists(WEBHOOKS_FILE): -+ webhooks = json.load(open(WEBHOOKS_FILE)) -+ -+ print ("Webhooks: " + ("" if webhooks else "None")) -+ for w in webhooks: -+ print (w) -+ -+ print () -+ action_handle("status") -+ -+ -+class WebhookAddCmd(Cmd): -+ name = "webhook-add" -+ -+ def args(self, parser): -+ parser.add_argument("url", help="URL of Webhook") -+ parser.add_argument("--bearer_token", "-t", help="Bearer Token", -+ default="") -+ -+ def run(self, args): -+ create_webhooks_file_if_not_exists() -+ -+ with fasteners.InterProcessLock(WEBHOOKS_FILE): -+ data = json.load(open(WEBHOOKS_FILE)) -+ if data.get(args.url, None) is not None: -+ output_error("Webhook already exists") -+ -+ data[args.url] = args.bearer_token -+ file_content_overwrite(WEBHOOKS_FILE, data) -+ -+ sync_to_peers() -+ -+ -+class WebhookModCmd(Cmd): -+ name = "webhook-mod" -+ -+ def args(self, parser): -+ parser.add_argument("url", help="URL of Webhook") -+ parser.add_argument("--bearer_token", "-t", help="Bearer Token", -+ default="") -+ -+ def run(self, args): -+ create_webhooks_file_if_not_exists() -+ -+ with fasteners.InterProcessLock(WEBHOOKS_FILE): -+ data = json.load(open(WEBHOOKS_FILE)) -+ if data.get(args.url, None) is None: -+ output_error("Webhook does not exists") -+ -+ data[args.url] = args.bearer_token -+ file_content_overwrite(WEBHOOKS_FILE, data) -+ -+ sync_to_peers() -+ -+ -+class WebhookDelCmd(Cmd): -+ name = "webhook-del" -+ -+ def args(self, parser): -+ parser.add_argument("url", help="URL of Webhook") -+ -+ def run(self, args): -+ create_webhooks_file_if_not_exists() -+ -+ with fasteners.InterProcessLock(WEBHOOKS_FILE): -+ data = json.load(open(WEBHOOKS_FILE)) -+ if data.get(args.url, None) is None: -+ output_error("Webhook does not exists") -+ -+ del data[args.url] -+ file_content_overwrite(WEBHOOKS_FILE, data) -+ -+ sync_to_peers() -+ -+ -+class NodeWebhookTestCmd(Cmd): -+ name = "node-webhook-test" -+ -+ def args(self, parser): -+ parser.add_argument("url") -+ parser.add_argument("bearer_token") -+ -+ def run(self, args): -+ http_headers = {} -+ if args.bearer_token != ".": -+ http_headers["Authorization"] = "Bearer " + args.bearer_token -+ -+ try: -+ resp = requests.post(args.url, headers=http_headers) -+ except requests.ConnectionError as e: -+ node_output_notok("{0}".format(e)) -+ -+ if resp.status_code != 200: -+ node_output_notok("{0}".format(resp.status_code)) -+ -+ node_output_ok() -+ -+ -+class WebhookTestCmd(Cmd): -+ name = "webhook-test" -+ -+ def args(self, parser): -+ parser.add_argument("url", help="URL of Webhook") -+ parser.add_argument("--bearer_token", "-t", help="Bearer Token") -+ -+ def run(self, args): -+ url = args.url -+ bearer_token = args.bearer_token -+ if not args.url: -+ url = "." -+ if not args.bearer_token: -+ bearer_token = "." -+ -+ out = execute_in_peers("node-webhook-test", [url, bearer_token]) -+ -+ table = PrettyTable(["NODE", "NODE STATUS", "WEBHOOK STATUS"]) -+ table.align["NODE STATUS"] = "r" -+ table.align["WEBHOOK STATUS"] = "r" -+ -+ for p in out: -+ table.add_row([p.hostname, -+ "UP" if p.node_up else "DOWN", -+ "OK" if p.ok else "NOT OK: {0}".format( -+ p.error)]) -+ -+ print (table) -+ -+ -+class ConfigGetCmd(Cmd): -+ name = "config-get" -+ -+ def args(self, parser): -+ parser.add_argument("--name", help="Config Name") -+ -+ def run(self, args): -+ data = json.load(open(DEFAULT_CONFIG_FILE)) -+ if os.path.exists(CUSTOM_CONFIG_FILE): -+ data.update(json.load(open(CUSTOM_CONFIG_FILE))) -+ -+ if args.name is not None and args.name not in CONFIG_KEYS: -+ output_error("Invalid Config item") -+ -+ table = PrettyTable(["NAME", "VALUE"]) -+ if args.name is None: -+ for k, v in data.items(): -+ table.add_row([k, v]) -+ else: -+ table.add_row([args.name, data[args.name]]) -+ -+ print (table) -+ -+ -+def read_file_content_json(fname): -+ content = "{}" -+ with open(fname) as f: -+ content = f.read() -+ if content.strip() == "": -+ content = "{}" -+ -+ return json.loads(content) -+ -+ -+class ConfigSetCmd(Cmd): -+ name = "config-set" -+ -+ def args(self, parser): -+ parser.add_argument("name", help="Config Name") -+ parser.add_argument("value", help="Config Value") -+ -+ def run(self, args): -+ if args.name not in CONFIG_KEYS: -+ output_error("Invalid Config item") -+ -+ with fasteners.InterProcessLock(CUSTOM_CONFIG_FILE): -+ data = json.load(open(DEFAULT_CONFIG_FILE)) -+ if os.path.exists(CUSTOM_CONFIG_FILE): -+ config_json = read_file_content_json(CUSTOM_CONFIG_FILE) -+ data.update(config_json) -+ -+ # Do Nothing if same as previous value -+ if data[args.name] == args.value: -+ return -+ -+ # TODO: Validate Value -+ create_custom_config_file_if_not_exists() -+ new_data = read_file_content_json(CUSTOM_CONFIG_FILE) -+ -+ v = args.value -+ if args.name in BOOL_CONFIGS: -+ v = boolify(args.value) -+ -+ new_data[args.name] = v -+ file_content_overwrite(CUSTOM_CONFIG_FILE, new_data) -+ -+ # If any value changed which requires restart of REST server -+ restart = False -+ if args.name in RESTART_CONFIGS: -+ restart = True -+ -+ sync_to_peers(restart=restart) -+ -+ -+class ConfigResetCmd(Cmd): -+ name = "config-reset" -+ -+ def args(self, parser): -+ parser.add_argument("name", help="Config Name or all") -+ -+ def run(self, args): -+ with fasteners.InterProcessLock(CUSTOM_CONFIG_FILE): -+ changed_keys = [] -+ data = {} -+ if os.path.exists(CUSTOM_CONFIG_FILE): -+ data = read_file_content_json(CUSTOM_CONFIG_FILE) -+ -+ if not data: -+ return -+ -+ if args.name.lower() == "all": -+ for k, v in data.items(): -+ changed_keys.append(k) -+ -+ # Reset all keys -+ file_content_overwrite(CUSTOM_CONFIG_FILE, {}) -+ else: -+ changed_keys.append(args.name) -+ del data[args.name] -+ file_content_overwrite(CUSTOM_CONFIG_FILE, data) -+ -+ # If any value changed which requires restart of REST server -+ restart = False -+ for key in changed_keys: -+ if key in RESTART_CONFIGS: -+ restart = True -+ break -+ -+ sync_to_peers(restart=restart) -+ -+ -+class SyncCmd(Cmd): -+ name = "sync" -+ -+ def run(self, args): -+ sync_to_peers() -+ -+ -+if __name__ == "__main__": -+ runcli() -diff --git a/events/src/utils.py b/events/src/utils.py -new file mode 100644 -index 0000000..772221a ---- /dev/null -+++ b/events/src/utils.py -@@ -0,0 +1,150 @@ -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+import json -+import os -+import logging -+ -+import requests -+from eventsapiconf import (LOG_FILE, -+ WEBHOOKS_FILE, -+ DEFAULT_CONFIG_FILE, -+ CUSTOM_CONFIG_FILE) -+import eventtypes -+ -+from gluster.cliutils import get_node_uuid -+ -+ -+# Webhooks list -+_webhooks = {} -+# Default Log Level -+_log_level = "INFO" -+# Config Object -+_config = {} -+ -+# Init Logger instance -+logger = logging.getLogger(__name__) -+ -+ -+def get_event_type_name(idx): -+ """ -+ Returns Event Type text from the index. For example, VOLUME_CREATE -+ """ -+ return eventtypes.all_events[idx].replace("EVENT_", "") -+ -+ -+def setup_logger(): -+ """ -+ Logging initialization, Log level by default will be INFO, once config -+ file is read, respective log_level will be set. -+ """ -+ global logger -+ logger.setLevel(logging.INFO) -+ -+ # create the logging file handler -+ fh = logging.FileHandler(LOG_FILE) -+ -+ formatter = logging.Formatter("[%(asctime)s] %(levelname)s " -+ "[%(module)s - %(lineno)s:%(funcName)s] " -+ "- %(message)s") -+ -+ fh.setFormatter(formatter) -+ -+ # add handler to logger object -+ logger.addHandler(fh) -+ -+ -+def load_config(): -+ """ -+ Load/Reload the config from REST Config files. This function will -+ be triggered during init and when SIGUSR2. -+ """ -+ global _config -+ _config = {} -+ if os.path.exists(DEFAULT_CONFIG_FILE): -+ _config = json.load(open(DEFAULT_CONFIG_FILE)) -+ if os.path.exists(CUSTOM_CONFIG_FILE): -+ _config.update(json.load(open(CUSTOM_CONFIG_FILE))) -+ -+ -+def load_log_level(): -+ """ -+ Reads log_level from Config file and sets accordingly. This function will -+ be triggered during init and when SIGUSR2. -+ """ -+ global logger, _log_level -+ new_log_level = _config.get("log_level", "INFO") -+ if _log_level != new_log_level: -+ logger.setLevel(getattr(logging, new_log_level.upper())) -+ _log_level = new_log_level.upper() -+ -+ -+def load_webhooks(): -+ """ -+ Load/Reload the webhooks list. This function will -+ be triggered during init and when SIGUSR2. -+ """ -+ global _webhooks -+ _webhooks = {} -+ if os.path.exists(WEBHOOKS_FILE): -+ _webhooks = json.load(open(WEBHOOKS_FILE)) -+ -+ -+def load_all(): -+ """ -+ Wrapper function to call all load/reload functions. This function will -+ be triggered during init and when SIGUSR2. -+ """ -+ load_config() -+ load_webhooks() -+ load_log_level() -+ -+ -+def publish(ts, event_key, data): -+ message = { -+ "nodeid": get_node_uuid(), -+ "ts": int(ts), -+ "event": get_event_type_name(event_key), -+ "message": data -+ } -+ if _webhooks: -+ plugin_webhook(message) -+ else: -+ # TODO: Default action? -+ pass -+ -+ -+def plugin_webhook(message): -+ message_json = json.dumps(message, sort_keys=True) -+ logger.debug("EVENT: {0}".format(message_json)) -+ for url, token in _webhooks.items(): -+ http_headers = {"Content-Type": "application/json"} -+ if token != "" and token is not None: -+ http_headers["Authorization"] = "Bearer " + token -+ -+ try: -+ resp = requests.post(url, headers=http_headers, data=message_json) -+ except requests.ConnectionError as e: -+ logger.warn("Event push failed to URL: {url}, " -+ "Event: {event}, " -+ "Status: {error}".format( -+ url=url, -+ event=message_json, -+ error=e)) -+ continue -+ -+ if resp.status_code != 200: -+ logger.warn("Event push failed to URL: {url}, " -+ "Event: {event}, " -+ "Status Code: {status_code}".format( -+ url=url, -+ event=message_json, -+ status_code=resp.status_code)) -diff --git a/events/tools/Makefile.am b/events/tools/Makefile.am -new file mode 100644 -index 0000000..7d5e331 ---- /dev/null -+++ b/events/tools/Makefile.am -@@ -0,0 +1,3 @@ -+scriptsdir = $(datadir)/glusterfs/scripts -+scripts_SCRIPTS = eventsdash.py -+EXTRA_DIST = eventsdash.py -diff --git a/events/tools/eventsdash.py b/events/tools/eventsdash.py -new file mode 100644 -index 0000000..47fc56d ---- /dev/null -+++ b/events/tools/eventsdash.py -@@ -0,0 +1,74 @@ -+#!/usr/bin/env python -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+from argparse import ArgumentParser, RawDescriptionHelpFormatter -+import logging -+from datetime import datetime -+ -+from flask import Flask, request -+ -+app = Flask(__name__) -+app.logger.disabled = True -+log = logging.getLogger('werkzeug') -+log.disabled = True -+ -+ -+def human_time(ts): -+ return datetime.fromtimestamp(float(ts)).strftime("%Y-%m-%d %H:%M:%S") -+ -+ -+@app.route("/") -+def home(): -+ return "OK" -+ -+ -+@app.route("/listen", methods=["POST"]) -+def listen(): -+ data = request.json -+ if data is None: -+ return "OK" -+ -+ message = [] -+ for k, v in data.get("message", {}).items(): -+ message.append("{0}={1}".format(k, v)) -+ -+ print ("{0:20s} {1:20s} {2:36} {3}".format( -+ human_time(data.get("ts")), -+ data.get("event"), -+ data.get("nodeid"), -+ " ".join(message))) -+ -+ return "OK" -+ -+ -+def main(): -+ parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter, -+ description=__doc__) -+ parser.add_argument("--port", type=int, help="Port", default=9000) -+ parser.add_argument("--debug", help="Run Server in debug mode", -+ action="store_true") -+ args = parser.parse_args() -+ -+ print ("{0:20s} {1:20s} {2:36} {3}".format( -+ "TIMESTAMP", "EVENT", "NODE ID", "MESSAGE" -+ )) -+ print ("{0:20s} {1:20s} {2:36} {3}".format( -+ "-"*20, "-"*20, "-"*36, "-"*20 -+ )) -+ if args.debug: -+ app.debug = True -+ -+ app.run(host="0.0.0.0", port=args.port) -+ -+ -+if __name__ == "__main__": -+ main() -diff --git a/extras/systemd/Makefile.am b/extras/systemd/Makefile.am -index 3f0ec89..5b9b117 100644 ---- a/extras/systemd/Makefile.am -+++ b/extras/systemd/Makefile.am -@@ -1,7 +1,11 @@ --CLEANFILES = glusterd.service --EXTRA_DIST = glusterd.service.in -+CLEANFILES = glusterd.service glustereventsd.service -+EXTRA_DIST = glusterd.service.in glustereventsd.service.in - - if USE_SYSTEMD - # systemddir is already defined through configure.ac - systemd_DATA = glusterd.service -+ -+if BUILD_EVENTS -+systemd_DATA += glustereventsd.service -+endif - endif -diff --git a/extras/systemd/glustereventsd.service.in b/extras/systemd/glustereventsd.service.in -new file mode 100644 -index 0000000..2be3f25 ---- /dev/null -+++ b/extras/systemd/glustereventsd.service.in -@@ -0,0 +1,12 @@ -+[Unit] -+Description=Gluster Events Notifier -+After=syslog.target network.target -+ -+[Service] -+Type=simple -+ExecStart=@SBIN_DIR@/glustereventsd -+ExecReload=/bin/kill -SIGUSR2 $MAINPID -+KillMode=control-group -+ -+[Install] -+WantedBy=multi-user.target -diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 7e40f75..cb90eef 100644 ---- a/glusterfs.spec.in -+++ b/glusterfs.spec.in -@@ -108,6 +108,13 @@ - %global _with_tmpfilesdir --without-tmpfilesdir - %endif - -+# Eventing -+%if 0%{?_build_server} -+%if ( 0%{?rhel} && 0%{?rhel} < 6 ) -+%global _without_events --disable-events -+%endif -+%endif -+ - # From https://fedoraproject.org/wiki/Packaging:Python#Macros - %if ( 0%{?rhel} && 0%{?rhel} <= 5 ) - %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} -@@ -604,6 +611,25 @@ is in user space and easily manageable. - - This package provides the translators needed on any GlusterFS client. - -+%if 0%{?_build_server} -+%if ( 0%{!?_without_events:1} ) -+%package events -+Summary: GlusterFS Events -+Group: Applications/File -+Requires: %{name}-server%{?_isa} = %{version}-%{release} -+Requires: python python-fasteners python-requests python-flask -+Requires: python-prettytable -+Requires: python-gluster = %{version}-%{release} -+%if ( 0%{?rhel} && 0%{?rhel} <= 6 ) -+Requires: python-argparse -+%endif -+ -+%description events -+GlusterFS Events -+ -+%endif -+%endif -+ - %prep - %setup -q -n %{name}-%{version}%{?prereltag} - -@@ -643,7 +669,8 @@ export LDFLAGS - %{?_without_ocf} \ - %{?_without_rdma} \ - %{?_without_syslog} \ -- %{?_without_tiering} -+ %{?_without_tiering} \ -+ %{?_without_events} - - # fix hardening and remove rpath in shlibs - %if ( 0%{?fedora} && 0%{?fedora} > 17 ) || ( 0%{?rhel} && 0%{?rhel} > 6 ) -@@ -963,6 +990,17 @@ exit 0 - %exclude %{_libexecdir}/glusterfs/glusterfind - %exclude %{_bindir}/glusterfind - %exclude %{_libexecdir}/glusterfs/peer_add_secret_pub -+# exclude eventsapi files -+%exclude %{_sysconfdir}/glusterfs/eventsconfig.json -+%exclude %{_sharedstatedir}/glusterd/events -+%exclude %{_libexecdir}/glusterfs/events -+%exclude %{_libexecdir}/glusterfs/peer_eventsapi.py* -+%exclude %{_sbindir}/glustereventsd -+%exclude %{_sbindir}/gluster-eventsapi -+%exclude %{_datadir}/glusterfs/scripts/eventsdash.py* -+%if ( 0%{?_with_systemd:1} ) -+%exclude %{_unitdir}/glustereventsd.service -+%endif - # exclude server files - %exclude %{_sharedstatedir}/glusterd/* - %exclude %{_sysconfdir}/glusterfs -@@ -1349,6 +1387,22 @@ exit 0 - %endif - %endif - -+# Events -+%if 0%{?_build_server} -+%if ( 0%{!?_without_events:1} ) -+%files events -+%config %attr(0600, root, root) %{_sysconfdir}/glusterfs/eventsconfig.json -+%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/events -+%{_libexecdir}/glusterfs/events -+%{_libexecdir}/glusterfs/peer_eventsapi.py* -+%{_sbindir}/glustereventsd -+%{_sbindir}/gluster-eventsapi -+%{_datadir}/glusterfs/scripts/eventsdash.py* -+%if ( 0%{?_with_systemd:1} ) -+%{_unitdir}/glustereventsd.service -+%endif -+%endif -+%endif - - ##----------------------------------------------------------------------------- - ## All %pretrans should be placed here and keep them sorted -@@ -1940,6 +1994,9 @@ end - %endif - - %changelog -+* Thu Sep 15 2016 Aravinda VK -+- Added new subpackage events(glusterfs-events) (#1334044) -+ - * Mon Aug 22 2016 Milind Changire - - Add psmisc as dependency for glusterfs-fuse for killall command (#1367665) - -diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am -index 89c7fa0..54b6194 100644 ---- a/libglusterfs/src/Makefile.am -+++ b/libglusterfs/src/Makefile.am -@@ -72,6 +72,12 @@ libglusterfs_la_SOURCES += $(CONTRIBDIR)/uuid/clear.c \ - $(CONTRIBDIR)/uuid/unpack.c - endif - -+if BUILD_EVENTS -+libglusterfs_la_SOURCES += events.c -+ -+libglusterfs_la_HEADERS += events.h eventtypes.h -+endif -+ - libgfchangelog_HEADERS = changelog.h - - EXTRA_DIST = graph.l graph.y defaults-tmpl.c -diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c -new file mode 100644 -index 0000000..9d78187 ---- /dev/null -+++ b/libglusterfs/src/events.c -@@ -0,0 +1,83 @@ -+/* -+ Copyright (c) 2016 Red Hat, Inc. -+ This file is part of GlusterFS. -+ -+ This file is licensed to you under your choice of the GNU Lesser -+ General Public License, version 3 or any later version (LGPLv3 or -+ later), or the GNU General Public License, version 2 (GPLv2), in all -+ cases as published by the Free Software Foundation. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "syscall.h" -+#include "mem-pool.h" -+#include "events.h" -+ -+int -+gf_event (int event, char *fmt, ...) -+{ -+ int sock = -1; -+ char eventstr[EVENTS_MSG_MAX] = ""; -+ struct sockaddr_un server; -+ va_list arguments; -+ char *msg = NULL; -+ int ret = 0; -+ size_t eventstr_size = 0; -+ -+ if (event < 0 || event >= EVENT_LAST) { -+ ret = EVENT_ERROR_INVALID_INPUTS; -+ goto out; -+ } -+ -+ sock = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (sock < 0) { -+ ret = EVENT_ERROR_SOCKET; -+ goto out; -+ } -+ server.sun_family = AF_UNIX; -+ strcpy(server.sun_path, EVENT_PATH); -+ -+ if (connect(sock, -+ (struct sockaddr *) &server, -+ sizeof(struct sockaddr_un)) < 0) { -+ ret = EVENT_ERROR_CONNECT; -+ goto out; -+ } -+ -+ va_start (arguments, fmt); -+ ret = gf_vasprintf (&msg, fmt, arguments); -+ va_end (arguments); -+ if (ret < 0) { -+ ret = EVENT_ERROR_INVALID_INPUTS; -+ goto out; -+ } -+ -+ eventstr_size = snprintf(NULL, 0, "%u %d %s", (unsigned)time(NULL), -+ event, msg); -+ -+ if (eventstr_size + 1 > EVENTS_MSG_MAX) { -+ eventstr_size = EVENTS_MSG_MAX - 1; -+ } -+ -+ snprintf(eventstr, eventstr_size+1, "%u %d %s", -+ (unsigned)time(NULL), event, msg); -+ -+ if (sys_write(sock, eventstr, strlen(eventstr)) <= 0) { -+ ret = EVENT_ERROR_SEND; -+ goto out; -+ } -+ -+ ret = EVENT_SEND_OK; -+ -+ out: -+ sys_close(sock); -+ GF_FREE(msg); -+ return ret; -+} -diff --git a/libglusterfs/src/events.h.in b/libglusterfs/src/events.h.in -new file mode 100644 -index 0000000..37692be ---- /dev/null -+++ b/libglusterfs/src/events.h.in -@@ -0,0 +1,23 @@ -+/* -+ Copyright (c) 2016 Red Hat, Inc. -+ This file is part of GlusterFS. -+ -+ This file is licensed to you under your choice of the GNU Lesser -+ General Public License, version 3 or any later version (LGPLv3 or -+ later), or the GNU General Public License, version 2 (GPLv2), in all -+ cases as published by the Free Software Foundation. -+*/ -+ -+#ifndef __EVENTS_H__ -+#define __EVENTS_H__ -+ -+#include -+ -+#include "eventtypes.h" -+ -+#define EVENT_PATH "@localstatedir@/run/gluster/events.sock" -+#define EVENTS_MSG_MAX 2048 -+ -+extern int gf_event(int key, char *fmt, ...); -+ -+#endif /* __EVENTS_H__ */ -diff --git a/libglusterfs/src/eventtypes.h b/libglusterfs/src/eventtypes.h -new file mode 100644 -index 0000000..874f8cc ---- /dev/null -+++ b/libglusterfs/src/eventtypes.h -@@ -0,0 +1,22 @@ -+#ifndef __EVENTTYPES_H__ -+#define __EVENTTYPES_H__ -+ -+typedef enum { -+ EVENT_SEND_OK, -+ EVENT_ERROR_INVALID_INPUTS, -+ EVENT_ERROR_SOCKET, -+ EVENT_ERROR_CONNECT, -+ EVENT_ERROR_SEND, -+} event_errors_t; -+ -+typedef enum { -+ EVENT_PEER_ATTACH, -+ EVENT_PEER_DETACH, -+ EVENT_VOLUME_CREATE, -+ EVENT_VOLUME_START, -+ EVENT_VOLUME_STOP, -+ EVENT_VOLUME_DELETE, -+ EVENT_LAST -+} eventtypes_t; -+ -+#endif /* __EVENTTYPES_H__ */ -diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h -index 0cee2ba..cbad737 100644 ---- a/libglusterfs/src/glusterfs.h -+++ b/libglusterfs/src/glusterfs.h -@@ -37,6 +37,10 @@ - #include "lkowner.h" - #include "compat-uuid.h" - -+#if (USE_EVENTS) -+#include "events.h" -+#endif -+ - #define GF_YES 1 - #define GF_NO 0 - --- -1.7.1 - diff --git a/SOURCES/0030-build-make-gf_attach-available-in-glusterfs-server.patch b/SOURCES/0030-build-make-gf_attach-available-in-glusterfs-server.patch new file mode 100644 index 0000000..aa6fd1d --- /dev/null +++ b/SOURCES/0030-build-make-gf_attach-available-in-glusterfs-server.patch @@ -0,0 +1,50 @@ +From 8279b8c5f23cddd1b7db59c56ed2d8896ac49aa7 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Tue, 4 Jul 2017 17:10:27 +0530 +Subject: [PATCH 30/74] build: make gf_attach available in glusterfs-server + +Problem: +gf_attach was erroneously packaged in glusterfs-fuse + +Solution: +move gf_attach listing to server package +add gf_attach to the exclude listing for client builds + +Label: DOWNSTREAM ONLY + +Change-Id: I0de45700badcbab65febf2385f1ac074c44cfa7c +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/111001 +Reviewed-by: Atin Mukherjee +--- + glusterfs.spec.in | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 4596e3f..600fa6e 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1135,6 +1135,7 @@ exit 0 + %exclude %{_sbindir}/gcron.py + %exclude %{_sbindir}/glfsheal + %exclude %{_sbindir}/glusterd ++%exclude %{_sbindir}/gf_attach + %exclude %{_sbindir}/snap_scheduler.py + %exclude %{_datadir}/glusterfs/scripts/stop-all-gluster-processes.sh + %if ( 0%{?_with_systemd:1} ) +@@ -2198,6 +2199,12 @@ end + * Thu Jul 13 2017 Kaleb S. KEITHLEY + - various directories not owned by any package + ++* Tue Jul 04 2017 Milind Changire ++- moved %{_sbindir}/gf_attach from glusterfs-fuse to glusterfs-server ++ ++* Fri Jun 23 2017 Kaleb S. KEITHLEY ++- DOWNSTREAM ONLY remove Requires: selinux-policy for puddle generation ++ + * Wed Jun 21 2017 Jiffin Tony Thottan + - Exclude glusterfssharedstorage.service and mount-shared-storage.sh from client builds + +-- +1.8.3.1 + diff --git a/SOURCES/0030-eventsapi-Fix-make-install-issue-second-time.patch b/SOURCES/0030-eventsapi-Fix-make-install-issue-second-time.patch deleted file mode 100644 index aa2cf39..0000000 --- a/SOURCES/0030-eventsapi-Fix-make-install-issue-second-time.patch +++ /dev/null @@ -1,43 +0,0 @@ -From cc29bde2853e571c685901a3db7966171c4056b9 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Tue, 19 Jul 2016 15:41:54 +0530 -Subject: [PATCH 30/86] eventsapi: Fix make install issue second time - -If Symlink file $SBIN/gluster-eventsapi is not deleted, -make install was failing when run second time(Without uninstall) - -With this patch, Symlink deleted before installing new symlink. - -> Reviewed-on: http://review.gluster.org/14954 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Kotresh HR - -BUG: 1351589 -Change-Id: I65e636f7b48ba9e81177f56c720ffc27e1f95fb3 -Signed-off-by: Aravinda VK - -Reviewed-on: https://code.engineering.redhat.com/gerrit/84736 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - events/src/Makefile.am | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/events/src/Makefile.am b/events/src/Makefile.am -index 528f020..50317d4 100644 ---- a/events/src/Makefile.am -+++ b/events/src/Makefile.am -@@ -15,7 +15,7 @@ install-exec-hook: - rm -f $(DESTDIR)$(sbindir)/glustereventsd - ln -s $(libexecdir)/glusterfs/events/glustereventsd.py \ - $(DESTDIR)$(sbindir)/glustereventsd -- rm -f $(DESTDIR)$(sbindir)/gluster-eventing -+ rm -f $(DESTDIR)$(sbindir)/gluster-eventsapi - ln -s $(libexecdir)/glusterfs/peer_eventsapi.py \ - $(DESTDIR)$(sbindir)/gluster-eventsapi - --- -1.7.1 - diff --git a/SOURCES/0031-eventsapi-Volume-Set-and-Reset-Events.patch b/SOURCES/0031-eventsapi-Volume-Set-and-Reset-Events.patch deleted file mode 100644 index eb7b744..0000000 --- a/SOURCES/0031-eventsapi-Volume-Set-and-Reset-Events.patch +++ /dev/null @@ -1,211 +0,0 @@ -From b39e5538a174b0fd25f6551ed291b9e0a05ca195 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Tue, 19 Jul 2016 17:28:14 +0530 -Subject: [PATCH 31/86] eventsapi: Volume Set and Reset Events - -Example of published data for Volume Set: - -{ - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": "VOLUME_SET", - "message": { - "name": VOLUME_NAME, - "options": [[KEY1, VALUE1], [KEY2, VALUE2],..] - } -} - -Example of published data for Volume Reset: - -{ - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": "VOLUME_RESET", - "message": { - "name": VOLUME_NAME, - "option": KEY - } -} - -> Reviewed-on: http://review.gluster.org/14973 -> NetBSD-regression: NetBSD Build System -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Atin Mukherjee - -BUG: 1351589 -Change-Id: If30cc95396459b2a9993b3412ee6d05d27f6a86a -Signed-off-by: Aravinda VK - -Reviewed-on: https://code.engineering.redhat.com/gerrit/84737 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 62 +++++++++++++++++++++++++++++++++++++++++ - events/eventskeygen.py | 2 + - events/src/eventtypes.py | 2 + - events/src/handlers.py | 19 ++++++++++++ - libglusterfs/src/eventtypes.h | 2 + - 5 files changed, 87 insertions(+), 0 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 5296093..4202622 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -665,6 +665,10 @@ cli_cmd_volume_reset_cbk (struct cli_state *state, struct cli_cmd_word *word, - call_frame_t *frame = NULL; - dict_t *options = NULL; - cli_local_t *local = NULL; -+#if (USE_EVENTS) -+ int ret1 = -1; -+ char *tmp_opt = NULL; -+#endif - - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_VOLUME]; - -@@ -692,6 +696,18 @@ out: - cli_out ("Volume reset failed"); - } - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ ret1 = dict_get_str (options, "key", &tmp_opt); -+ if (ret1) -+ tmp_opt = ""; -+ -+ gf_event (EVENT_VOLUME_RESET, "name=%s;option=%s", -+ (char *)words[2], -+ tmp_opt); -+ } -+#endif -+ - CLI_STACK_DESTROY (frame); - - return ret; -@@ -758,6 +774,15 @@ cli_cmd_volume_set_cbk (struct cli_state *state, struct cli_cmd_word *word, - cli_local_t *local = NULL; - char *op_errstr = NULL; - -+#if (USE_EVENTS) -+ int ret1 = -1; -+ int i = 1; -+ char dict_key[50] = {0,}; -+ char *tmp_opt = NULL; -+ char *opts_str = NULL; -+ int num_options = 0; -+#endif -+ - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SET_VOLUME]; - - frame = create_frame (THIS, THIS->ctx->pool); -@@ -790,6 +815,43 @@ out: - cli_out ("Volume set failed"); - } - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ ret1 = dict_get_int32 (options, "count", &num_options); -+ if (ret1) -+ num_options = 0; -+ else -+ num_options = num_options/2; -+ -+ /* Initialize opts_str */ -+ opts_str = gf_strdup (""); -+ -+ /* Prepare String in format options=KEY1,VALUE1,KEY2,VALUE2 */ -+ for (i = 1; i <= num_options; i++) { -+ sprintf (dict_key, "key%d", i); -+ ret1 = dict_get_str (options, dict_key, &tmp_opt); -+ if (ret1) -+ tmp_opt = ""; -+ -+ gf_asprintf (&opts_str, "%s,%s", opts_str, tmp_opt); -+ -+ sprintf (dict_key, "value%d", i); -+ ret1 = dict_get_str (options, dict_key, &tmp_opt); -+ if (ret1) -+ tmp_opt = ""; -+ -+ gf_asprintf (&opts_str, "%s,%s", opts_str, tmp_opt); -+ } -+ -+ gf_event (EVENT_VOLUME_SET, "name=%s;options=%s", -+ (char *)words[2], -+ opts_str); -+ -+ /* Allocated by gf_strdup and gf_asprintf */ -+ GF_FREE (opts_str); -+ } -+#endif -+ - CLI_STACK_DESTROY (frame); - - return ret; -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 656a7dc..f9bdb9f 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -25,6 +25,8 @@ keys = ( - "EVENT_VOLUME_START", - "EVENT_VOLUME_STOP", - "EVENT_VOLUME_DELETE", -+ "EVENT_VOLUME_SET", -+ "EVENT_VOLUME_RESET", - ) - - LAST_EVENT = "EVENT_LAST" -diff --git a/events/src/eventtypes.py b/events/src/eventtypes.py -index 4812e65..b09e5bc 100644 ---- a/events/src/eventtypes.py -+++ b/events/src/eventtypes.py -@@ -6,4 +6,6 @@ all_events = [ - "EVENT_VOLUME_START", - "EVENT_VOLUME_STOP", - "EVENT_VOLUME_DELETE", -+ "EVENT_VOLUME_SET", -+ "EVENT_VOLUME_RESET", - ] -diff --git a/events/src/handlers.py b/events/src/handlers.py -index 9b756a9..21d3e83 100644 ---- a/events/src/handlers.py -+++ b/events/src/handlers.py -@@ -19,3 +19,22 @@ def generic_handler(ts, key, data): - Ex: handle_event_volume_create(ts, key, data) - """ - utils.publish(ts, key, data) -+ -+ -+def handle_event_volume_set(ts, key, data): -+ """ -+ Recieved data will have all the options as one string, split into -+ list of options. "key1,value1,key2,value2" into -+ [[key1, value1], [key2, value2]] -+ """ -+ opts = data.get("options", "").strip(",").split(",") -+ data["options"] = [] -+ for i, opt in enumerate(opts): -+ if i % 2 == 0: -+ # Add new array with key -+ data["options"].append([opt]) -+ else: -+ # Add to the last added array -+ data["options"][-1].append(opt) -+ -+ utils.publish(ts, key, data) -diff --git a/libglusterfs/src/eventtypes.h b/libglusterfs/src/eventtypes.h -index 874f8cc..20c4b02 100644 ---- a/libglusterfs/src/eventtypes.h -+++ b/libglusterfs/src/eventtypes.h -@@ -16,6 +16,8 @@ typedef enum { - EVENT_VOLUME_START, - EVENT_VOLUME_STOP, - EVENT_VOLUME_DELETE, -+ EVENT_VOLUME_SET, -+ EVENT_VOLUME_RESET, - EVENT_LAST - } eventtypes_t; - --- -1.7.1 - diff --git a/SOURCES/0031-glusterd-Revert-op-version-for-cluster.max-brick-per.patch b/SOURCES/0031-glusterd-Revert-op-version-for-cluster.max-brick-per.patch new file mode 100644 index 0000000..6ee34e5 --- /dev/null +++ b/SOURCES/0031-glusterd-Revert-op-version-for-cluster.max-brick-per.patch @@ -0,0 +1,37 @@ +From e1f21c716b9a9f245e8ad2c679fb12fd86c8655e Mon Sep 17 00:00:00 2001 +From: Samikshan Bairagya +Date: Mon, 10 Jul 2017 11:54:52 +0530 +Subject: [PATCH 31/74] glusterd: Revert op-version for + "cluster.max-brick-per-process" + +The op-version for the "cluster.max-brick-per-process" option was +set to 3.12.0 in the upstream patch and was backported here: +https://code.engineering.redhat.com/gerrit/#/c/111799. This commit +reverts the op-version for this option to 3.11.1 instead. + +Label: DOWNSTREAM ONLY + +Change-Id: I23639cef43d41915eea0394d019b1e0796a99d7b +Signed-off-by: Samikshan Bairagya +Reviewed-on: https://code.engineering.redhat.com/gerrit/111804 +Reviewed-by: Atin Mukherjee +--- + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +index 9729767..2210b82 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +@@ -3449,7 +3449,7 @@ struct volopt_map_entry glusterd_volopt_map[] = { + { .key = GLUSTERD_BRICKMUX_LIMIT_KEY, + .voltype = "mgmt/glusterd", + .value = "0", +- .op_version = GD_OP_VERSION_3_12_0, ++ .op_version = GD_OP_VERSION_3_11_1, + .validate_fn = validate_mux_limit, + .type = GLOBAL_DOC, + .description = "This option can be used to limit the number of brick " +-- +1.8.3.1 + diff --git a/SOURCES/0032-cli-Add-message-for-user-before-modifying-brick-mult.patch b/SOURCES/0032-cli-Add-message-for-user-before-modifying-brick-mult.patch new file mode 100644 index 0000000..a4faa77 --- /dev/null +++ b/SOURCES/0032-cli-Add-message-for-user-before-modifying-brick-mult.patch @@ -0,0 +1,56 @@ +From 472aebd90fb081db85b00491ce7034a9b971f4e1 Mon Sep 17 00:00:00 2001 +From: Samikshan Bairagya +Date: Wed, 9 Aug 2017 14:32:59 +0530 +Subject: [PATCH 32/74] cli: Add message for user before modifying + brick-multiplex option + +Users should ne notified that brick-multiplexing feature is +supported only for container workloads (CNS/CRS). It should also be +made known to users that it is advisable to either have all volumes +in stopped state or have no bricks running before modifying the +"brick-multiplex" option. This commit makes sure these messages +are displayed to the user before brick-multiplexing is enabled or +disabled. + +Label: DOWNSTREAM ONLY + +Change-Id: Ic40294b26c691ea03185c4d1fce840ef23f95718 +Signed-off-by: Samikshan Bairagya +Reviewed-on: https://code.engineering.redhat.com/gerrit/114793 +Reviewed-by: Atin Mukherjee +--- + cli/src/cli-cmd-parser.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c +index ca4d906..216e050 100644 +--- a/cli/src/cli-cmd-parser.c ++++ b/cli/src/cli-cmd-parser.c +@@ -1621,6 +1621,24 @@ cli_cmd_volume_set_parse (struct cli_state *state, const char **words, + goto out; + } + } ++ ++ if ((strcmp (key, "cluster.brick-multiplex") == 0)) { ++ question = "Brick-multiplexing is supported only for " ++ "container workloads (CNS/CRS). Also it is " ++ "advised to make sure that either all " ++ "volumes are in stopped state or no bricks " ++ "are running before this option is modified." ++ "Do you still want to continue?"; ++ ++ answer = cli_cmd_get_confirmation (state, question); ++ if (GF_ANSWER_NO == answer) { ++ gf_log ("cli", GF_LOG_ERROR, "Operation " ++ "cancelled, exiting"); ++ *op_errstr = gf_strdup ("Aborted by user."); ++ ret = -1; ++ goto out; ++ } ++ } + } + + ret = dict_set_int32 (dict, "count", wordcount-3); +-- +1.8.3.1 + diff --git a/SOURCES/0032-eventsapi-Auto-generate-header-files-during-make.patch b/SOURCES/0032-eventsapi-Auto-generate-header-files-during-make.patch deleted file mode 100644 index 1806f50..0000000 --- a/SOURCES/0032-eventsapi-Auto-generate-header-files-during-make.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 69442f05acf98130df16f1311edd704d4e937ac3 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Thu, 28 Jul 2016 15:49:59 +0530 -Subject: [PATCH 32/79] eventsapi: Auto generate header files during make - -$SRC/libglusterfs/src/eventtypes.h and $SRC/events/src/eventtypes.py are -generated by running `python $SRC/events/eventskeygen.py` - -Header files generation step is added to make file itself, Now All new -events should be added to only to $SRC/events/eventskeygen.py file. - -> Reviewed-on: http://review.gluster.org/15035 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Kotresh HR -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Atin Mukherjee - -BUG: 1351589 -Change-Id: I384961ef2978ca2d0be37f288b39ac0d834bdf06 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84738 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - events/eventskeygen.py | 49 ++++++++++++++++++++++------------------ - events/src/Makefile.am | 9 ++++++- - events/src/eventtypes.py | 11 --------- - libglusterfs/src/Makefile.am | 10 +++++++- - libglusterfs/src/eventtypes.h | 24 -------------------- - 6 files changed, 46 insertions(+), 59 deletions(-) - delete mode 100644 events/src/eventtypes.py - delete mode 100644 libglusterfs/src/eventtypes.h - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index f9bdb9f..5bb0319 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -11,11 +11,14 @@ - # - - import os -+import sys - - GLUSTER_SRC_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - eventtypes_h = os.path.join(GLUSTER_SRC_ROOT, "libglusterfs/src/eventtypes.h") - eventtypes_py = os.path.join(GLUSTER_SRC_ROOT, "events/src/eventtypes.py") - -+gen_header_type = sys.argv[1] -+ - # When adding new keys add it to the END - keys = ( - "EVENT_PEER_ATTACH", -@@ -39,29 +42,31 @@ ERRORS = ( - "EVENT_ERROR_SEND" - ) - --# Generate eventtypes.h --with open(eventtypes_h, "w") as f: -- f.write("#ifndef __EVENTTYPES_H__\n") -- f.write("#define __EVENTTYPES_H__\n\n") -- f.write("typedef enum {\n") -- for k in ERRORS: -- f.write(" {0},\n".format(k)) -- f.write("} event_errors_t;\n") -+if gen_header_type == "C_HEADER": -+ # Generate eventtypes.h -+ with open(eventtypes_h, "w") as f: -+ f.write("#ifndef __EVENTTYPES_H__\n") -+ f.write("#define __EVENTTYPES_H__\n\n") -+ f.write("typedef enum {\n") -+ for k in ERRORS: -+ f.write(" {0},\n".format(k)) -+ f.write("} event_errors_t;\n") - -- f.write("\n") -+ f.write("\n") - -- f.write("typedef enum {\n") -- for k in keys: -- f.write(" {0},\n".format(k)) -+ f.write("typedef enum {\n") -+ for k in keys: -+ f.write(" {0},\n".format(k)) - -- f.write(" {0}\n".format(LAST_EVENT)) -- f.write("} eventtypes_t;\n") -- f.write("\n#endif /* __EVENTTYPES_H__ */\n") -+ f.write(" {0}\n".format(LAST_EVENT)) -+ f.write("} eventtypes_t;\n") -+ f.write("\n#endif /* __EVENTTYPES_H__ */\n") - --# Generate eventtypes.py --with open(eventtypes_py, "w") as f: -- f.write("# -*- coding: utf-8 -*-\n") -- f.write("all_events = [\n") -- for ev in keys: -- f.write(' "{0}",\n'.format(ev)) -- f.write("]\n") -+if gen_header_type == "PY_HEADER": -+ # Generate eventtypes.py -+ with open(eventtypes_py, "w") as f: -+ f.write("# -*- coding: utf-8 -*-\n") -+ f.write("all_events = [\n") -+ for ev in keys: -+ f.write(' "{0}",\n'.format(ev)) -+ f.write("]\n") -diff --git a/events/src/Makefile.am b/events/src/Makefile.am -index 50317d4..8b2150e 100644 ---- a/events/src/Makefile.am -+++ b/events/src/Makefile.am -@@ -1,6 +1,10 @@ --EXTRA_DIST = glustereventsd.py __init__.py eventsapiconf.py.in eventtypes.py \ -+noinst_PYTHON = $(top_srcdir)/events/eventskeygen.py -+EXTRA_DIST = glustereventsd.py __init__.py eventsapiconf.py.in \ - handlers.py utils.py peer_eventsapi.py eventsconfig.json - -+BUILT_SOURCES = eventtypes.py -+CLEANFILES = eventtypes.py -+ - eventsdir = $(libexecdir)/glusterfs/events - eventspeerscriptdir = $(libexecdir)/glusterfs - eventsconfdir = $(sysconfdir)/glusterfs -@@ -10,6 +14,9 @@ events_PYTHON = __init__.py eventsapiconf.py eventtypes.py handlers.py utils.py - events_SCRIPTS = glustereventsd.py - eventspeerscript_SCRIPTS = peer_eventsapi.py - -+eventtypes.py: $(top_srcdir)/events/eventskeygen.py -+ $(PYTHON) $(top_srcdir)/events/eventskeygen.py PY_HEADER -+ - install-exec-hook: - $(mkdir_p) $(DESTDIR)$(sbindir) - rm -f $(DESTDIR)$(sbindir)/glustereventsd -diff --git a/events/src/eventtypes.py b/events/src/eventtypes.py -deleted file mode 100644 -index b09e5bc..0000000 ---- a/events/src/eventtypes.py -+++ /dev/null -@@ -1,11 +0,0 @@ --# -*- coding: utf-8 -*- --all_events = [ -- "EVENT_PEER_ATTACH", -- "EVENT_PEER_DETACH", -- "EVENT_VOLUME_CREATE", -- "EVENT_VOLUME_START", -- "EVENT_VOLUME_STOP", -- "EVENT_VOLUME_DELETE", -- "EVENT_VOLUME_SET", -- "EVENT_VOLUME_RESET", --] -diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am -index 54b6194..66369e2 100644 ---- a/libglusterfs/src/Makefile.am -+++ b/libglusterfs/src/Makefile.am -@@ -1,4 +1,4 @@ --noinst_PYTHON = generator.py gen-defaults.py -+noinst_PYTHON = generator.py gen-defaults.py $(top_srcdir)/events/eventskeygen.py - - libglusterfs_la_CFLAGS = $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \ - -DDATADIR=\"$(localstatedir)\" -@@ -73,9 +73,13 @@ libglusterfs_la_SOURCES += $(CONTRIBDIR)/uuid/clear.c \ - endif - - if BUILD_EVENTS -+BUILT_SOURCES += eventtypes.h - libglusterfs_la_SOURCES += events.c - - libglusterfs_la_HEADERS += events.h eventtypes.h -+ -+eventtypes.h: $(top_srcdir)/events/eventskeygen.py -+ $(PYTHON) $(top_srcdir)/events/eventskeygen.py C_HEADER - endif - - libgfchangelog_HEADERS = changelog.h -@@ -111,3 +115,7 @@ CLEANFILES += *.gcda *.gcno *_xunit.xml - noinst_PROGRAMS = - TESTS = - endif -+ -+if BUILD_EVENTS -+CLEANFILES += eventtypes.h -+endif -diff --git a/libglusterfs/src/eventtypes.h b/libglusterfs/src/eventtypes.h -deleted file mode 100644 -index 20c4b02..0000000 ---- a/libglusterfs/src/eventtypes.h -+++ /dev/null -@@ -1,24 +0,0 @@ --#ifndef __EVENTTYPES_H__ --#define __EVENTTYPES_H__ -- --typedef enum { -- EVENT_SEND_OK, -- EVENT_ERROR_INVALID_INPUTS, -- EVENT_ERROR_SOCKET, -- EVENT_ERROR_CONNECT, -- EVENT_ERROR_SEND, --} event_errors_t; -- --typedef enum { -- EVENT_PEER_ATTACH, -- EVENT_PEER_DETACH, -- EVENT_VOLUME_CREATE, -- EVENT_VOLUME_START, -- EVENT_VOLUME_STOP, -- EVENT_VOLUME_DELETE, -- EVENT_VOLUME_SET, -- EVENT_VOLUME_RESET, -- EVENT_LAST --} eventtypes_t; -- --#endif /* __EVENTTYPES_H__ */ --- -1.7.1 - diff --git a/SOURCES/0033-build-launch-glusterd-upgrade-after-all-new-bits-are.patch b/SOURCES/0033-build-launch-glusterd-upgrade-after-all-new-bits-are.patch new file mode 100644 index 0000000..700f1d7 --- /dev/null +++ b/SOURCES/0033-build-launch-glusterd-upgrade-after-all-new-bits-are.patch @@ -0,0 +1,114 @@ +From 1ce0b65090c888b0e2b28cab03731674f4988aeb Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Tue, 10 Oct 2017 09:58:24 +0530 +Subject: [PATCH 33/74] build: launch glusterd upgrade after all new bits are + installed + +Problem: +glusterd upgrade mode needs new bits from glusterfs-rdma which +optional and causes the dependency graph to break since it is +not tied into glusterfs-server requirements + +Solution: +Run glusterd upgrade mode after all new bits are installed +i.e. in %posttrans server section + +Label: DOWNSTREAM ONLY + +Change-Id: I356e02d0bf0eaaef43c20ce07b388262f63093a4 +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/120094 +Reviewed-by: Atin Mukherjee +Tested-by: RHGS Build Bot +Reviewed-by: Raghavendra Talur +--- + glusterfs.spec.in | 56 ++++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 35 insertions(+), 21 deletions(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 600fa6e..f4386de 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -963,27 +963,6 @@ fi + %firewalld_reload + %endif + +-pidof -c -o %PPID -x glusterd &> /dev/null +-if [ $? -eq 0 ]; then +- kill -9 `pgrep -f gsyncd.py` &> /dev/null +- +- killall --wait glusterd &> /dev/null +- glusterd --xlator-option *.upgrade=on -N +- +- #Cleaning leftover glusterd socket file which is created by glusterd in +- #rpm_script_t context. +- rm -f %{_rundir}/glusterd.socket +- +- # glusterd _was_ running, we killed it, it exited after *.upgrade=on, +- # so start it again +- %_init_start glusterd +-else +- glusterd --xlator-option *.upgrade=on -N +- +- #Cleaning leftover glusterd socket file which is created by glusterd in +- #rpm_script_t context. +- rm -f %{_rundir}/glusterd.socket +-fi + %endif + + ##----------------------------------------------------------------------------- +@@ -2166,6 +2145,35 @@ os.remove(tmpname) + if not (ok == 0) then + error("Detected running glusterfs processes", ok) + end ++ ++%posttrans server ++pidof -c -o %PPID -x glusterd &> /dev/null ++if [ $? -eq 0 ]; then ++ kill -9 `pgrep -f gsyncd.py` &> /dev/null ++ ++ killall --wait -SIGTERM glusterd &> /dev/null ++ ++ if [ "$?" != "0" ]; then ++ echo "killall failed while killing glusterd" ++ fi ++ ++ glusterd --xlator-option *.upgrade=on -N ++ ++ #Cleaning leftover glusterd socket file which is created by glusterd in ++ #rpm_script_t context. ++ rm -rf /var/run/glusterd.socket ++ ++ # glusterd _was_ running, we killed it, it exited after *.upgrade=on, ++ # so start it again ++ %_init_start glusterd ++else ++ glusterd --xlator-option *.upgrade=on -N ++ ++ #Cleaning leftover glusterd socket file which is created by glusterd in ++ #rpm_script_t context. ++ rm -rf /var/run/glusterd.socket ++fi ++ + %endif + + # Events +@@ -2190,9 +2198,15 @@ end + %endif + + %changelog ++* Tue Oct 10 2017 Milind Changire ++- DOWNSTREAM ONLY patch - launch glusterd in upgrade mode after all new bits have been installed ++ + * Tue Aug 22 2017 Kaleb S. KEITHLEY + - libibverbs-devel, librdmacm-devel -> rdma-core-devel #1483996 + ++* Fri Aug 04 2017 Kaleb S. KEITHLEY ++- /var/lib/glusterd/options made config(noreplace) to avoid losing shared state info ++ + * Thu Jul 20 2017 Aravinda VK + - Added new tool/binary to set the gfid2path xattr on files + +-- +1.8.3.1 + diff --git a/SOURCES/0033-eventsapi-Geo-replication-User-driven-events.patch b/SOURCES/0033-eventsapi-Geo-replication-User-driven-events.patch deleted file mode 100644 index 4654d82..0000000 --- a/SOURCES/0033-eventsapi-Geo-replication-User-driven-events.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 73effb9f22fad8ee6084521c62566b5b4a46792c Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Wed, 3 Aug 2016 12:16:43 +0530 -Subject: [PATCH 33/86] eventsapi: Geo-replication User driven events - -Following Geo-replication Events are added - -GEOREP_CREATE/GEOREP_START/GEOREP_STOP/GEOREP_DELETE/GEOREP_PAUSE/GEOREP_RESUME - { - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": EVENT_TYPE, - "message": { - "master": MASTER_VOLUME_NAME, - "slave": SLAVE_DETAILS - } - } - -GEOREP_CONFIG_SET - { - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": GEOREP_CONFIG_SET, - "message": { - "master": MASTER_VOLUME_NAME, - "slave": SLAVE_DETAILS, - "option": OPTION_NAME, - "value": OPTION_VALUE - } - } - -GEOREP_CONFIG_RESET - { - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": GEOREP_CONFIG_RESET, - "message": { - "master": MASTER_VOLUME_NAME, - "slave": SLAVE_DETAILS, - "option": OPTION_NAME - } - } - -> Reviewed-on: http://review.gluster.org/15077 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Kotresh HR - -BUG: 1361118 -Change-Id: I78c81aabd022ebb042b3eae3c6b5a284a6c2801f -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84739 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++ - events/eventskeygen.py | 9 +++ - 2 files changed, 134 insertions(+), 0 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 4202622..7e53514 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -1958,6 +1958,14 @@ cli_cmd_volume_gsync_set_cbk (struct cli_state *state, struct cli_cmd_word *word - rpc_clnt_procedure_t *proc = NULL; - call_frame_t *frame = NULL; - cli_local_t *local = NULL; -+#if (USE_EVENTS) -+ int ret1 = -1; -+ int cmd_type = -1; -+ int tmpi = 0; -+ char *tmp = NULL; -+ char *events_str = NULL; -+ int event_type = -1; -+#endif - - proc = &cli_rpc_prog->proctable [GLUSTER_CLI_GSYNC_SET]; - -@@ -1983,6 +1991,123 @@ out: - if (ret && parse_err == 0) - cli_out (GEOREP" command failed"); - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ events_str = gf_strdup (""); -+ -+ /* Type of Geo-rep Action - Create, Start etc */ -+ ret1 = dict_get_int32 (options, "type", &cmd_type); -+ if (ret1) -+ cmd_type = -1; -+ -+ /* Only capture Events for modification commands */ -+ switch (cmd_type) { -+ case GF_GSYNC_OPTION_TYPE_CREATE: -+ event_type = EVENT_GEOREP_CREATE; -+ break; -+ case GF_GSYNC_OPTION_TYPE_START: -+ event_type = EVENT_GEOREP_START; -+ break; -+ case GF_GSYNC_OPTION_TYPE_STOP: -+ event_type = EVENT_GEOREP_STOP; -+ break; -+ case GF_GSYNC_OPTION_TYPE_PAUSE: -+ event_type = EVENT_GEOREP_PAUSE; -+ break; -+ case GF_GSYNC_OPTION_TYPE_RESUME: -+ event_type = EVENT_GEOREP_RESUME; -+ break; -+ case GF_GSYNC_OPTION_TYPE_DELETE: -+ event_type = EVENT_GEOREP_DELETE; -+ break; -+ case GF_GSYNC_OPTION_TYPE_CONFIG: -+ ret1 = dict_get_str (options, "subop", &tmp); -+ if (ret1) -+ tmp = ""; -+ -+ /* For Config Set additionally capture key and value */ -+ /* For Config Reset capture key */ -+ if (strcmp (tmp, "set") == 0) { -+ event_type = EVENT_GEOREP_CONFIG_SET; -+ -+ ret1 = dict_get_str (options, "op_name", &tmp); -+ if (ret1) -+ tmp = ""; -+ -+ gf_asprintf (&events_str, "%soption=%s;", -+ events_str, tmp); -+ -+ ret1 = dict_get_str (options, "op_value", &tmp); -+ if (ret1) -+ tmp = ""; -+ -+ gf_asprintf (&events_str, "%svalue=%s;", -+ events_str, tmp); -+ } else if (strcmp (tmp, "del") == 0) { -+ event_type = EVENT_GEOREP_CONFIG_RESET; -+ -+ ret1 = dict_get_str (options, "op_name", &tmp); -+ if (ret1) -+ tmp = ""; -+ -+ gf_asprintf (&events_str, "%soption=%s;", -+ events_str, tmp); -+ } -+ break; -+ default: -+ break; -+ } -+ -+ if (event_type > -1) { -+ /* Capture all optional arguments used */ -+ ret1 = dict_get_int32 (options, "force", &tmpi); -+ if (ret1 == 0) -+ gf_asprintf (&events_str, "%sforce=%d;", -+ events_str, tmpi); -+ -+ ret1 = dict_get_int32 (options, "push_pem", &tmpi); -+ if (ret1 == 0) -+ gf_asprintf (&events_str, "%spush_pem=%d;", -+ events_str, tmpi); -+ -+ ret1 = dict_get_int32 (options, "no_verify", &tmpi); -+ if (ret1 == 0) -+ gf_asprintf (&events_str, "%sno_verify=%d;", -+ events_str, tmpi); -+ -+ ret1 = dict_get_int32 (options, "ssh_port", &tmpi); -+ if (ret1 == 0) -+ gf_asprintf (&events_str, "%sssh_port=%d;", -+ events_str, tmpi); -+ -+ ret1 = dict_get_int32 (options, "reset-sync-time", -+ &tmpi); -+ if (ret1 == 0) -+ gf_asprintf (&events_str, -+ "%sreset_sync_time=%d;", -+ events_str, tmpi); -+ -+ /* Capture Master and Slave Info */ -+ ret1 = dict_get_str (options, "master", &tmp); -+ if (ret1) -+ tmp = ""; -+ gf_asprintf (&events_str, "%smaster=%s;", -+ events_str, tmp); -+ -+ ret1 = dict_get_str (options, "slave", &tmp); -+ if (ret1) -+ tmp = ""; -+ gf_asprintf (&events_str, "%sslave=%s", -+ events_str, tmp); -+ -+ gf_event (event_type, "%s", events_str); -+ } -+ -+ /* Allocated by gf_strdup and gf_asprintf */ -+ GF_FREE (events_str); -+ } -+#endif -+ - CLI_STACK_DESTROY (frame); - - return ret; -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 5bb0319..bccb91a 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -30,6 +30,15 @@ keys = ( - "EVENT_VOLUME_DELETE", - "EVENT_VOLUME_SET", - "EVENT_VOLUME_RESET", -+ -+ "EVENT_GEOREP_CREATE", -+ "EVENT_GEOREP_START", -+ "EVENT_GEOREP_STOP", -+ "EVENT_GEOREP_PAUSE", -+ "EVENT_GEOREP_RESUME", -+ "EVENT_GEOREP_DELETE", -+ "EVENT_GEOREP_CONFIG_SET", -+ "EVENT_GEOREP_CONFIG_RESET", - ) - - LAST_EVENT = "EVENT_LAST" --- -1.7.1 - diff --git a/SOURCES/0034-build-remove-pretrans-script-for-python-gluster.patch b/SOURCES/0034-build-remove-pretrans-script-for-python-gluster.patch new file mode 100644 index 0000000..8f0aa31 --- /dev/null +++ b/SOURCES/0034-build-remove-pretrans-script-for-python-gluster.patch @@ -0,0 +1,76 @@ +From 58e52a8862aff553a883ee8b554f38baa2bda9a6 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Tue, 7 Nov 2017 18:32:59 +0530 +Subject: [PATCH 34/74] build: remove pretrans script for python-gluster + +Remove pretrans scriptlet for python-gluster. + +Label: DOWNSTREAM ONLY + +Change-Id: Iee006354c596aedbd70438a3bdd583de28837190 +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/122556 +Reviewed-by: Prashanth Pai +Reviewed-by: Aravinda Vishwanathapura Krishna Murthy +Reviewed-by: Atin Mukherjee +Tested-by: RHGS Build Bot +--- + glusterfs.spec.in | 42 ------------------------------------------ + 1 file changed, 42 deletions(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index f4386de..8c16477 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1976,48 +1976,6 @@ end + + + +-%pretrans -n python-gluster -p +-if not posix.access("/bin/bash", "x") then +- -- initial installation, no shell, no running glusterfsd +- return 0 +-end +- +--- TODO: move this completely to a lua script +--- For now, we write a temporary bash script and execute that. +- +-script = [[#!/bin/sh +-pidof -c -o %PPID -x glusterfsd &>/dev/null +- +-if [ $? -eq 0 ]; then +- pushd . > /dev/null 2>&1 +- for volume in /var/lib/glusterd/vols/*; do cd $volume; +- vol_type=`grep '^type=' info | awk -F'=' '{print $2}'` +- volume_started=`grep '^status=' info | awk -F'=' '{print $2}'` +- if [ $vol_type -eq 0 ] && [ $volume_started -eq 1 ] ; then +- exit 1; +- fi +- done +- +- popd > /dev/null 2>&1 +- exit 1; +-fi +-]] +- +--- Since we run pretrans scripts only for RPMs built for a server build, +--- we can now use os.tmpname() since it is available on RHEL6 and later +--- platforms which are server platforms. +-tmpname = os.tmpname() +-tmpfile = io.open(tmpname, "w") +-tmpfile:write(script) +-tmpfile:close() +-ok, how, val = os.execute("/bin/bash " .. tmpname) +-os.remove(tmpname) +-if not (ok == 0) then +- error("Detected running glusterfs processes", ok) +-end +- +- +- + %if ( 0%{!?_without_rdma:1} ) + %pretrans rdma -p + if not posix.access("/bin/bash", "x") then +-- +1.8.3.1 + diff --git a/SOURCES/0034-eventsapi-Python-library-for-gf_event.patch b/SOURCES/0034-eventsapi-Python-library-for-gf_event.patch deleted file mode 100644 index 2d762cb..0000000 --- a/SOURCES/0034-eventsapi-Python-library-for-gf_event.patch +++ /dev/null @@ -1,139 +0,0 @@ -From bc6fac6847c3fe2db021e6a0bbe8d55dc24487af Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Mon, 1 Aug 2016 17:16:50 +0530 -Subject: [PATCH 34/86] eventsapi: Python library for gf_event - -Python library to emit Events from Geo-replication or any other Python apps -running in storage nodes. - -Add $LIBEXEC/glusterfs/events to Python path to use gf_event - -gf_event(event_type, **kwargs) - -For example, - - sys.path.insert(1, "LIBEXECDIR/glusterfs") - from events.gf_event import gf_event - from events import eventtypes - - gf_event(eventtypes.GEOREP_FAULTY, - volname="gv1", - slaveuser="root", - slavehost="node1", - slavevol="gv2") - -Errors will be logged in $LOGDIR/glusterfs/events.log - -> Reviewed-on: http://review.gluster.org/15063 -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Samikshan Bairagya -> Reviewed-by: Prashanth Pai - -BUG: 1351589 -Change-Id: I2af2bd77f9961975e4387006b9e99e4543e12b57 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84740 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - events/eventskeygen.py | 6 +++++- - events/src/Makefile.am | 5 +++-- - events/src/gf_event.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 56 insertions(+), 3 deletions(-) - create mode 100644 events/src/gf_event.py - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index bccb91a..7357d8e 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -78,4 +78,8 @@ if gen_header_type == "PY_HEADER": - f.write("all_events = [\n") - for ev in keys: - f.write(' "{0}",\n'.format(ev)) -- f.write("]\n") -+ -+ f.write("]\n\n") -+ -+ for idx, ev in enumerate(keys): -+ f.write("{0} = {1}\n".format(ev.replace("EVENT_", ""), idx)) -diff --git a/events/src/Makefile.am b/events/src/Makefile.am -index 8b2150e..423bc88 100644 ---- a/events/src/Makefile.am -+++ b/events/src/Makefile.am -@@ -1,6 +1,6 @@ - noinst_PYTHON = $(top_srcdir)/events/eventskeygen.py - EXTRA_DIST = glustereventsd.py __init__.py eventsapiconf.py.in \ -- handlers.py utils.py peer_eventsapi.py eventsconfig.json -+ handlers.py utils.py peer_eventsapi.py eventsconfig.json gf_event.py - - BUILT_SOURCES = eventtypes.py - CLEANFILES = eventtypes.py -@@ -10,7 +10,8 @@ eventspeerscriptdir = $(libexecdir)/glusterfs - eventsconfdir = $(sysconfdir)/glusterfs - eventsconf_DATA = eventsconfig.json - --events_PYTHON = __init__.py eventsapiconf.py eventtypes.py handlers.py utils.py -+events_PYTHON = __init__.py eventsapiconf.py eventtypes.py handlers.py \ -+ utils.py gf_event.py - events_SCRIPTS = glustereventsd.py - eventspeerscript_SCRIPTS = peer_eventsapi.py - -diff --git a/events/src/gf_event.py b/events/src/gf_event.py -new file mode 100644 -index 0000000..0924a65 ---- /dev/null -+++ b/events/src/gf_event.py -@@ -0,0 +1,48 @@ -+#!/usr/bin/env python -+# -*- coding: utf-8 -*- -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+# -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+import socket -+import time -+ -+from eventsapiconf import SERVER_ADDRESS -+from eventtypes import all_events -+ -+from utils import logger, setup_logger -+ -+# Run this when this lib loads -+setup_logger() -+ -+ -+def gf_event(event_type, **kwargs): -+ if not isinstance(event_type, int) or event_type >= len(all_events): -+ logger.error("Invalid Event Type: {0}".format(event_type)) -+ return -+ -+ try: -+ client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -+ client.connect(SERVER_ADDRESS) -+ except socket.error as e: -+ logger.error("Unable to connect to events.sock: {0}".format(e)) -+ return -+ -+ # Convert key value args into KEY1=VALUE1;KEY2=VALUE2;.. -+ msg = "" -+ for k, v in kwargs.items(): -+ msg += "{0}={1};".format(k, v) -+ -+ # -+ msg = "{0} {1} {2}".format(int(time.time()), event_type, msg.strip(";")) -+ -+ try: -+ client.sendall(msg) -+ except socket.error as e: -+ logger.error("Unable to Send message: {0}".format(e)) --- -1.7.1 - diff --git a/SOURCES/0035-events-move-conditional-macro-check-USE_EVENTS-insid.patch b/SOURCES/0035-events-move-conditional-macro-check-USE_EVENTS-insid.patch deleted file mode 100644 index 4efdc03..0000000 --- a/SOURCES/0035-events-move-conditional-macro-check-USE_EVENTS-insid.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 1755a9d3da61860aa8bbe0137d572a51981e1d68 Mon Sep 17 00:00:00 2001 -From: Atin Mukherjee -Date: Mon, 1 Aug 2016 11:56:27 +0530 -Subject: [PATCH 35/86] events: move conditional macro check USE_EVENTS inside gf_events - -> Reviewed-on: http://review.gluster.org/15054 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Kotresh HR -> Reviewed-by: Aravinda VK - -Change-Id: I88279b11b648e676a4544bbb55c7466fbc55ffa7 -BUG: 1351589 -Signed-off-by: Atin Mukherjee -Reviewed-on: https://code.engineering.redhat.com/gerrit/84741 -Tested-by: Aravinda Vishwanathapura Krishna Murthy -Reviewed-by: Milind Changire ---- - cli/src/cli-cmd-peer.c | 4 ---- - cli/src/cli-cmd-volume.c | 8 -------- - libglusterfs/src/events.c | 4 +++- - 3 files changed, 3 insertions(+), 13 deletions(-) - -diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c -index 36c328a..fc72075 100644 ---- a/cli/src/cli-cmd-peer.c -+++ b/cli/src/cli-cmd-peer.c -@@ -90,11 +90,9 @@ out: - - CLI_STACK_DESTROY (frame); - --#if (USE_EVENTS) - if (ret == 0) { - gf_event (EVENT_PEER_ATTACH, "host=%s", (char *)words[2]); - } --#endif - - return ret; - } -@@ -166,11 +164,9 @@ out: - - CLI_STACK_DESTROY (frame); - --#if (USE_EVENTS) - if (ret == 0) { - gf_event (EVENT_PEER_DETACH, "host=%s", (char *)words[2]); - } --#endif - - return ret; - } -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 7e53514..740a867 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -243,11 +243,9 @@ out: - } - - CLI_STACK_DESTROY (frame); --#if (USE_EVENTS) - if (ret == 0) { - gf_event (EVENT_VOLUME_CREATE, "name=%s", (char *)words[2]); - } --#endif - return ret; - } - -@@ -322,11 +320,9 @@ out: - - CLI_STACK_DESTROY (frame); - --#if (USE_EVENTS) - if (ret == 0) { - gf_event (EVENT_VOLUME_DELETE, "name=%s", (char *)words[2]); - } --#endif - - return ret; - } -@@ -402,11 +398,9 @@ out: - - CLI_STACK_DESTROY (frame); - --#if (USE_EVENTS) - if (ret == 0) { - gf_event (EVENT_VOLUME_START, "name=%s", (char *)words[2]); - } --#endif - - return ret; - } -@@ -540,11 +534,9 @@ out: - - CLI_STACK_DESTROY (frame); - --#if (USE_EVENTS) - if (ret == 0) { - gf_event (EVENT_VOLUME_STOP, "name=%s", (char *)words[2]); - } --#endif - - return ret; - } -diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c -index 9d78187..2df8c29 100644 ---- a/libglusterfs/src/events.c -+++ b/libglusterfs/src/events.c -@@ -23,12 +23,13 @@ - int - gf_event (int event, char *fmt, ...) - { -+ int ret = 0; -+#if (USE_EVENTS) - int sock = -1; - char eventstr[EVENTS_MSG_MAX] = ""; - struct sockaddr_un server; - va_list arguments; - char *msg = NULL; -- int ret = 0; - size_t eventstr_size = 0; - - if (event < 0 || event >= EVENT_LAST) { -@@ -79,5 +80,6 @@ gf_event (int event, char *fmt, ...) - out: - sys_close(sock); - GF_FREE(msg); -+#endif - return ret; - } --- -1.7.1 - diff --git a/SOURCES/0035-glusterd-regenerate-volfiles-on-op-version-bump-up.patch b/SOURCES/0035-glusterd-regenerate-volfiles-on-op-version-bump-up.patch new file mode 100644 index 0000000..63d2dfe --- /dev/null +++ b/SOURCES/0035-glusterd-regenerate-volfiles-on-op-version-bump-up.patch @@ -0,0 +1,99 @@ +From 88ed6bd3e752a028b5372aa948a191fa49377459 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Fri, 10 Nov 2017 19:17:27 +0530 +Subject: [PATCH 35/74] glusterd: regenerate volfiles on op-version bump up + +Please note that LOC of downstream patch differs because of a +downstream only fix https://code.engineering.redhat.com/gerrit/94006 + +Label: DOWNSTREAM ONLY + +>Reviewed-on: https://review.gluster.org/16455 +>NetBSD-regression: NetBSD Build System +>Smoke: Gluster Build System +>CentOS-regression: Gluster Build System +>Reviewed-by: Prashanth Pai +>Reviewed-by: Kaushal M + +Change-Id: I2fe7a3ebea19492d52253ad5a1fdd67ac95c71c8 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/96368 +Reviewed-by: Samikshan Bairagya +Reviewed-by: Prashanth Pai +--- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 38 ++++++++++-------------------- + 1 file changed, 13 insertions(+), 25 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 4fc719a..96e0860 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -2612,7 +2612,8 @@ glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict, + NULL); + if (ret) + goto out; +- ret = glusterd_update_volumes_dict (volinfo); ++ ret = glusterd_update_volumes_dict ++ (volinfo, &start_nfs_svc); + if (ret) + goto out; + if (!volinfo->is_snap_volume) { +@@ -2622,14 +2623,6 @@ glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict, + if (ret) + goto out; + } +- +- if (volinfo->type == GF_CLUSTER_TYPE_TIER) { +- svc = &(volinfo->tierd.svc); +- ret = svc->reconfigure (volinfo); +- if (ret) +- goto out; +- } +- + ret = glusterd_create_volfiles_and_notify_services (volinfo); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, +@@ -2651,6 +2644,17 @@ glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict, + } + } + } ++ if (start_nfs_svc) { ++ ret = conf->nfs_svc.manager (&(conf->nfs_svc), ++ NULL, ++ PROC_START_NO_WAIT); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_SVC_START_FAIL, ++ "unable to start nfs service"); ++ goto out; ++ } ++ } + ret = glusterd_store_global_info (this); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, +@@ -2658,22 +2662,6 @@ glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict, + "Failed to store op-version."); + } + } +- cds_list_for_each_entry (volinfo, &conf->volumes, vol_list) { +- ret = glusterd_update_volumes_dict (volinfo, +- &start_nfs_svc); +- if (ret) +- goto out; +- } +- if (start_nfs_svc) { +- ret = conf->nfs_svc.manager (&(conf->nfs_svc), NULL, +- PROC_START_NO_WAIT); +- if (ret) { +- gf_msg (this->name, GF_LOG_ERROR, 0, +- GD_MSG_SVC_START_FAIL, +- "unable to start nfs service"); +- goto out; +- } +- } + /* No need to save cluster.op-version in conf->opts + */ + goto out; +-- +1.8.3.1 + diff --git a/SOURCES/0036-eventsapi-Fix-disable-events-issue.patch b/SOURCES/0036-eventsapi-Fix-disable-events-issue.patch deleted file mode 100644 index 495b29b..0000000 --- a/SOURCES/0036-eventsapi-Fix-disable-events-issue.patch +++ /dev/null @@ -1,335 +0,0 @@ -From bd6e817e5272069500e3504c0db669a119c08b68 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Thu, 18 Aug 2016 14:51:44 +0530 -Subject: [PATCH 36/79] eventsapi: Fix disable-events issue - -Events related sources are not loaded in libglusterfs when -configure is run with --disable-events option. Due to this -every call of gf_event should be guarded with USE_EVENTS macro. - -To prevent this, USE_EVENTS macro was included in events.c -itself(Patch #15054) - -Instead of disabling building entire directory "events", selectively -disabled the code. So that constants and empty function gf_event is -exposed. Code will not fail even if gf_event is called when events is -disabled. - -> Reviewed-on: http://review.gluster.org/15198 -> Smoke: Gluster Build System -> Reviewed-by: Niels de Vos -> CentOS-regression: Gluster Build System -> NetBSD-regression: NetBSD Build System - -BUG: 1351589 -Change-Id: Ia6abfe9c1e46a7640c4d8ff5ccf0e9c30c87f928 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84742 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - Makefile.am | 2 +- - cli/src/cli-cmd-peer.c | 1 + - cli/src/cli-cmd-volume.c | 1 + - configure.ac | 1 - - events/Makefile.am | 4 +++- - events/src/Makefile.am | 15 ++++++++++----- - events/src/eventsapiconf.py.in | 1 + - events/src/gf_event.py | 5 ++++- - events/tools/Makefile.am | 5 ++++- - libglusterfs/src/Makefile.am | 14 ++++++-------- - libglusterfs/src/events.c | 9 ++++++--- - libglusterfs/src/{events.h.in => events.h} | 16 ++++++++++------ - libglusterfs/src/glusterfs.h | 4 ---- - xlators/features/bit-rot/src/bitd/bit-rot-scrub.c | 1 + - xlators/mgmt/glusterd/src/glusterd.h | 1 + - 16 files changed, 49 insertions(+), 32 deletions(-) - rename libglusterfs/src/{events.h.in => events.h} (71%) - -diff --git a/Makefile.am b/Makefile.am -index 37cbb86..da224c4 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -12,7 +12,7 @@ EXTRA_DIST = autogen.sh \ - - SUBDIRS = $(ARGP_STANDALONE_DIR) libglusterfs rpc api xlators glusterfsd \ - $(FUSERMOUNT_SUBDIR) doc extras cli heal @SYNCDAEMON_SUBDIR@ \ -- @UMOUNTD_SUBDIR@ tools @EVENTS_SUBDIR@ -+ @UMOUNTD_SUBDIR@ tools events - - pkgconfigdir = @pkgconfigdir@ - pkgconfig_DATA = glusterfs-api.pc libgfchangelog.pc -diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c -index fc72075..4802f71 100644 ---- a/cli/src/cli-cmd-peer.c -+++ b/cli/src/cli-cmd-peer.c -@@ -18,6 +18,7 @@ - #include "cli-mem-types.h" - #include "cli1-xdr.h" - #include "protocol-common.h" -+#include "events.h" - - extern struct rpc_clnt *global_rpc; - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 740a867..09cfcee 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -26,6 +26,7 @@ - #include "run.h" - #include "syscall.h" - #include "common-utils.h" -+#include "events.h" - - extern struct rpc_clnt *global_rpc; - extern struct rpc_clnt *global_quotad_rpc; -diff --git a/configure.ac b/configure.ac -index 2e0323d..e18309d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -38,7 +38,6 @@ AC_CONFIG_HEADERS([config.h]) - AC_CONFIG_FILES([Makefile - libglusterfs/Makefile - libglusterfs/src/Makefile -- libglusterfs/src/events.h - libglusterfs/src/gfdb/Makefile - geo-replication/src/peer_gsec_create - geo-replication/src/peer_mountbroker -diff --git a/events/Makefile.am b/events/Makefile.am -index 04a74ef..264bb74 100644 ---- a/events/Makefile.am -+++ b/events/Makefile.am -@@ -1,6 +1,8 @@ - SUBDIRS = src tools -- -+EXTRA_DIST = eventskeygen.py - noinst_PYTHON = eventskeygen.py - -+if BUILD_EVENTS - install-data-hook: - $(INSTALL) -d -m 755 $(DESTDIR)@GLUSTERD_WORKDIR@/events -+endif -diff --git a/events/src/Makefile.am b/events/src/Makefile.am -index 423bc88..d292fbe 100644 ---- a/events/src/Makefile.am -+++ b/events/src/Makefile.am -@@ -6,18 +6,21 @@ BUILT_SOURCES = eventtypes.py - CLEANFILES = eventtypes.py - - eventsdir = $(libexecdir)/glusterfs/events -+events_PYTHON = __init__.py gf_event.py eventsapiconf.py eventtypes.py \ -+ utils.py -+ -+eventtypes.py: -+ $(PYTHON) $(top_srcdir)/events/eventskeygen.py PY_HEADER -+ -+if BUILD_EVENTS - eventspeerscriptdir = $(libexecdir)/glusterfs - eventsconfdir = $(sysconfdir)/glusterfs - eventsconf_DATA = eventsconfig.json - --events_PYTHON = __init__.py eventsapiconf.py eventtypes.py handlers.py \ -- utils.py gf_event.py -+events_PYTHON += handlers.py - events_SCRIPTS = glustereventsd.py - eventspeerscript_SCRIPTS = peer_eventsapi.py - --eventtypes.py: $(top_srcdir)/events/eventskeygen.py -- $(PYTHON) $(top_srcdir)/events/eventskeygen.py PY_HEADER -- - install-exec-hook: - $(mkdir_p) $(DESTDIR)$(sbindir) - rm -f $(DESTDIR)$(sbindir)/glustereventsd -@@ -30,3 +33,5 @@ install-exec-hook: - uninstall-hook: - rm -f $(DESTDIR)$(sbindir)/glustereventsd - rm -f $(DESTDIR)$(sbindir)/gluster-eventsapi -+ -+endif -diff --git a/events/src/eventsapiconf.py.in b/events/src/eventsapiconf.py.in -index 702e1d2..03dd0e8 100644 ---- a/events/src/eventsapiconf.py.in -+++ b/events/src/eventsapiconf.py.in -@@ -20,3 +20,4 @@ EVENTSD = "glustereventsd" - CONFIG_KEYS = ["log_level"] - BOOL_CONFIGS = [] - RESTART_CONFIGS = [] -+EVENTS_ENABLED = @EVENTS_ENABLED@ -diff --git a/events/src/gf_event.py b/events/src/gf_event.py -index 0924a65..20dfc8a 100644 ---- a/events/src/gf_event.py -+++ b/events/src/gf_event.py -@@ -13,7 +13,7 @@ - import socket - import time - --from eventsapiconf import SERVER_ADDRESS -+from eventsapiconf import SERVER_ADDRESS, EVENTS_ENABLED - from eventtypes import all_events - - from utils import logger, setup_logger -@@ -23,6 +23,9 @@ setup_logger() - - - def gf_event(event_type, **kwargs): -+ if EVENTS_ENABLED == 0: -+ return -+ - if not isinstance(event_type, int) or event_type >= len(all_events): - logger.error("Invalid Event Type: {0}".format(event_type)) - return -diff --git a/events/tools/Makefile.am b/events/tools/Makefile.am -index 7d5e331..fb6770c 100644 ---- a/events/tools/Makefile.am -+++ b/events/tools/Makefile.am -@@ -1,3 +1,6 @@ -+EXTRA_DIST = eventsdash.py -+ -+if BUILD_EVENTS - scriptsdir = $(datadir)/glusterfs/scripts - scripts_SCRIPTS = eventsdash.py --EXTRA_DIST = eventsdash.py -+endif -diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am -index 66369e2..b7c3116 100644 ---- a/libglusterfs/src/Makefile.am -+++ b/libglusterfs/src/Makefile.am -@@ -38,7 +38,7 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \ - nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c defaults.c - nodist_libglusterfs_la_HEADERS = y.tab.h glusterfs-fops.h cli1-xdr.h - --BUILT_SOURCES = graph.lex.c defaults.c glusterfs-fops.h cli1-xdr.h -+BUILT_SOURCES = graph.lex.c defaults.c glusterfs-fops.h cli1-xdr.h eventtypes.h - - libglusterfs_la_HEADERS = common-utils.h defaults.h default-args.h \ - dict.h glusterfs.h hashfn.h timespec.h logging.h xlator.h \ -@@ -52,7 +52,7 @@ libglusterfs_la_HEADERS = common-utils.h defaults.h default-args.h \ - glfs-message-id.h template-component-messages.h strfd.h \ - syncop-utils.h parse-utils.h libglusterfs-messages.h tw.h \ - lvm-defaults.h quota-common-utils.h rot-buffs.h \ -- compat-uuid.h upcall-utils.h -+ compat-uuid.h upcall-utils.h events.h - - libglusterfs_ladir = $(includedir)/glusterfs - -@@ -72,14 +72,12 @@ libglusterfs_la_SOURCES += $(CONTRIBDIR)/uuid/clear.c \ - $(CONTRIBDIR)/uuid/unpack.c - endif - --if BUILD_EVENTS --BUILT_SOURCES += eventtypes.h --libglusterfs_la_SOURCES += events.c -- --libglusterfs_la_HEADERS += events.h eventtypes.h - --eventtypes.h: $(top_srcdir)/events/eventskeygen.py -+eventtypes.h: - $(PYTHON) $(top_srcdir)/events/eventskeygen.py C_HEADER -+ -+if BUILD_EVENTS -+libglusterfs_la_SOURCES += events.c - endif - - libgfchangelog_HEADERS = changelog.h -diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c -index 2df8c29..f93934d 100644 ---- a/libglusterfs/src/events.c -+++ b/libglusterfs/src/events.c -@@ -20,11 +20,15 @@ - #include "mem-pool.h" - #include "events.h" - -+ -+#define EVENT_PATH DATADIR "/run/gluster/events.sock" -+#define EVENTS_MSG_MAX 2048 -+ -+ - int --gf_event (int event, char *fmt, ...) -+gf_event (eventtypes_t event, char *fmt, ...) - { - int ret = 0; --#if (USE_EVENTS) - int sock = -1; - char eventstr[EVENTS_MSG_MAX] = ""; - struct sockaddr_un server; -@@ -80,6 +84,5 @@ gf_event (int event, char *fmt, ...) - out: - sys_close(sock); - GF_FREE(msg); --#endif - return ret; - } -diff --git a/libglusterfs/src/events.h.in b/libglusterfs/src/events.h -similarity index 71% -rename from libglusterfs/src/events.h.in -rename to libglusterfs/src/events.h -index 37692be..6b280a0 100644 ---- a/libglusterfs/src/events.h.in -+++ b/libglusterfs/src/events.h -@@ -11,13 +11,17 @@ - #ifndef __EVENTS_H__ - #define __EVENTS_H__ - --#include -- - #include "eventtypes.h" - --#define EVENT_PATH "@localstatedir@/run/gluster/events.sock" --#define EVENTS_MSG_MAX 2048 -- --extern int gf_event(int key, char *fmt, ...); -+#ifdef USE_EVENTS -+int -+gf_event (eventtypes_t event, char *fmt, ...); -+#else -+static inline int -+gf_event (eventtypes_t event, char *fmt, ...) -+{ -+ return 0; -+} -+#endif /* USE_EVENTS */ - - #endif /* __EVENTS_H__ */ -diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h -index cbad737..0cee2ba 100644 ---- a/libglusterfs/src/glusterfs.h -+++ b/libglusterfs/src/glusterfs.h -@@ -37,10 +37,6 @@ - #include "lkowner.h" - #include "compat-uuid.h" - --#if (USE_EVENTS) --#include "events.h" --#endif -- - #define GF_YES 1 - #define GF_NO 0 - -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -index 601dea9..abf8dcf 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -+++ b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -@@ -20,6 +20,7 @@ - #include - #include "bit-rot-bitd-messages.h" - #include "bit-rot-scrub-status.h" -+#include "events.h" - - struct br_scrubbers { - pthread_t scrubthread; -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index 29aaf64..f5e090d 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -36,6 +36,7 @@ - #include "syncop.h" - #include "store.h" - #include "glusterd-rcu.h" -+#include "events.h" - - #define GLUSTERD_TR_LOG_SIZE 50 - #define GLUSTERD_SOCKET_LISTEN_BACKLOG 128 --- -1.7.1 - diff --git a/SOURCES/0036-mount-fuse-Fix-parsing-of-vol_id-for-snapshot-volume.patch b/SOURCES/0036-mount-fuse-Fix-parsing-of-vol_id-for-snapshot-volume.patch new file mode 100644 index 0000000..5a50372 --- /dev/null +++ b/SOURCES/0036-mount-fuse-Fix-parsing-of-vol_id-for-snapshot-volume.patch @@ -0,0 +1,50 @@ +From b5f16e56bd1a9e64fa461f22f24790992fd2c008 Mon Sep 17 00:00:00 2001 +From: Mohammed Rafi KC +Date: Thu, 12 Oct 2017 14:31:14 +0530 +Subject: [PATCH 36/74] mount/fuse : Fix parsing of vol_id for snapshot volume + +For supporting sub-dir mount, we changed the volid. Which means anything +after a '/' in volume_id will be considered as sub-dir path. + +But snapshot volume has vol_id stracture of /snaps// +which has to be considered as during the parsing. + +Note 1: sub-dir mount is not supported on snapshot volume +Note 2: With sub-dir mount changes brick based mount for quota cannot be + executed via mount command. It has to be a direct call via glusterfs + +Backport of> +>Change-Id: I0d824de0236b803db8a918f683dabb0cb523cb04 +>BUG: 1501235 +>Signed-off-by: Mohammed Rafi KC +>Upstream patch : https://review.gluster.org/18506 + +Change-Id: I82903bdd0bfcf8454faef958b38f13d4d95a2346 +Signed-off-by: Mohammed Rafi KC +Reviewed-on: https://code.engineering.redhat.com/gerrit/120524 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + xlators/mount/fuse/utils/mount.glusterfs.in | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in +index bd6503a..36b60ff 100755 +--- a/xlators/mount/fuse/utils/mount.glusterfs.in ++++ b/xlators/mount/fuse/utils/mount.glusterfs.in +@@ -675,8 +675,10 @@ main () + [ ${first_char} = '/' ] && { + volume_str_temp=$(echo "$volume_str" | cut -c 2-) + } +- [ $(echo $volume_str_temp | grep -c "/") -eq 1 ] && { +- volume_id=$(echo "$volume_str_temp" | cut -f1 -d '/'); ++ volume_id_temp=$(echo "$volume_str_temp" | cut -f1 -d '/'); ++ [ $(echo $volume_str_temp | grep -c "/") -eq 1 ] && ++ [ "$volume_id_temp" != "snaps" ] && { ++ volume_id=$volume_id_temp; + subdir_mount=$(echo "$volume_str_temp" | cut -f2- -d '/'); + } + } +-- +1.8.3.1 + diff --git a/SOURCES/0037-extras-kill-processes-gracefully.patch b/SOURCES/0037-extras-kill-processes-gracefully.patch deleted file mode 100644 index 74254eb..0000000 --- a/SOURCES/0037-extras-kill-processes-gracefully.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 2e072bb19d47080ca91c181698cfcf1beb60b8b1 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 16 Sep 2016 13:08:00 +0530 -Subject: [PATCH 37/86] extras: kill processes gracefully - -Currently all of brick, gsyncd and other glustershd services/processes -are killed without checking for ongoing tasks such as geo-rep, -self-heal, rebalance and etc. which may lead to inconsistency after -the node is brought back. - -This patch introduce an option '-g' which ensures whether all the -gluster processes are ready (not busy) to be terminated before we -executing 'kill' on them - -Usage: ./extras/stop-all-gluster-processes.sh [-g] [-h] - options: - -g Terminate in graceful mode - -h Show this message, then exit - - eg: - 1. ./extras/stop-all-gluster-processes.sh - 2. ./extras/stop-all-gluster-processes.sh -g - -By default, this script executes in force mode, processes are killed -without checking for ongoing tasks, on specifying '-g' option this -script works in graceful mode, which returns exitcode if some of gluster -processes are busy in doing their jobs. - -exitcodes include: - 0 No errors/Success - 64 Rebalance is in progress - 65 Self-Heal is in progress - 66 Tier daemon running on this node - 127 option not found - -Backport of: -> Change-Id: I2f924b2bf9f04a81788d0f5604895a42755b33a1 -> BUG: 1367771 -> Signed-off-by: Prasanna Kumar Kalever -> Reviewed-on: http://review.gluster.org/15188 -> Tested-by: Prasanna Kumar Kalever -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Rajesh Joseph -> CentOS-regression: Gluster Build System -> Reviewed-by: Ravishankar N -> Reviewed-by: mohammed rafi kc -> Reviewed-by: Atin Mukherjee - -Change-Id: I2f924b2bf9f04a81788d0f5604895a42755b33a1 -BUG: 1294754 -Signed-off-by: Prasanna Kumar Kalever -Reviewed-on: https://code.engineering.redhat.com/gerrit/84768 -Reviewed-by: Atin Mukherjee ---- - extras/stop-all-gluster-processes.sh | 111 +++++++++++++++++++++++++++++++++- - 1 files changed, 110 insertions(+), 1 deletions(-) - -diff --git a/extras/stop-all-gluster-processes.sh b/extras/stop-all-gluster-processes.sh -index 356a2a6..f11c634 100755 ---- a/extras/stop-all-gluster-processes.sh -+++ b/extras/stop-all-gluster-processes.sh -@@ -1,4 +1,37 @@ - #!/usr/bin/env bash -+# -+# Kill all the processes/services except glusterd -+# -+# Usage: ./extras/stop-all-gluster-processes.sh [-g] [-h] -+# options: -+# -g Terminate in graceful mode -+# -h Show this message, then exit -+# -+# eg: -+# 1. ./extras/stop-all-gluster-processes.sh -+# 2. ./extras/stop-all-gluster-processes.sh -g -+# -+# By default, this script executes in force mode, i.e. all of brick, gsyncd -+# and other glustershd services/processes are killed without checking for -+# ongoing tasks such as geo-rep, self-heal, rebalance and etc. which may lead -+# to inconsistency after the node is brought back. -+# -+# On specifying '-g' option this script works in graceful mode, to maintain -+# data consistency the script fails with a valid exit code incase if any of -+# the gluster processes are busy in doing their jobs. -+# -+# The author of page [1] proposes user-defined exit codes to the range 64 - 113 -+# Find the better explanation behind the choice in the link -+# -+# The exit code returned by stop-all-gluster-processes.sh: -+# 0 No errors/Success -+# 64 Rebalance is in progress -+# 65 Self-Heal is in progress -+# 66 Tier daemon running on this node -+# 127 option not found -+# -+# [1] http://www.tldp.org/LDP/abs/html/exitcodes.html -+ - - # global - errors=0 -@@ -64,8 +97,84 @@ kill_georep_gsync() - fi - } - -+# check if all processes are ready to die -+check_background_tasks() -+{ -+ volumes=$(gluster vol list) -+ quit=0 -+ for volname in ${volumes}; -+ do -+ # tiering -+ if [[ $(gluster volume tier ${volname} status 2> /dev/null | -+ grep "localhost" | grep -c "in progress") -gt 0 ]] -+ then -+ quit=66 -+ break; -+ fi -+ -+ # rebalance -+ if [[ $(gluster volume rebalance ${volname} status 2> /dev/null | -+ grep -c "in progress") -gt 0 ]] -+ then -+ quit=64 -+ break; -+ fi -+ -+ # self heal -+ if [[ $(gluster volume heal ${volname} info | grep "Number of entries" | -+ awk '{ sum+=$4} END {print sum}') -gt 0 ]]; -+ then -+ quit=65 -+ break; -+ fi -+ -+ # geo-rep, snapshot and quota doesn't need grace checks, -+ # as they ensures the consistancy on force kills -+ done -+ -+ echo ${quit} -+} -+ -+usage() -+{ -+ cat < +Date: Mon, 16 Oct 2017 11:44:59 +0530 +Subject: [PATCH 37/74] protocol-auth: use the proper validation method + +Currently, server protocol's init and glusterd's option +validation methods are different, causing an issue. They +should be same for having consistent behavior + +> Upstream: +> Change-Id: Ibbf9a18c7192b2d77f9b7675ae7da9b8d2fe5de4 +> URL: https://review.gluster.org/#/c/18489/ + +Change-Id: Id595a1032b14233ca8f31d20813dca98476b2468 +Signed-off-by: Amar Tumballi +Reviewed-on: https://code.engineering.redhat.com/gerrit/120558 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + libglusterfs/src/options.c | 4 ++-- + libglusterfs/src/options.h | 5 +++++ + tests/features/subdir-mount.t | 4 ++++ + xlators/protocol/server/src/server.c | 40 +++++++----------------------------- + 4 files changed, 18 insertions(+), 35 deletions(-) + +diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c +index f0292ea..a0f04c7 100644 +--- a/libglusterfs/src/options.c ++++ b/libglusterfs/src/options.c +@@ -590,7 +590,7 @@ xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value, + return ret; + } + +-static int ++int + xlator_option_validate_addr_list (xlator_t *xl, const char *key, + const char *value, volume_option_t *opt, + char **op_errstr) +@@ -668,7 +668,7 @@ xlator_option_validate_addr_list (xlator_t *xl, const char *key, + out: + if (ret) { + snprintf (errstr, sizeof (errstr), "option %s %s: '%s' is not " +- "a valid internet-address-list", key, value, value); ++ "a valid internet-address-list", key, value, value); + gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", + errstr); + if (op_errstr) +diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h +index 3154dce..d259d44 100644 +--- a/libglusterfs/src/options.h ++++ b/libglusterfs/src/options.h +@@ -87,6 +87,11 @@ int xlator_options_validate_list (xlator_t *xl, dict_t *options, + int xlator_option_validate (xlator_t *xl, char *key, char *value, + volume_option_t *opt, char **op_errstr); + int xlator_options_validate (xlator_t *xl, dict_t *options, char **errstr); ++ ++int xlator_option_validate_addr_list (xlator_t *xl, const char *key, ++ const char *value, volume_option_t *opt, ++ char **op_errstr); ++ + volume_option_t * + xlator_volume_option_get (xlator_t *xl, const char *key); + +diff --git a/tests/features/subdir-mount.t b/tests/features/subdir-mount.t +index 2fb0be4..ab7ef35 100644 +--- a/tests/features/subdir-mount.t ++++ b/tests/features/subdir-mount.t +@@ -78,6 +78,10 @@ TEST ! $CLI volume set $V0 auth.allow "subdir2\(1.2.3.4\)" + # support subdir inside subdir + TEST $CLI volume set $V0 auth.allow '/subdir1/subdir1.1/subdir1.2/\(1.2.3.4\|::1\),/\(192.168.10.1\|192.168.11.1\),/subdir2\(1.2.3.4\)' + ++TEST $CLI volume stop $V0 ++ ++TEST $CLI volume start $V0 ++ + # /subdir2 has not allowed IP + TEST $GFS --subdir-mount /subdir2 -s $H0 --volfile-id $V0 $M1 + TEST stat $M1 +diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c +index e47acb2..6dc9d0f 100644 +--- a/xlators/protocol/server/src/server.c ++++ b/xlators/protocol/server/src/server.c +@@ -386,9 +386,6 @@ _check_for_auth_option (dict_t *d, char *k, data_t *v, + int ret = 0; + xlator_t *xl = NULL; + char *tail = NULL; +- char *tmp_addr_list = NULL; +- char *addr = NULL; +- char *tmp_str = NULL; + + xl = tmp; + +@@ -417,38 +414,15 @@ _check_for_auth_option (dict_t *d, char *k, data_t *v, + * valid auth.allow. + * Now we verify the ip address + */ +- if (!strcmp (v->data, "*")) { +- ret = 0; +- goto out; +- } +- +- /* TODO-SUBDIR-MOUNT: fix the format */ +- tmp_addr_list = gf_strdup (v->data); +- addr = strtok_r (tmp_addr_list, ",", &tmp_str); +- if (!addr) +- addr = v->data; +- +- while (addr) { +- if (valid_internet_address (addr, _gf_true)) { +- ret = 0; +- } else { +- ret = -1; +- gf_msg (xl->name, GF_LOG_ERROR, 0, +- PS_MSG_INTERNET_ADDR_ERROR, +- "internet address '%s'" +- " does not conform to" +- " standards.", addr); +- goto out; +- } +- if (tmp_str) +- addr = strtok_r (NULL, ",", &tmp_str); +- else +- addr = NULL; +- } ++ ret = xlator_option_validate_addr_list (xl, "auth-*", v->data, ++ NULL, NULL); ++ if (ret) ++ gf_msg (xl->name, GF_LOG_ERROR, 0, ++ PS_MSG_INTERNET_ADDR_ERROR, ++ "internet address '%s' does not conform " ++ "to standards.", v->data); + } + out: +- GF_FREE (tmp_addr_list); +- + return ret; + } + +-- +1.8.3.1 + diff --git a/SOURCES/0038-extras-kill-gsyncd-before-glusterfsd.patch b/SOURCES/0038-extras-kill-gsyncd-before-glusterfsd.patch deleted file mode 100644 index 846bc94..0000000 --- a/SOURCES/0038-extras-kill-gsyncd-before-glusterfsd.patch +++ /dev/null @@ -1,55 +0,0 @@ -From f72331f4acbdf2794f6373f552da9e5355fef6e2 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 16 Sep 2016 12:55:37 +0530 -Subject: [PATCH 38/86] extras: kill gsyncd before glusterfsd - -It's a good practice to kill gsyncd before brick process, else we see -unnecessary loops and logs of bring up the faulty bricks - -Backport of: -> Change-Id: I2d2176f2bf5014f3afd622194a8b2d60c86926af -> BUG: 1367771 -> Signed-off-by: Prasanna Kumar Kalever -> Reviewed-on: http://review.gluster.org/15187 -> Tested-by: Prasanna Kumar Kalever -> CentOS-regression: Gluster Build System -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Atin Mukherjee -> Reviewed-by: Kotresh HR - -Change-Id: I2d2176f2bf5014f3afd622194a8b2d60c86926af -BUG: 1294754 -Signed-off-by: Prasanna Kumar Kalever -Reviewed-on: https://code.engineering.redhat.com/gerrit/84767 -Reviewed-by: Atin Mukherjee ---- - extras/stop-all-gluster-processes.sh | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/extras/stop-all-gluster-processes.sh b/extras/stop-all-gluster-processes.sh -index f11c634..69fd601 100755 ---- a/extras/stop-all-gluster-processes.sh -+++ b/extras/stop-all-gluster-processes.sh -@@ -176,16 +176,16 @@ main() - shift $((OPTIND-1)) - - kill_mounts TERM -- kill_bricks_and_services TERM - kill_georep_gsync TERM -+ kill_bricks_and_services TERM - - sleep 5; - echo "" - - # still not Terminated? let's pass SIGKILL - kill_mounts KILL -- kill_bricks_and_services KILL - kill_georep_gsync KILL -+ kill_bricks_and_services KILL - - exit ${errors}; - } --- -1.7.1 - diff --git a/SOURCES/0038-protocol-server-fix-the-comparision-logic-in-case-of.patch b/SOURCES/0038-protocol-server-fix-the-comparision-logic-in-case-of.patch new file mode 100644 index 0000000..fb8a5fd --- /dev/null +++ b/SOURCES/0038-protocol-server-fix-the-comparision-logic-in-case-of.patch @@ -0,0 +1,111 @@ +From 4fd6388cf08d9c902f20683579d62408847c3766 Mon Sep 17 00:00:00 2001 +From: Amar Tumballi +Date: Mon, 23 Oct 2017 21:17:52 +0200 +Subject: [PATCH 38/74] protocol/server: fix the comparision logic in case of + subdir mount + +without the fix, the stat entry on a file would return inode==1 for +many files, in case of subdir mount + +This happened with the confusion of return value of 'gf_uuid_compare()', +it is more like strcmp, instead of a gf_boolean return value, and hence +resulted in the bug. + +> Upstream: +> URL: https://review.gluster.org/#/c/18558/ +> + +Also fixes the bz1501714 + +Change-Id: I31b8cbd95eaa3af5ff916a969458e8e4020c86bb +Signed-off-by: Amar Tumballi +Reviewed-on: https://code.engineering.redhat.com/gerrit/121726 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + xlators/protocol/server/src/server-common.c | 60 ++++++++++++++--------------- + 1 file changed, 30 insertions(+), 30 deletions(-) + +diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c +index b972918..ce33089 100644 +--- a/xlators/protocol/server/src/server-common.c ++++ b/xlators/protocol/server/src/server-common.c +@@ -12,22 +12,22 @@ + void + server_post_stat (server_state_t *state, gfs3_stat_rsp *rsp, struct iatt *stbuf) + { +- if (state->client->subdir_mount) { +- if (gf_uuid_compare (stbuf->ia_gfid, +- state->client->subdir_gfid)) { +- /* This is very important as when we send iatt of +- root-inode, fuse/client expect the gfid to be 1, +- along with inode number. As for subdirectory mount, +- we use inode table which is shared by everyone, but +- make sure we send fops only from subdir and below, +- we have to alter inode gfid and send it to client */ +- uuid_t gfid = {0,}; +- +- gfid[15] = 1; +- stbuf->ia_ino = 1; +- gf_uuid_copy (stbuf->ia_gfid, gfid); +- } ++ if (state->client->subdir_mount && ++ !gf_uuid_compare (stbuf->ia_gfid, ++ state->client->subdir_gfid)) { ++ /* This is very important as when we send iatt of ++ root-inode, fuse/client expect the gfid to be 1, ++ along with inode number. As for subdirectory mount, ++ we use inode table which is shared by everyone, but ++ make sure we send fops only from subdir and below, ++ we have to alter inode gfid and send it to client */ ++ uuid_t gfid = {0,}; ++ ++ gfid[15] = 1; ++ stbuf->ia_ino = 1; ++ gf_uuid_copy (stbuf->ia_gfid, gfid); + } ++ + gf_stat_from_iatt (&rsp->stat, stbuf); + } + +@@ -185,22 +185,22 @@ void + server_post_fstat (server_state_t *state, gfs3_fstat_rsp *rsp, + struct iatt *stbuf) + { +- if (state->client->subdir_mount) { +- if (gf_uuid_compare (stbuf->ia_gfid, +- state->client->subdir_gfid)) { +- /* This is very important as when we send iatt of +- root-inode, fuse/client expect the gfid to be 1, +- along with inode number. As for subdirectory mount, +- we use inode table which is shared by everyone, but +- make sure we send fops only from subdir and below, +- we have to alter inode gfid and send it to client */ +- uuid_t gfid = {0,}; +- +- gfid[15] = 1; +- stbuf->ia_ino = 1; +- gf_uuid_copy (stbuf->ia_gfid, gfid); +- } ++ if (state->client->subdir_mount && ++ !gf_uuid_compare (stbuf->ia_gfid, ++ state->client->subdir_gfid)) { ++ /* This is very important as when we send iatt of ++ root-inode, fuse/client expect the gfid to be 1, ++ along with inode number. As for subdirectory mount, ++ we use inode table which is shared by everyone, but ++ make sure we send fops only from subdir and below, ++ we have to alter inode gfid and send it to client */ ++ uuid_t gfid = {0,}; ++ ++ gfid[15] = 1; ++ stbuf->ia_ino = 1; ++ gf_uuid_copy (stbuf->ia_gfid, gfid); + } ++ + gf_stat_from_iatt (&rsp->stat, stbuf); + } + +-- +1.8.3.1 + diff --git a/SOURCES/0039-build-fix-eventtypes.h-generation.patch b/SOURCES/0039-build-fix-eventtypes.h-generation.patch deleted file mode 100644 index 5f0a3cf..0000000 --- a/SOURCES/0039-build-fix-eventtypes.h-generation.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 75459302c58c25e0fbca495c69f1a6e2e5f163a3 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 26 Aug 2016 13:49:32 +0530 -Subject: [PATCH 39/86] build: fix eventtypes.h generation - -make 'eventtypes.py' as dependent i.e. must build eventtypes.h - -Else the consequence will be like: -error: 'EVENT_CLIENT_GRACE_TIMER_START' undeclared (first use in this function) - -> Reviewed-on: http://review.gluster.org/15327 -> Tested-by: Prasanna Kumar Kalever -> Smoke: Gluster Build System -> Reviewed-by: Aravinda VK -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System - -Change-Id: I5fe2491d8d1e0c430b307026695d25475250ae79 -BUG: 1351589 -Signed-off-by: Prasanna Kumar Kalever -Reviewed-on: https://code.engineering.redhat.com/gerrit/84743 -Tested-by: Aravinda Vishwanathapura Krishna Murthy -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - events/src/Makefile.am | 2 +- - libglusterfs/src/Makefile.am | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/events/src/Makefile.am b/events/src/Makefile.am -index d292fbe..87282c6 100644 ---- a/events/src/Makefile.am -+++ b/events/src/Makefile.am -@@ -9,7 +9,7 @@ eventsdir = $(libexecdir)/glusterfs/events - events_PYTHON = __init__.py gf_event.py eventsapiconf.py eventtypes.py \ - utils.py - --eventtypes.py: -+eventtypes.py: $(top_srcdir)/events/eventskeygen.py - $(PYTHON) $(top_srcdir)/events/eventskeygen.py PY_HEADER - - if BUILD_EVENTS -diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am -index b7c3116..93403db 100644 ---- a/libglusterfs/src/Makefile.am -+++ b/libglusterfs/src/Makefile.am -@@ -73,7 +73,7 @@ libglusterfs_la_SOURCES += $(CONTRIBDIR)/uuid/clear.c \ - endif - - --eventtypes.h: -+eventtypes.h: $(top_srcdir)/events/eventskeygen.py - $(PYTHON) $(top_srcdir)/events/eventskeygen.py C_HEADER - - if BUILD_EVENTS --- -1.7.1 - diff --git a/SOURCES/0039-protocol-client-handle-the-subdir-handshake-properly.patch b/SOURCES/0039-protocol-client-handle-the-subdir-handshake-properly.patch new file mode 100644 index 0000000..97d9ccf --- /dev/null +++ b/SOURCES/0039-protocol-client-handle-the-subdir-handshake-properly.patch @@ -0,0 +1,108 @@ +From 0f3a3c9ed32fec80f1b88cc649a98bcdcc234b6a Mon Sep 17 00:00:00 2001 +From: Amar Tumballi +Date: Sun, 22 Oct 2017 12:41:38 +0530 +Subject: [PATCH 39/74] protocol/client: handle the subdir handshake properly + for add-brick + +There should be different way we handle handshake in case of subdir +mount for the first time, and in case of subsequent graph changes. + +> Upstream +> URL: https://review.gluster.org/#/c/18550/ +> + +Change-Id: I2a7ba836433bb0a0f4a861809e2bb0d7fbc4da54 +Signed-off-by: Amar Tumballi +Reviewed-on: https://code.engineering.redhat.com/gerrit/121725 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + tests/features/subdir-mount.t | 31 +++++++++++++++++++++----- + xlators/protocol/client/src/client-handshake.c | 10 ++++++++- + 2 files changed, 35 insertions(+), 6 deletions(-) + +diff --git a/tests/features/subdir-mount.t b/tests/features/subdir-mount.t +index ab7ef35..1742f86 100644 +--- a/tests/features/subdir-mount.t ++++ b/tests/features/subdir-mount.t +@@ -82,17 +82,38 @@ TEST $CLI volume stop $V0 + + TEST $CLI volume start $V0 + +-# /subdir2 has not allowed IP +-TEST $GFS --subdir-mount /subdir2 -s $H0 --volfile-id $V0 $M1 +-TEST stat $M1 +- + TEST $GFS --subdir-mount /subdir1/subdir1.1/subdir1.2 -s $H0 --volfile-id $V0 $M2 + TEST stat $M2 + ++# mount shouldn't fail even after add-brick ++TEST $CLI volume add-brick $V0 replica 2 $H0:$B0/${V0}{5,6}; ++ ++# 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") ++TEST test "$mount_inode" == "1" ++ ++TEST umount $M2 ++ ++# because the subdir is not yet 'healed', below should fail. ++TEST $GFS --subdir-mount /subdir2 -s $H0 --volfile-id $V0 $M2 ++mount_inode=$(stat --format "%i" "$M2") ++TEST test "$mount_inode" != "1" ++ ++# Allow the heal to complete ++TEST stat $M0/subdir1/subdir1.1/subdir1.2/subdir1.2_file; ++TEST stat $M0/subdir2/ ++ ++# Now the mount should succeed ++TEST $GFS --subdir-mount /subdir2 -s $H0 --volfile-id $V0 $M1 ++TEST stat $M1 ++ + # umount $M1 / $M2 + TEST umount $M0 + TEST umount $M1 +-TEST umount $M2 + + + TEST $CLI volume stop $V0; +diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c +index b6dc079..aee6b3a 100644 +--- a/xlators/protocol/client/src/client-handshake.c ++++ b/xlators/protocol/client/src/client-handshake.c +@@ -1079,10 +1079,14 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m + int32_t op_errno = 0; + gf_boolean_t auth_fail = _gf_false; + uint32_t lk_ver = 0; ++ glusterfs_ctx_t *ctx = NULL; + + frame = myframe; + this = frame->this; + conf = this->private; ++ GF_VALIDATE_OR_GOTO (this->name, conf, out); ++ ctx = this->ctx; ++ GF_VALIDATE_OR_GOTO (this->name, ctx, out); + + if (-1 == req->rpc_status) { + gf_msg (frame->this->name, GF_LOG_WARNING, ENOTCONN, +@@ -1145,9 +1149,13 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m + auth_fail = _gf_true; + op_ret = 0; + } +- if ((op_errno == ENOENT) && this->ctx->cmd_args.subdir_mount) { ++ if ((op_errno == ENOENT) && this->ctx->cmd_args.subdir_mount && ++ (ctx->graph_id <= 1)) { + /* A case of subdir not being present at the moment, + ride on auth_fail framework to notify the error */ ++ /* Make sure this case is handled only in the new ++ graph, so mount may fail in this case. In case ++ of 'add-brick' etc, we need to continue retry */ + auth_fail = _gf_true; + op_ret = 0; + } +-- +1.8.3.1 + diff --git a/SOURCES/0040-glusterd-delete-source-brick-only-once-in-reset-bric.patch b/SOURCES/0040-glusterd-delete-source-brick-only-once-in-reset-bric.patch new file mode 100644 index 0000000..46a133a --- /dev/null +++ b/SOURCES/0040-glusterd-delete-source-brick-only-once-in-reset-bric.patch @@ -0,0 +1,69 @@ +From 8fb2496f67b1170595144eecb9a3b8f3be35044e Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Mon, 30 Oct 2017 15:55:32 +0530 +Subject: [PATCH 40/74] glusterd: delete source brick only once in reset-brick + commit force + +While stopping the brick which is to be reset and replaced delete_brick +flag was passed as true which resulted glusterd to free up to source +brick before the actual operation. This results commit force to fail +failing to find the source brickinfo. + +>upstream patch : https://review.gluster.org/#/c/18581 + +Change-Id: I1aa7508eff7cc9c9b5d6f5163f3bb92736d6df44 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/121876 +Tested-by: RHGS Build Bot +--- + .../bug-1507466-reset-brick-commit-force.t | 24 ++++++++++++++++++++++ + xlators/mgmt/glusterd/src/glusterd-reset-brick.c | 2 +- + 2 files changed, 25 insertions(+), 1 deletion(-) + create mode 100644 tests/bugs/glusterd/bug-1507466-reset-brick-commit-force.t + +diff --git a/tests/bugs/glusterd/bug-1507466-reset-brick-commit-force.t b/tests/bugs/glusterd/bug-1507466-reset-brick-commit-force.t +new file mode 100644 +index 0000000..764399d +--- /dev/null ++++ b/tests/bugs/glusterd/bug-1507466-reset-brick-commit-force.t +@@ -0,0 +1,24 @@ ++#!/bin/bash ++. $(dirname $0)/../../include.rc ++. $(dirname $0)/../../cluster.rc ++cleanup; ++ ++function check_peers { ++ $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l ++} ++ ++TEST launch_cluster 3 ++TEST $CLI_1 peer probe $H2; ++EXPECT_WITHIN $PROBE_TIMEOUT 1 check_peers ++ ++TEST $CLI_1 volume create $V0 replica 2 $H1:$B0/${V0} $H2:$B0/${V0} ++TEST $CLI_1 volume start $V0 ++ ++# Negative case with brick not killed && volume-id xattrs present ++TEST ! $CLI_1 volume reset-brick $V0 $H1:$B0/${V0} $H1:$B0/${V0} commit force ++ ++TEST $CLI_1 volume reset-brick $V0 $H1:$B0/${V0} start ++# Now test if reset-brick commit force works ++TEST $CLI_1 volume reset-brick $V0 $H1:$B0/${V0} $H1:$B0/${V0} commit force ++ ++cleanup; +diff --git a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c +index c127d64..abb44e0 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c ++++ b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c +@@ -343,7 +343,7 @@ glusterd_op_reset_brick (dict_t *dict, dict_t *rsp_dict) + gf_msg_debug (this->name, 0, "I AM THE DESTINATION HOST"); + ret = glusterd_volume_stop_glusterfs (volinfo, + src_brickinfo, +- _gf_true); ++ _gf_false); + if (ret) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, + GD_MSG_BRICK_STOP_FAIL, +-- +1.8.3.1 + diff --git a/SOURCES/0040-packaging-eventsapi-Make-Python-site-packages-variab.patch b/SOURCES/0040-packaging-eventsapi-Make-Python-site-packages-variab.patch deleted file mode 100644 index ac3e05b..0000000 --- a/SOURCES/0040-packaging-eventsapi-Make-Python-site-packages-variab.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 398636c8bd8ac0829ca1ef6000821026f2e3c003 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Wed, 24 Aug 2016 14:02:08 +0530 -Subject: [PATCH 40/86] packaging/eventsapi: Make Python site-packages variable global - -Python site-packages path is assigned when glupy is enabled. -Eventsapi will not work as expected if glupy is disabled using -./configure --disable-glupy. - -With this patch, all the Python variables are moved out of glupy -and used inside it. - -systemd services will fail if we import gluster.cliutils python library -which is installed in /usr/local/lib/python.2.7/site-packages or some -other location. With this patch, Environment variable is added in -systemd service file. - -> Reviewed-on: http://review.gluster.org/15305 -> Smoke: Gluster Build System -> Reviewed-by: Kaleb KEITHLEY -> Tested-by: Atin Mukherjee -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System - -BUG: 1351589 -Change-Id: I9416240f03889e3bbcb4cd375e27c784fa9ca277 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84744 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - configure.ac | 91 +++++++++++++++++------------ - extras/systemd/glustereventsd.service.in | 1 + - 2 files changed, 54 insertions(+), 38 deletions(-) - -diff --git a/configure.ac b/configure.ac -index e18309d..d77f41f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -502,6 +502,51 @@ if test "x${have_umount2}" = "xyes"; then - AC_DEFINE(HAVE_UMOUNT2, 1, [define if found umount2]) - fi - -+dnl Check Python Availability -+have_python=no -+AM_PATH_PYTHON(,, [:]) -+if test "$PYTHON" != ":"; then -+ have_python=yes -+fi -+ -+dnl Check if version matches that we require -+PYTHONDEV_CPPFLAGS= -+PYTHONDEV_CPPFLAGS= -+BUILD_PYTHON_SITE_PACKAGES= -+BUILD_PYTHON_INC= -+BUILD_PYTHON_LIB= -+have_python2=no -+have_Python_h=no -+ -+if echo $PYTHON_VERSION | grep ^2; then -+ have_python2=yes -+ -+ dnl Use pkg-config to get runtime search patch missing from ${PYTHON}-config -+ dnl Just do "true" on failure so that configure does not bail out -+ PKG_CHECK_MODULES([PYTHON], "python-$PYTHON_VERSION",,true) -+ -+ PYTHONDEV_CPPFLAGS="`${PYTHON}-config --cflags`" -+ dnl Edit out the flags that are not required or are conflicting -+ PYTHONDEV_CPPFLAGS=`echo ${PYTHONDEV_CPPFLAGS} | sed -e 's/-Wp,-D_FORTIFY_SOURCE=[[0-9]]//g'` -+ -+ dnl Find python libs at user configured libdir and also "lib" under prefix -+ PYTHONDEV_LDFLAGS="${PYTHON_LIBS} -L`${PYTHON}-config --prefix`/lib -L`${PYTHON}-config --prefix`/$libdir `${PYTHON}-config --ldflags`" -+ -+ BUILD_PYTHON_SITE_PACKAGES=`$PYTHON -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib(prefix="${exec_prefix}"))'` -+ BUILD_PYTHON_INC=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_inc()"` -+ BUILD_PYTHON_LIB=python$PYTHON_VERSION -+ -+ dnl Now check for python header using the include path obtained above -+ AC_CHECK_HEADERS([${BUILD_PYTHON_INC}/Python.h],[have_Python_h=yes],[]) -+fi -+ -+AC_SUBST(PYTHONDEV_CPPFLAGS) -+AC_SUBST(PYTHONDEV_LDFLAGS) -+AC_SUBST(BUILD_PYTHON_SITE_PACKAGES) -+AC_SUBST(BUILD_PYTHON_INC) -+AC_SUBST(BUILD_PYTHON_LIB) -+ -+ - # FUSE section - AC_ARG_ENABLE([fuse-client], - AC_HELP_STRING([--disable-fuse-client], -@@ -713,17 +758,11 @@ AC_ARG_ENABLE([events], - BUILD_EVENTS=no - EVENTS_ENABLED=0 - EVENTS_SUBDIR= --have_python2=no - if test "x$enable_events" != "xno"; then - EVENTS_SUBDIR=events - EVENTS_ENABLED=1 - - BUILD_EVENTS="yes" -- AM_PATH_PYTHON() -- dnl Check if version matches that we require -- if echo $PYTHON_VERSION | grep ^2; then -- have_python2=yes -- fi - - if test "x$have_python2" = "xno"; then - if test "x$enable_events" = "xyes"; then -@@ -1125,11 +1164,19 @@ sysconfdirtemp="${sysconfdir}" - eval sysconfdirtemp=\"${sysconfdirtemp}\" - SYSCONF_DIR=${sysconfdirtemp} - -+# Eval two times to expand fully. First eval replaces $exec_prefix into $prefix -+# Second eval will expand $prefix -+build_python_site_packages_temp="${BUILD_PYTHON_SITE_PACKAGES}" -+eval build_python_site_packages_temp=\"${build_python_site_packages_temp}\" -+eval build_python_site_packages_temp=\"${build_python_site_packages_temp}\" -+BUILD_PYTHON_SITE_PACKAGES_EXPANDED=${build_python_site_packages_temp} -+ - prefix=$prefix_temp - exec_prefix=$exec_prefix_temp - - AC_SUBST(SBIN_DIR) - AC_SUBST(SYSCONF_DIR) -+AC_SUBST(BUILD_PYTHON_SITE_PACKAGES_EXPANDED) - - # lazy umount emulation - UMOUNTD_SUBDIR="" -@@ -1184,42 +1231,15 @@ fi - - dnl glupy section - BUILD_GLUPY=no --have_python2=no --have_Python_h=no - - AC_ARG_ENABLE([glupy], AS_HELP_STRING([--enable-glupy], [build glupy])) - if test "x$enable_glupy" != "xno"; then enable_glupy=yes; fi - - if test "x$enable_glupy" = "xyes"; then -- dnl Check if python exists -- AM_PATH_PYTHON() -- dnl Check if version matches that we require -- if echo $PYTHON_VERSION | grep ^2; then -- have_python2=yes -- fi -- -- dnl Use pkg-config to get runtime search patch missing from ${PYTHON}-config -- dnl Just do "true" on failure so that configure does not bail out -- PKG_CHECK_MODULES([PYTHON], "python-$PYTHON_VERSION",,true) -- -- PYTHONDEV_CPPFLAGS="`${PYTHON}-config --cflags`" -- dnl Edit out the flags that are not required or are conflicting -- PYTHONDEV_CPPFLAGS=`echo ${PYTHONDEV_CPPFLAGS} | sed -e 's/-Wp,-D_FORTIFY_SOURCE=[[0-9]]//g'` -- -- dnl Find python libs at user configured libdir and also "lib" under prefix -- PYTHONDEV_LDFLAGS="${PYTHON_LIBS} -L`${PYTHON}-config --prefix`/lib -L`${PYTHON}-config --prefix`/$libdir `${PYTHON}-config --ldflags`" -- -- BUILD_PYTHON_SITE_PACKAGES=`$PYTHON -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib(prefix="${exec_prefix}"))'` -- BUILD_PYTHON_INC=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_inc()"` -- BUILD_PYTHON_LIB=python$PYTHON_VERSION -- - GLUPY_SUBDIR=glupy - GLUPY_SUBDIR_MAKEFILE=xlators/features/glupy/Makefile - GLUPY_SUBDIR_SRC_MAKEFILE=xlators/features/glupy/src/Makefile - -- dnl Now check for python header using the include path obtained above -- AC_CHECK_HEADERS([${BUILD_PYTHON_INC}/Python.h],[have_Python_h=yes],[]) -- - if test "x$have_python2" = "xyes" -a "x$have_Python_h" = "xyes"; then - case $host_os in - darwin*) -@@ -1240,11 +1260,6 @@ if test "x$enable_glupy" = "xyes"; then - - echo "building glupy with -isystem $BUILD_PYTHON_INC -l $BUILD_PYTHON_LIB" - -- AC_SUBST(PYTHONDEV_CPPFLAGS) -- AC_SUBST(PYTHONDEV_LDFLAGS) -- AC_SUBST(BUILD_PYTHON_SITE_PACKAGES) -- AC_SUBST(BUILD_PYTHON_INC) -- AC_SUBST(BUILD_PYTHON_LIB) - AC_SUBST(GLUPY_SUBDIR) - AC_SUBST(GLUPY_SUBDIR_MAKEFILE) - AC_SUBST(GLUPY_SUBDIR_SRC_MAKEFILE) -diff --git a/extras/systemd/glustereventsd.service.in b/extras/systemd/glustereventsd.service.in -index 2be3f25..75cca16 100644 ---- a/extras/systemd/glustereventsd.service.in -+++ b/extras/systemd/glustereventsd.service.in -@@ -3,6 +3,7 @@ Description=Gluster Events Notifier - After=syslog.target network.target - - [Service] -+Environment=PYTHONPATH=@BUILD_PYTHON_SITE_PACKAGES_EXPANDED@:$PYTHONPATH - Type=simple - ExecStart=@SBIN_DIR@/glustereventsd - ExecReload=/bin/kill -SIGUSR2 $MAINPID --- -1.7.1 - diff --git a/SOURCES/0041-eventsapi-Add-support-for-Client-side-Events.patch b/SOURCES/0041-eventsapi-Add-support-for-Client-side-Events.patch deleted file mode 100644 index dca9245..0000000 --- a/SOURCES/0041-eventsapi-Add-support-for-Client-side-Events.patch +++ /dev/null @@ -1,516 +0,0 @@ -From 432870b71d90e80f5a3d66d222c169171a44ec4e Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Wed, 17 Aug 2016 13:46:00 +0530 -Subject: [PATCH 41/86] eventsapi: Add support for Client side Events - -Client side gf_event uses ctx->cmd_args.volfile_server to push -notifications to the eventsd. - -Socket server changed from Unix domain socket to UDP to support -external events. - -Following to be addressed in different patch -- Port used for eventsd is 24009. Make it configurable - Already configurable in Server side. Configurable in gf_event API - is required. -- Auth Token yet to be added as discussed in - https://www.gluster.org/pipermail/gluster-devel/2016-August/050324.html - -> Reviewed-on: http://review.gluster.org/15189 -> Smoke: Gluster Build System -> Reviewed-by: Prashanth Pai -> Reviewed-by: Atin Mukherjee -> CentOS-regression: Gluster Build System -> NetBSD-regression: NetBSD Build System - -Change-Id: I159acf80b681d10b82d52cfb3ffdf85cb896542d -BUG: 1351589 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84745 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - events/eventskeygen.py | 4 +- - events/src/eventsapiconf.py.in | 8 ++- - events/src/eventsconfig.json | 3 +- - events/src/gf_event.py | 20 ++++++-- - events/src/glustereventsd.py | 95 ++++++++++------------------------------ - events/src/peer_eventsapi.py | 4 ++ - events/src/utils.py | 28 ++++++++++-- - extras/firewalld/glusterfs.xml | 1 + - libglusterfs/src/events.c | 90 ++++++++++++++++++++++++++------------ - 9 files changed, 139 insertions(+), 114 deletions(-) - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 7357d8e..468c795 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -48,7 +48,9 @@ ERRORS = ( - "EVENT_ERROR_INVALID_INPUTS", - "EVENT_ERROR_SOCKET", - "EVENT_ERROR_CONNECT", -- "EVENT_ERROR_SEND" -+ "EVENT_ERROR_SEND", -+ "EVENT_ERROR_RESOLVE", -+ "EVENT_ERROR_MSG_FORMAT", - ) - - if gen_header_type == "C_HEADER": -diff --git a/events/src/eventsapiconf.py.in b/events/src/eventsapiconf.py.in -index 03dd0e8..fad96ca 100644 ---- a/events/src/eventsapiconf.py.in -+++ b/events/src/eventsapiconf.py.in -@@ -9,7 +9,7 @@ - # cases as published by the Free Software Foundation. - # - --SERVER_ADDRESS = "@localstatedir@/run/gluster/events.sock" -+SERVER_ADDRESS = "0.0.0.0" - DEFAULT_CONFIG_FILE = "@SYSCONF_DIR@/glusterfs/eventsconfig.json" - CUSTOM_CONFIG_FILE_TO_SYNC = "/events/config.json" - CUSTOM_CONFIG_FILE = "@GLUSTERD_WORKDIR@" + CUSTOM_CONFIG_FILE_TO_SYNC -@@ -17,7 +17,9 @@ WEBHOOKS_FILE_TO_SYNC = "/events/webhooks.json" - WEBHOOKS_FILE = "@GLUSTERD_WORKDIR@" + WEBHOOKS_FILE_TO_SYNC - LOG_FILE = "@localstatedir@/log/glusterfs/events.log" - EVENTSD = "glustereventsd" --CONFIG_KEYS = ["log_level"] -+CONFIG_KEYS = ["log_level", "port"] - BOOL_CONFIGS = [] --RESTART_CONFIGS = [] -+INT_CONFIGS = ["port"] -+RESTART_CONFIGS = ["port"] - EVENTS_ENABLED = @EVENTS_ENABLED@ -+UUID_FILE = "@GLUSTERD_WORKDIR@/glusterd.info" -diff --git a/events/src/eventsconfig.json b/events/src/eventsconfig.json -index ce2c775..45730f9 100644 ---- a/events/src/eventsconfig.json -+++ b/events/src/eventsconfig.json -@@ -1,3 +1,4 @@ - { -- "log_level": "INFO" -+ "log_level": "INFO", -+ "port": 24009 - } -diff --git a/events/src/gf_event.py b/events/src/gf_event.py -index 20dfc8a..f9ece6a 100644 ---- a/events/src/gf_event.py -+++ b/events/src/gf_event.py -@@ -16,7 +16,7 @@ import time - from eventsapiconf import SERVER_ADDRESS, EVENTS_ENABLED - from eventtypes import all_events - --from utils import logger, setup_logger -+from utils import logger, setup_logger, get_config - - # Run this when this lib loads - setup_logger() -@@ -31,10 +31,9 @@ def gf_event(event_type, **kwargs): - return - - try: -- client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -- client.connect(SERVER_ADDRESS) -+ client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - except socket.error as e: -- logger.error("Unable to connect to events.sock: {0}".format(e)) -+ logger.error("Unable to connect to events Server: {0}".format(e)) - return - - # Convert key value args into KEY1=VALUE1;KEY2=VALUE2;.. -@@ -45,7 +44,18 @@ def gf_event(event_type, **kwargs): - # - msg = "{0} {1} {2}".format(int(time.time()), event_type, msg.strip(";")) - -+ port = get_config("port") -+ if port is None: -+ logger.error("Unable to get eventsd port details") -+ return -+ - try: -- client.sendall(msg) -+ sent = client.sendto(msg, (SERVER_ADDRESS, port)) -+ assert sent == len(msg) - except socket.error as e: - logger.error("Unable to Send message: {0}".format(e)) -+ except AssertionError: -+ logger.error("Unable to send message. Sent: {0}, Actual: {1}".format( -+ sent, len(msg))) -+ finally: -+ client.close() -diff --git a/events/src/glustereventsd.py b/events/src/glustereventsd.py -index 3fa5768..91a0743 100644 ---- a/events/src/glustereventsd.py -+++ b/events/src/glustereventsd.py -@@ -11,12 +11,10 @@ - # - - from __future__ import print_function --import asyncore --import socket --import os --from multiprocessing import Process, Queue - import sys - import signal -+import SocketServer -+import socket - - from eventtypes import all_events - import handlers -@@ -24,26 +22,19 @@ import utils - from eventsapiconf import SERVER_ADDRESS - from utils import logger - --# Global Queue, EventsHandler will add items to the queue --# and process_event will gets each item and handles it --events_queue = Queue() --events_server_pid = None - -+class GlusterEventsRequestHandler(SocketServer.BaseRequestHandler): - --def process_event(): -- """ -- Seperate process which handles all the incoming events from Gluster -- processes. -- """ -- while True: -- data = events_queue.get() -- logger.debug("EVENT: {0}".format(repr(data))) -+ def handle(self): -+ data = self.request[0].strip() -+ logger.debug("EVENT: {0} from {1}".format(repr(data), -+ self.client_address[0])) - try: - # Event Format - ts, key, value = data.split(" ", 2) - except ValueError: - logger.warn("Invalid Event Format {0}".format(data)) -- continue -+ return - - data_dict = {} - try: -@@ -51,7 +42,7 @@ def process_event(): - data_dict = dict(x.split('=') for x in value.split(';')) - except ValueError: - logger.warn("Unable to parse Event {0}".format(data)) -- continue -+ return - - try: - # Event Type to Function Map, Recieved event data will be in -@@ -75,68 +66,28 @@ def process_event(): - handlers.generic_handler(ts, int(key), data_dict) - - --def process_event_wrapper(): -- try: -- process_event() -- except KeyboardInterrupt: -- return -- -- --class GlusterEventsHandler(asyncore.dispatcher_with_send): -- -- def handle_read(self): -- data = self.recv(8192) -- if data: -- events_queue.put(data) -- self.send(data) -- -- --class GlusterEventsServer(asyncore.dispatcher): -- -- def __init__(self): -- global events_server_pid -- asyncore.dispatcher.__init__(self) -- # Start the Events listener process which listens to -- # the global queue -- p = Process(target=process_event_wrapper) -- p.start() -- events_server_pid = p.pid -- -- # Create UNIX Domain Socket, bind to path -- self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM) -- self.bind(SERVER_ADDRESS) -- self.listen(5) -- -- def handle_accept(self): -- pair = self.accept() -- if pair is not None: -- sock, addr = pair -- GlusterEventsHandler(sock) -- -- - def signal_handler_sigusr2(sig, frame): -- if events_server_pid is not None: -- os.kill(events_server_pid, signal.SIGUSR2) - utils.load_all() - - - def init_event_server(): - utils.setup_logger() -- -- # Delete Socket file if Exists -- try: -- os.unlink(SERVER_ADDRESS) -- except OSError: -- if os.path.exists(SERVER_ADDRESS): -- print ("Failed to cleanup socket file {0}".format(SERVER_ADDRESS), -- file=sys.stderr) -- sys.exit(1) -- - utils.load_all() - -- # Start the Eventing Server, UNIX DOMAIN SOCKET Server -- GlusterEventsServer() -- asyncore.loop() -+ port = utils.get_config("port") -+ if port is None: -+ sys.stderr.write("Unable to get Port details from Config\n") -+ sys.exit(1) -+ -+ # Start the Eventing Server, UDP Server -+ try: -+ server = SocketServer.ThreadingUDPServer( -+ (SERVER_ADDRESS, port), -+ GlusterEventsRequestHandler) -+ except socket.error as e: -+ sys.stderr.write("Failed to start Eventsd: {0}\n".format(e)) -+ sys.exit(1) -+ server.serve_forever() - - - def main(): -diff --git a/events/src/peer_eventsapi.py b/events/src/peer_eventsapi.py -index 7887d77..f444778 100644 ---- a/events/src/peer_eventsapi.py -+++ b/events/src/peer_eventsapi.py -@@ -31,6 +31,7 @@ from events.eventsapiconf import (WEBHOOKS_FILE_TO_SYNC, - EVENTSD, - CONFIG_KEYS, - BOOL_CONFIGS, -+ INT_CONFIGS, - RESTART_CONFIGS) - - -@@ -462,6 +463,9 @@ class ConfigSetCmd(Cmd): - if args.name in BOOL_CONFIGS: - v = boolify(args.value) - -+ if args.name in INT_CONFIGS: -+ v = int(args.value) -+ - new_data[args.name] = v - file_content_overwrite(CUSTOM_CONFIG_FILE, new_data) - -diff --git a/events/src/utils.py b/events/src/utils.py -index 772221a..386e8f2 100644 ---- a/events/src/utils.py -+++ b/events/src/utils.py -@@ -17,11 +17,10 @@ import requests - from eventsapiconf import (LOG_FILE, - WEBHOOKS_FILE, - DEFAULT_CONFIG_FILE, -- CUSTOM_CONFIG_FILE) -+ CUSTOM_CONFIG_FILE, -+ UUID_FILE) - import eventtypes - --from gluster.cliutils import get_node_uuid -- - - # Webhooks list - _webhooks = {} -@@ -32,6 +31,23 @@ _config = {} - - # Init Logger instance - logger = logging.getLogger(__name__) -+NodeID = None -+ -+ -+def get_node_uuid(): -+ val = None -+ with open(UUID_FILE) as f: -+ for line in f: -+ if line.startswith("UUID="): -+ val = line.strip().split("=")[-1] -+ break -+ return val -+ -+ -+def get_config(key): -+ if not _config: -+ load_config() -+ return _config.get(key, None) - - - def get_event_type_name(idx): -@@ -109,8 +125,12 @@ def load_all(): - - - def publish(ts, event_key, data): -+ global NodeID -+ if NodeID is None: -+ NodeID = get_node_uuid() -+ - message = { -- "nodeid": get_node_uuid(), -+ "nodeid": NodeID, - "ts": int(ts), - "event": get_event_type_name(event_key), - "message": data -diff --git a/extras/firewalld/glusterfs.xml b/extras/firewalld/glusterfs.xml -index f8efd90..7e17644 100644 ---- a/extras/firewalld/glusterfs.xml -+++ b/extras/firewalld/glusterfs.xml -@@ -4,6 +4,7 @@ - Default ports for gluster-distributed storage - - -+ - - - -diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c -index f93934d..b7b513e 100644 ---- a/libglusterfs/src/events.c -+++ b/libglusterfs/src/events.c -@@ -16,73 +16,107 @@ - #include - #include - #include -+#include -+#include -+#include -+ - #include "syscall.h" - #include "mem-pool.h" -+#include "glusterfs.h" -+#include "globals.h" - #include "events.h" - - --#define EVENT_PATH DATADIR "/run/gluster/events.sock" --#define EVENTS_MSG_MAX 2048 -+#define EVENT_HOST "127.0.0.1" -+#define EVENT_PORT 24009 - - - int - gf_event (eventtypes_t event, char *fmt, ...) - { -- int ret = 0; -- int sock = -1; -- char eventstr[EVENTS_MSG_MAX] = ""; -- struct sockaddr_un server; -- va_list arguments; -- char *msg = NULL; -- size_t eventstr_size = 0; -+ int ret = 0; -+ int sock = -1; -+ char *eventstr = NULL; -+ struct sockaddr_in server; -+ va_list arguments; -+ char *msg = NULL; -+ glusterfs_ctx_t *ctx = NULL; -+ struct hostent *host_data; -+ char *host = NULL; -+ -+ /* Global context */ -+ ctx = THIS->ctx; - - if (event < 0 || event >= EVENT_LAST) { - ret = EVENT_ERROR_INVALID_INPUTS; - goto out; - } - -- sock = socket(AF_UNIX, SOCK_STREAM, 0); -+ /* Initialize UDP socket */ -+ sock = socket (AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - ret = EVENT_ERROR_SOCKET; - goto out; - } -- server.sun_family = AF_UNIX; -- strcpy(server.sun_path, EVENT_PATH); - -- if (connect(sock, -- (struct sockaddr *) &server, -- sizeof(struct sockaddr_un)) < 0) { -- ret = EVENT_ERROR_CONNECT; -- goto out; -+ /* Get Host name to send message */ -+ if (ctx && ctx->cmd_args.volfile_server) { -+ /* If it is client code then volfile_server is set -+ use that information to push the events. */ -+ host_data = gethostbyname (ctx->cmd_args.volfile_server); -+ if (host_data == NULL) { -+ ret = EVENT_ERROR_RESOLVE; -+ goto out; -+ } -+ host = inet_ntoa (*(struct in_addr *)(host_data->h_addr)); -+ } else { -+ /* Localhost, Use the defined IP for localhost */ -+ host = EVENT_HOST; - } - -+ /* Socket Configurations */ -+ server.sin_family = AF_INET; -+ server.sin_port = htons (EVENT_PORT); -+ server.sin_addr.s_addr = inet_addr (host); -+ memset (&server.sin_zero, '\0', sizeof (server.sin_zero)); -+ - va_start (arguments, fmt); - ret = gf_vasprintf (&msg, fmt, arguments); - va_end (arguments); -+ - if (ret < 0) { - ret = EVENT_ERROR_INVALID_INPUTS; - goto out; - } - -- eventstr_size = snprintf(NULL, 0, "%u %d %s", (unsigned)time(NULL), -- event, msg); -+ ret = gf_asprintf (&eventstr, "%u %d %s", -+ (unsigned)time(NULL), event, msg); - -- if (eventstr_size + 1 > EVENTS_MSG_MAX) { -- eventstr_size = EVENTS_MSG_MAX - 1; -+ if (ret <= 0) { -+ ret = EVENT_ERROR_MSG_FORMAT; -+ goto out; - } - -- snprintf(eventstr, eventstr_size+1, "%u %d %s", -- (unsigned)time(NULL), event, msg); -- -- if (sys_write(sock, eventstr, strlen(eventstr)) <= 0) { -+ /* Send Message */ -+ if (sendto (sock, eventstr, strlen (eventstr), -+ 0, (struct sockaddr *)&server, sizeof (server)) <= 0) { - ret = EVENT_ERROR_SEND; -- goto out; - } - - ret = EVENT_SEND_OK; - - out: -- sys_close(sock); -- GF_FREE(msg); -+ if (sock >= 0) { -+ sys_close (sock); -+ } -+ -+ /* Allocated by gf_vasprintf */ -+ if (msg) -+ GF_FREE (msg); -+ -+ /* Allocated by gf_asprintf */ -+ if (eventstr) -+ GF_FREE (eventstr); -+ - return ret; - } --- -1.7.1 - diff --git a/SOURCES/0041-glusterd-persist-brickinfo-s-port-change-into-gluste.patch b/SOURCES/0041-glusterd-persist-brickinfo-s-port-change-into-gluste.patch new file mode 100644 index 0000000..736ebe3 --- /dev/null +++ b/SOURCES/0041-glusterd-persist-brickinfo-s-port-change-into-gluste.patch @@ -0,0 +1,193 @@ +From 548895f0333a0706ec9475efc3b28456d591f093 Mon Sep 17 00:00:00 2001 +From: Gaurav Yadav +Date: Fri, 27 Oct 2017 16:04:46 +0530 +Subject: [PATCH 41/74] glusterd: persist brickinfo's port change into + glusterd's store + +Problem: +Consider a case where node reboot is performed and prior to reboot +brick was listening to 49153. Post reboot glusterd assigned 49152 +to brick and started the brick process but the new port was never +persisted. Now when glusterd restarts glusterd always read the port +from its persisted store i.e 49153 however pmap signin happens with +the correct port i.e 49152. + +Fix: +Make sure when glusterd_brick_start is called, glusterd_store_volinfo is +eventually invoked. + +>upstream mainline patch : https://review.gluster.org/#/c/18579/ + +Change-Id: Ic0efbd48c51d39729ed951a42922d0e59f7115a1 +Signed-off-by: Gaurav Yadav +Reviewed-on: https://code.engineering.redhat.com/gerrit/121878 +Reviewed-by: Atin Mukherjee +Tested-by: Atin Mukherjee +Tested-by: RHGS Build Bot +--- + xlators/mgmt/glusterd/src/glusterd-handshake.c | 18 +++++++++--------- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 9 ++++++++- + xlators/mgmt/glusterd/src/glusterd-server-quorum.c | 16 ++++++++++++++++ + xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c | 10 ++++++++++ + xlators/mgmt/glusterd/src/glusterd-utils.c | 19 +++++++++++++++++++ + 5 files changed, 62 insertions(+), 10 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c +index c7e419c..8dfb528 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c +@@ -658,6 +658,15 @@ glusterd_create_missed_snap (glusterd_missed_snap_info *missed_snapinfo, + } + + brickinfo->snap_status = 0; ++ ret = glusterd_brick_start (snap_vol, brickinfo, _gf_false); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_WARNING, 0, ++ GD_MSG_BRICK_DISCONNECTED, "starting the " ++ "brick %s:%s for the snap %s failed", ++ brickinfo->hostname, brickinfo->path, ++ snap->snapname); ++ goto out; ++ } + ret = glusterd_store_volinfo (snap_vol, + GLUSTERD_VOLINFO_VER_AC_NONE); + if (ret) { +@@ -668,15 +677,6 @@ glusterd_create_missed_snap (glusterd_missed_snap_info *missed_snapinfo, + goto out; + } + +- ret = glusterd_brick_start (snap_vol, brickinfo, _gf_false); +- if (ret) { +- gf_msg (this->name, GF_LOG_WARNING, 0, +- GD_MSG_BRICK_DISCONNECTED, "starting the " +- "brick %s:%s for the snap %s failed", +- brickinfo->hostname, brickinfo->path, +- snap->snapname); +- goto out; +- } + out: + if (device) + GF_FREE (device); +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 96e0860..9641b4f 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -2415,8 +2415,15 @@ glusterd_start_bricks (glusterd_volinfo_t *volinfo) + brickinfo->path); + goto out; + } +- } + ++ } ++ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_NONE); ++ if (ret) { ++ gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_STORE_FAIL, ++ "Failed to write volinfo for volume %s", ++ volinfo->volname); ++ goto out; ++ } + ret = 0; + out: + return ret; +diff --git a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +index a4637f8..659ff9d 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c ++++ b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +@@ -12,6 +12,7 @@ + #include "glusterd-utils.h" + #include "glusterd-messages.h" + #include "glusterd-server-quorum.h" ++#include "glusterd-store.h" + #include "glusterd-syncop.h" + #include "glusterd-op-sm.h" + +@@ -309,6 +310,7 @@ void + glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo, + gf_boolean_t meets_quorum) + { ++ int ret = -1; + glusterd_brickinfo_t *brickinfo = NULL; + gd_quorum_status_t quorum_status = NOT_APPLICABLE_QUORUM; + gf_boolean_t follows_quorum = _gf_false; +@@ -365,6 +367,20 @@ glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo, + glusterd_brick_start (volinfo, brickinfo, _gf_false); + } + volinfo->quorum_status = quorum_status; ++ if (quorum_status == MEETS_QUORUM) { ++ /* bricks might have been restarted and so as the port change ++ * might have happened ++ */ ++ ret = glusterd_store_volinfo (volinfo, ++ GLUSTERD_VOLINFO_VER_AC_NONE); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_VOLINFO_STORE_FAIL, ++ "Failed to write volinfo for volume %s", ++ volinfo->volname); ++ goto out; ++ } ++ } + out: + return; + } +diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +index 6fb49c3..4cbade1 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +@@ -1680,6 +1680,16 @@ glusterd_import_friend_snap (dict_t *peer_data, int32_t snap_count, + } + if (glusterd_is_volume_started (snap_vol)) { + (void) glusterd_start_bricks (snap_vol); ++ ret = glusterd_store_volinfo ++ (snap_vol, ++ GLUSTERD_VOLINFO_VER_AC_NONE); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_VOLINFO_STORE_FAIL, "Failed to " ++ "write volinfo for volume %s", ++ snap_vol->volname); ++ goto out; ++ } + } else { + (void) glusterd_stop_bricks(snap_vol); + } +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index f34e218..bb236df 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -6003,6 +6003,15 @@ glusterd_restart_bricks (glusterd_conf_t *conf) + glusterd_brick_start (volinfo, brickinfo, + _gf_false); + } ++ ret = glusterd_store_volinfo ++ (volinfo, GLUSTERD_VOLINFO_VER_AC_NONE); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_VOLINFO_STORE_FAIL, "Failed to " ++ "write volinfo for volume %s", ++ volinfo->volname); ++ goto out; ++ } + } + } + +@@ -6034,6 +6043,16 @@ glusterd_restart_bricks (glusterd_conf_t *conf) + glusterd_brick_start (volinfo, brickinfo, + _gf_false); + } ++ ret = glusterd_store_volinfo ++ (volinfo, GLUSTERD_VOLINFO_VER_AC_NONE); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_VOLINFO_STORE_FAIL, "Failed to " ++ "write volinfo for volume %s", ++ volinfo->volname); ++ goto out; ++ } ++ + } + } + ret = 0; +-- +1.8.3.1 + diff --git a/SOURCES/0042-eventsapi-Fix-Volume-Stop-and-delete-prompt-issue.patch b/SOURCES/0042-eventsapi-Fix-Volume-Stop-and-delete-prompt-issue.patch deleted file mode 100644 index 77de5a2..0000000 --- a/SOURCES/0042-eventsapi-Fix-Volume-Stop-and-delete-prompt-issue.patch +++ /dev/null @@ -1,64 +0,0 @@ -From e522517af3b4a1c449a8e74386f8c41d16e4cf16 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Mon, 5 Sep 2016 11:15:10 +0530 -Subject: [PATCH 42/86] eventsapi: Fix Volume Stop and delete prompt issue - -During Volume Stop and Delete, event is emitted even if -prompt answer is No. - -Also added "force" details in START and STOP events. - -> Reviewed-on: http://review.gluster.org/15399 -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Atin Mukherjee - -BUG: 1351589 -Change-Id: I986dcff7154b584f6ed44b533d4eeabe82815235 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84746 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 10 ++++++---- - 1 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 09cfcee..3a7c9ed 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -321,7 +321,7 @@ out: - - CLI_STACK_DESTROY (frame); - -- if (ret == 0) { -+ if (ret == 0 && GF_ANSWER_YES == answer) { - gf_event (EVENT_VOLUME_DELETE, "name=%s", (char *)words[2]); - } - -@@ -400,7 +400,8 @@ out: - CLI_STACK_DESTROY (frame); - - if (ret == 0) { -- gf_event (EVENT_VOLUME_START, "name=%s", (char *)words[2]); -+ gf_event (EVENT_VOLUME_START, "name=%s;force=%d", -+ (char *)words[2], (flags & GF_CLI_FLAG_OP_FORCE)); - } - - return ret; -@@ -535,8 +536,9 @@ out: - - CLI_STACK_DESTROY (frame); - -- if (ret == 0) { -- gf_event (EVENT_VOLUME_STOP, "name=%s", (char *)words[2]); -+ if (ret == 0 && GF_ANSWER_YES == answer) { -+ gf_event (EVENT_VOLUME_STOP, "name=%s;force=%d", -+ (char *)words[2], (flags & GF_CLI_FLAG_OP_FORCE)); - } - - return ret; --- -1.7.1 - diff --git a/SOURCES/0042-glusterd-restart-the-brick-if-qorum-status-is-NOT_AP.patch b/SOURCES/0042-glusterd-restart-the-brick-if-qorum-status-is-NOT_AP.patch new file mode 100644 index 0000000..42fd2a4 --- /dev/null +++ b/SOURCES/0042-glusterd-restart-the-brick-if-qorum-status-is-NOT_AP.patch @@ -0,0 +1,39 @@ +From 4ea251b0a23ae8fc0740abc2c5d85c09c31e0c70 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Mon, 6 Nov 2017 13:23:32 +0530 +Subject: [PATCH 42/74] glusterd: restart the brick if qorum status is + NOT_APPLICABLE_QUORUM + +If a volume is not having server quorum enabled and in a trusted storage +pool all the glusterd instances from other peers are down, on restarting +glusterd the brick start trigger doesn't happen resulting into the +brick not coming up. + +> mainline patch : https://review.gluster.org/18669 + +Change-Id: If1458e03b50a113f1653db553bb2350d11577539 +BUG: 1509102 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/123055 +Reviewed-by: Gaurav Yadav +--- + xlators/mgmt/glusterd/src/glusterd-server-quorum.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +index 659ff9d..4706403 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c ++++ b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +@@ -341,7 +341,8 @@ glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo, + * the bricks that are down are brought up again. In this process it + * also brings up the brick that is purposefully taken down. + */ +- if (volinfo->quorum_status == quorum_status) ++ if (quorum_status != NOT_APPLICABLE_QUORUM && ++ volinfo->quorum_status == quorum_status) + goto out; + + if (quorum_status == MEETS_QUORUM) { +-- +1.8.3.1 + diff --git a/SOURCES/0043-features-ganesha-remove-ganesha-xlator-from-client-g.patch b/SOURCES/0043-features-ganesha-remove-ganesha-xlator-from-client-g.patch deleted file mode 100644 index 239bb18..0000000 --- a/SOURCES/0043-features-ganesha-remove-ganesha-xlator-from-client-g.patch +++ /dev/null @@ -1,69 +0,0 @@ -From e5db9f2ea99770e3dc6dfa613872012d45e7c786 Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Thu, 7 Jul 2016 15:55:07 +0530 -Subject: [PATCH 43/86] features/ganesha : remove ganesha xlator from client graph - -The ganesha introduced in dummy xlator in the client graph, which is used -for introducing the cli options. When the volume set command "ganesha.enable" -ran, this xlator will add into client graph but never removed from it. In my -opinion there is no point in adding the ganesha xlator in the client graph - -Upstream refernce : ->Change-Id: I926c4b4adf991361aa459679e275cb58246c5294 ->BUG: 1349270 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/14871 ->CentOS-regression: Gluster Build System ->Tested-by: Gluster Build System ->Reviewed-by: Kaleb KEITHLEY ->NetBSD-regression: NetBSD Build System ->Smoke: Gluster Build System ->Reviewed-by: Atin Mukherjee ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: I926c4b4adf991361aa459679e275cb58246c5294 -BUG: 1348949 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84774 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - xlators/mgmt/glusterd/src/glusterd-volgen.c | 22 ---------------------- - 1 files changed, 0 insertions(+), 22 deletions(-) - -diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c -index b6b4914..9e66547 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-volgen.c -+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c -@@ -3982,28 +3982,6 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, - goto out; - } - -- ret = dict_get_str_boolean (set_dict, "ganesha.enable", _gf_false); -- -- if (ret == -1) { -- gf_msg (this->name, GF_LOG_WARNING, errno, -- GD_MSG_DICT_GET_FAILED, "setting ganesha.enable" -- "option failed."); -- goto out; -- } -- -- if (ret) { -- xl = volgen_graph_add (graph, "features/ganesha", volname); -- -- if (!xl) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_GRAPH_FEATURE_ADD_FAIL, -- "failed to add" -- "add features/ganesha to graph"); -- ret = -1; -- goto out; -- } -- } -- - /* add debug translators depending on the options */ - ret = check_and_add_debug_xl (graph, set_dict, volname, - "client"); --- -1.7.1 - diff --git a/SOURCES/0043-glusterd-clean-up-portmap-on-brick-disconnect.patch b/SOURCES/0043-glusterd-clean-up-portmap-on-brick-disconnect.patch new file mode 100644 index 0000000..ac60763 --- /dev/null +++ b/SOURCES/0043-glusterd-clean-up-portmap-on-brick-disconnect.patch @@ -0,0 +1,173 @@ +From 385b61f9a6f818c2810cc0a2223c9d71340cd345 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Tue, 17 Oct 2017 21:32:44 +0530 +Subject: [PATCH 43/74] glusterd: clean up portmap on brick disconnect + +GlusterD's portmap entry for a brick is cleaned up when a PMAP_SIGNOUT event is +initiated by the brick process at the shutdown. But if the brick process crashes +or gets killed through SIGKILL then this event is not initiated and glusterd +ends up with a stale port. Since GlusterD's portmap traversal happens both ways, +forward for allocation and backward for registry search, there is a possibility +that glusterd might end up running with a stale port for a brick which +eventually will end up with clients to fail to connect to the bricks. + +Solution is to clean up the port entry in case the process is down as +part of the brick disconnect event. Although with this the handling +PMAP_SIGNOUT event becomes redundant in most of the cases, but this is +the safeguard method to avoid glusterd getting into the stale port +issues. + +>mainline patch : https://review.gluster.org/#/c/18541 + +Change-Id: I04c5be6d11e772ee4de16caf56dbb37d5c944303 +BUG: 1503244 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/123057 +Reviewed-by: Gaurav Yadav +--- + xlators/mgmt/glusterd/src/glusterd-handler.c | 25 +++++++++++++++++++++++++ + xlators/mgmt/glusterd/src/glusterd-pmap.c | 26 +++++++++++++++++--------- + xlators/mgmt/glusterd/src/glusterd-pmap.h | 3 ++- + xlators/mgmt/glusterd/src/glusterd.c | 3 ++- + 4 files changed, 46 insertions(+), 11 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c +index af9a796..34e751c 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handler.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handler.c +@@ -5974,8 +5974,10 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, + glusterd_volinfo_t *volinfo = NULL; + xlator_t *this = NULL; + int temp = 0; ++ int32_t pid = -1; + glusterd_brickinfo_t *brickinfo_tmp = NULL; + glusterd_brick_proc_t *brick_proc = NULL; ++ char pidfile[PATH_MAX] = {0}; + + brickid = mydata; + if (!brickid) +@@ -6074,6 +6076,29 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, + "peer=%s;volume=%s;brick=%s", + brickinfo->hostname, volinfo->volname, + brickinfo->path); ++ /* In case of an abrupt shutdown of a brick PMAP_SIGNOUT ++ * event is not received by glusterd which can lead to a ++ * stale port entry in glusterd, so forcibly clean up ++ * the same if the process is not running ++ */ ++ GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, ++ brickinfo, conf); ++ if (!gf_is_service_running (pidfile, &pid)) { ++ ret = pmap_registry_remove ( ++ THIS, brickinfo->port, ++ brickinfo->path, ++ GF_PMAP_PORT_BRICKSERVER, ++ NULL, _gf_true); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_WARNING, ++ GD_MSG_PMAP_REGISTRY_REMOVE_FAIL, ++ 0, "Failed to remove pmap " ++ "registry for port %d for " ++ "brick %s", brickinfo->port, ++ brickinfo->path); ++ ret = 0; ++ } ++ } + } + + if (is_brick_mx_enabled()) { +diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c +index 2a75476..1b547e7 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-pmap.c ++++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c +@@ -239,7 +239,8 @@ pmap_assign_port (xlator_t *this, int old_port, const char *path) + + if (old_port) { + ret = pmap_registry_remove (this, 0, path, +- GF_PMAP_PORT_BRICKSERVER, NULL); ++ GF_PMAP_PORT_BRICKSERVER, NULL, ++ _gf_false); + if (ret) { + gf_msg (this->name, GF_LOG_WARNING, + GD_MSG_PMAP_REGISTRY_REMOVE_FAIL, 0, "Failed to" +@@ -342,7 +343,8 @@ pmap_registry_extend (xlator_t *this, int port, const char *brickname) + + int + pmap_registry_remove (xlator_t *this, int port, const char *brickname, +- gf_pmap_port_type_t type, void *xprt) ++ gf_pmap_port_type_t type, void *xprt, ++ gf_boolean_t brick_disconnect) + { + struct pmap_registry *pmap = NULL; + int p = 0; +@@ -389,11 +391,16 @@ remove: + * can delete the entire entry. + */ + if (!pmap->ports[p].xprt) { +- brick_str = pmap->ports[p].brickname; +- if (brick_str) { +- while (*brick_str != '\0') { +- if (*(brick_str++) != ' ') { +- goto out; ++ /* If the signout call is being triggered by brick disconnect ++ * then clean up all the bricks (in case of brick mux) ++ */ ++ if (!brick_disconnect) { ++ brick_str = pmap->ports[p].brickname; ++ if (brick_str) { ++ while (*brick_str != '\0') { ++ if (*(brick_str++) != ' ') { ++ goto out; ++ } + } + } + } +@@ -548,14 +555,15 @@ __gluster_pmap_signout (rpcsvc_request_t *req) + goto fail; + } + rsp.op_ret = pmap_registry_remove (THIS, args.port, args.brick, +- GF_PMAP_PORT_BRICKSERVER, req->trans); ++ GF_PMAP_PORT_BRICKSERVER, req->trans, ++ _gf_false); + + ret = glusterd_get_brickinfo (THIS, args.brick, args.port, &brickinfo); + if (args.rdma_port) { + snprintf(brick_path, PATH_MAX, "%s.rdma", args.brick); + rsp.op_ret = pmap_registry_remove (THIS, args.rdma_port, + brick_path, GF_PMAP_PORT_BRICKSERVER, +- req->trans); ++ req->trans, _gf_false); + } + /* Update portmap status on brickinfo */ + if (brickinfo) +diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.h b/xlators/mgmt/glusterd/src/glusterd-pmap.h +index 9965a95..253b4cc 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-pmap.h ++++ b/xlators/mgmt/glusterd/src/glusterd-pmap.h +@@ -42,7 +42,8 @@ int pmap_registry_bind (xlator_t *this, int port, const char *brickname, + gf_pmap_port_type_t type, void *xprt); + int pmap_registry_extend (xlator_t *this, int port, const char *brickname); + int pmap_registry_remove (xlator_t *this, int port, const char *brickname, +- gf_pmap_port_type_t type, void *xprt); ++ gf_pmap_port_type_t type, void *xprt, ++ gf_boolean_t brick_disconnect); + int pmap_registry_search (xlator_t *this, const char *brickname, + gf_pmap_port_type_t type, gf_boolean_t destroy); + struct pmap_registry *pmap_registry_get (xlator_t *this); +diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c +index 4887ff4..81a3206 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.c ++++ b/xlators/mgmt/glusterd/src/glusterd.c +@@ -424,7 +424,8 @@ glusterd_rpcsvc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, + pthread_mutex_lock (&priv->xprt_lock); + list_del (&xprt->list); + pthread_mutex_unlock (&priv->xprt_lock); +- pmap_registry_remove (this, 0, NULL, GF_PMAP_PORT_ANY, xprt); ++ pmap_registry_remove (this, 0, NULL, GF_PMAP_PORT_ANY, xprt, ++ _gf_false); + break; + } + +-- +1.8.3.1 + diff --git a/SOURCES/0044-eventsapi-Add-Init-scripts-for-different-distributio.patch b/SOURCES/0044-eventsapi-Add-Init-scripts-for-different-distributio.patch deleted file mode 100644 index 093645b..0000000 --- a/SOURCES/0044-eventsapi-Add-Init-scripts-for-different-distributio.patch +++ /dev/null @@ -1,754 +0,0 @@ -From a3f0b6fce07d6849d7b98353067c4c9f1e926751 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Wed, 31 Aug 2016 08:33:44 +0530 -Subject: [PATCH 44/86] eventsapi: Add Init scripts for different distributions - -Added init scripts for -- SysvInit(CentOS 6 or Red Hat 6) -- rc.d (FreeBSD) - -Most of the latest distributions are using systemd. Support to be -added for other distributions which are not using systemd. - -Removed systemctl wrapper functions(start/stop/status) from -gluster-eventsapi CLI(peer_eventsapi.py). Status and Reload -re-implemented using pid file check. - -Added pid file support for glustereventsd. - -Following dependencies removed -python-flask - Only used for example dashboard. User can install -if required. -python-fasteners - Not available for EPEL 6, added custom code using -fcntl as replacement. - -> Reviewed-on: http://review.gluster.org/15367 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Niels de Vos -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Kaleb KEITHLEY - -BUG: 1351589 -Change-Id: I26792eae9b11e93304f70b3997cd7d8d03b067f4 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84747 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - configure.ac | 2 + - events/src/eventsapiconf.py.in | 1 + - events/src/glustereventsd.py | 21 ++++- - events/src/peer_eventsapi.py | 160 +++++++++--------------------- - events/src/utils.py | 77 ++++++++++++++ - extras/init.d/Makefile.am | 11 ++- - extras/init.d/glustereventsd-FreeBSD.in | 19 ++++ - extras/init.d/glustereventsd-Redhat.in | 129 ++++++++++++++++++++++++ - extras/systemd/glustereventsd.service.in | 3 +- - glusterfs.spec.in | 19 +++- - 10 files changed, 322 insertions(+), 120 deletions(-) - create mode 100644 extras/init.d/glustereventsd-FreeBSD.in - create mode 100644 extras/init.d/glustereventsd-Redhat.in - -diff --git a/configure.ac b/configure.ac -index d77f41f..d84398d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -200,6 +200,8 @@ AC_CONFIG_FILES([Makefile - extras/init.d/glusterd-Redhat - extras/init.d/glusterd-FreeBSD - extras/init.d/glusterd-SuSE -+ extras/init.d/glustereventsd-Redhat -+ extras/init.d/glustereventsd-FreeBSD - extras/ganesha/Makefile - extras/ganesha/config/Makefile - extras/ganesha/scripts/Makefile -diff --git a/events/src/eventsapiconf.py.in b/events/src/eventsapiconf.py.in -index fad96ca..ecccd3d 100644 ---- a/events/src/eventsapiconf.py.in -+++ b/events/src/eventsapiconf.py.in -@@ -23,3 +23,4 @@ INT_CONFIGS = ["port"] - RESTART_CONFIGS = ["port"] - EVENTS_ENABLED = @EVENTS_ENABLED@ - UUID_FILE = "@GLUSTERD_WORKDIR@/glusterd.info" -+PID_FILE = "@localstatedir@/run/glustereventsd.pid" -diff --git a/events/src/glustereventsd.py b/events/src/glustereventsd.py -index 91a0743..d057e09 100644 ---- a/events/src/glustereventsd.py -+++ b/events/src/glustereventsd.py -@@ -15,12 +15,13 @@ import sys - import signal - import SocketServer - import socket -+from argparse import ArgumentParser, RawDescriptionHelpFormatter - - from eventtypes import all_events - import handlers - import utils --from eventsapiconf import SERVER_ADDRESS --from utils import logger -+from eventsapiconf import SERVER_ADDRESS, PID_FILE -+from utils import logger, PidFile, PidFileLockFailed - - - class GlusterEventsRequestHandler(SocketServer.BaseRequestHandler): -@@ -90,9 +91,23 @@ def init_event_server(): - server.serve_forever() - - -+def get_args(): -+ parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter, -+ description=__doc__) -+ parser.add_argument("-p", "--pid-file", help="PID File", -+ default=PID_FILE) -+ -+ return parser.parse_args() -+ -+ - def main(): -+ args = get_args() - try: -- init_event_server() -+ with PidFile(args.pid_file): -+ init_event_server() -+ except PidFileLockFailed as e: -+ sys.stderr.write("Failed to get lock for pid file({0}): {1}".format( -+ args.pid_file, e)) - except KeyboardInterrupt: - sys.exit(1) - -diff --git a/events/src/peer_eventsapi.py b/events/src/peer_eventsapi.py -index f444778..7f80f79 100644 ---- a/events/src/peer_eventsapi.py -+++ b/events/src/peer_eventsapi.py -@@ -14,14 +14,17 @@ from __future__ import print_function - import os - import json - from errno import EEXIST -+import fcntl -+from errno import EACCES, EAGAIN -+import signal - - import requests --import fasteners - from prettytable import PrettyTable - - from gluster.cliutils import (Cmd, execute, node_output_ok, node_output_notok, - sync_file_to_peers, GlusterCmdException, - output_error, execute_in_peers, runcli) -+from events.utils import LockedOpen - - from events.eventsapiconf import (WEBHOOKS_FILE_TO_SYNC, - WEBHOOKS_FILE, -@@ -32,6 +35,7 @@ from events.eventsapiconf import (WEBHOOKS_FILE_TO_SYNC, - CONFIG_KEYS, - BOOL_CONFIGS, - INT_CONFIGS, -+ PID_FILE, - RESTART_CONFIGS) - - -@@ -78,67 +82,36 @@ def mkdirp(path, exit_on_err=False, logger=None): - output_error("Fail to create dir %s: %s" % (path, e)) - - --def is_enabled(service): -- rc, out, err = execute(["systemctl", "is-enabled", service]) -- return rc == 0 -- -- --def is_active(service): -- rc, out, err = execute(["systemctl", "is-active", service]) -- return rc == 0 -- -- --def enable_service(service): -- if not is_enabled(service): -- cmd = ["systemctl", "enable", service] -- return execute(cmd) -- -- return (0, "", "") -- -- --def disable_service(service): -- if is_enabled(service): -- cmd = ["systemctl", "disable", service] -- return execute(cmd) -- -- return (0, "", "") -- -- --def start_service(service): -- rc, out, err = enable_service(service) -- if rc != 0: -- return (rc, out, err) -- -- cmd = ["systemctl", "start", service] -- return execute(cmd) -- -- --def stop_service(service): -- rc, out, err = disable_service(service) -- if rc != 0: -- return (rc, out, err) -- -- cmd = ["systemctl", "stop", service] -- return execute(cmd) -- -- --def restart_service(service): -- rc, out, err = stop_service(service) -- if rc != 0: -- return (rc, out, err) -- -- return start_service(service) -+def is_active(): -+ state = False -+ try: -+ with open(PID_FILE, "a+") as f: -+ fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) -+ state = False -+ except (IOError, OSError) as e: -+ if e.errno in (EACCES, EAGAIN): -+ # cannot grab. so, process still running..move on -+ state = True -+ else: -+ state = False -+ return state - - --def reload_service(service): -- if is_active(service): -- cmd = ["systemctl", "reload", service] -- return execute(cmd) -+def reload_service(): -+ pid = None -+ if is_active(): -+ with open(PID_FILE) as f: -+ try: -+ pid = int(f.read().strip()) -+ except ValueError: -+ pid = None -+ if pid is not None: -+ os.kill(pid, signal.SIGUSR2) - - return (0, "", "") - - --def sync_to_peers(restart=False): -+def sync_to_peers(): - if os.path.exists(WEBHOOKS_FILE): - try: - sync_file_to_peers(WEBHOOKS_FILE_TO_SYNC) -@@ -153,11 +126,7 @@ def sync_to_peers(restart=False): - output_error("Failed to sync Config file: [Error: {0}]" - "{1}".format(e[0], e[2])) - -- action = "node-reload" -- if restart: -- action = "node-restart" -- -- out = execute_in_peers(action) -+ out = execute_in_peers("node-reload") - table = PrettyTable(["NODE", "NODE STATUS", "SYNC STATUS"]) - table.align["NODE STATUS"] = "r" - table.align["SYNC STATUS"] = "r" -@@ -204,53 +173,11 @@ def action_handle(action): - print (table) - - --class NodeStart(Cmd): -- name = "node-start" -- -- def run(self, args): -- node_output_handle(start_service(EVENTSD)) -- -- --class StartCmd(Cmd): -- name = "start" -- -- def run(self, args): -- action_handle("start") -- -- --class NodeStop(Cmd): -- name = "node-stop" -- -- def run(self, args): -- node_output_handle(stop_service(EVENTSD)) -- -- --class StopCmd(Cmd): -- name = "stop" -- -- def run(self, args): -- action_handle("stop") -- -- --class NodeRestart(Cmd): -- name = "node-restart" -- -- def run(self, args): -- node_output_handle(restart_service(EVENTSD)) -- -- --class RestartCmd(Cmd): -- name = "restart" -- -- def run(self, args): -- action_handle("restart") -- -- - class NodeReload(Cmd): - name = "node-reload" - - def run(self, args): -- node_output_handle(reload_service(EVENTSD)) -+ node_output_handle(reload_service()) - - - class ReloadCmd(Cmd): -@@ -264,7 +191,7 @@ class NodeStatus(Cmd): - name = "node-status" - - def run(self, args): -- node_output_ok("UP" if is_active(EVENTSD) else "DOWN") -+ node_output_ok("UP" if is_active() else "DOWN") - - - class StatusCmd(Cmd): -@@ -294,7 +221,7 @@ class WebhookAddCmd(Cmd): - def run(self, args): - create_webhooks_file_if_not_exists() - -- with fasteners.InterProcessLock(WEBHOOKS_FILE): -+ with LockedOpen(WEBHOOKS_FILE, 'r+'): - data = json.load(open(WEBHOOKS_FILE)) - if data.get(args.url, None) is not None: - output_error("Webhook already exists") -@@ -316,7 +243,7 @@ class WebhookModCmd(Cmd): - def run(self, args): - create_webhooks_file_if_not_exists() - -- with fasteners.InterProcessLock(WEBHOOKS_FILE): -+ with LockedOpen(WEBHOOKS_FILE, 'r+'): - data = json.load(open(WEBHOOKS_FILE)) - if data.get(args.url, None) is None: - output_error("Webhook does not exists") -@@ -336,7 +263,7 @@ class WebhookDelCmd(Cmd): - def run(self, args): - create_webhooks_file_if_not_exists() - -- with fasteners.InterProcessLock(WEBHOOKS_FILE): -+ with LockedOpen(WEBHOOKS_FILE, 'r+'): - data = json.load(open(WEBHOOKS_FILE)) - if data.get(args.url, None) is None: - output_error("Webhook does not exists") -@@ -445,7 +372,9 @@ class ConfigSetCmd(Cmd): - if args.name not in CONFIG_KEYS: - output_error("Invalid Config item") - -- with fasteners.InterProcessLock(CUSTOM_CONFIG_FILE): -+ create_custom_config_file_if_not_exists() -+ -+ with LockedOpen(CUSTOM_CONFIG_FILE, 'r+'): - data = json.load(open(DEFAULT_CONFIG_FILE)) - if os.path.exists(CUSTOM_CONFIG_FILE): - config_json = read_file_content_json(CUSTOM_CONFIG_FILE) -@@ -456,7 +385,6 @@ class ConfigSetCmd(Cmd): - return - - # TODO: Validate Value -- create_custom_config_file_if_not_exists() - new_data = read_file_content_json(CUSTOM_CONFIG_FILE) - - v = args.value -@@ -474,7 +402,9 @@ class ConfigSetCmd(Cmd): - if args.name in RESTART_CONFIGS: - restart = True - -- sync_to_peers(restart=restart) -+ sync_to_peers() -+ if restart: -+ print ("\nRestart glustereventsd in all nodes") - - - class ConfigResetCmd(Cmd): -@@ -484,7 +414,9 @@ class ConfigResetCmd(Cmd): - parser.add_argument("name", help="Config Name or all") - - def run(self, args): -- with fasteners.InterProcessLock(CUSTOM_CONFIG_FILE): -+ create_custom_config_file_if_not_exists() -+ -+ with LockedOpen(CUSTOM_CONFIG_FILE, 'r+'): - changed_keys = [] - data = {} - if os.path.exists(CUSTOM_CONFIG_FILE): -@@ -511,7 +443,9 @@ class ConfigResetCmd(Cmd): - restart = True - break - -- sync_to_peers(restart=restart) -+ sync_to_peers() -+ if restart: -+ print ("\nRestart glustereventsd in all nodes") - - - class SyncCmd(Cmd): -diff --git a/events/src/utils.py b/events/src/utils.py -index 386e8f2..db8ebfe 100644 ---- a/events/src/utils.py -+++ b/events/src/utils.py -@@ -12,6 +12,8 @@ - import json - import os - import logging -+import fcntl -+from errno import ESRCH, EBADF - - import requests - from eventsapiconf import (LOG_FILE, -@@ -168,3 +170,78 @@ def plugin_webhook(message): - url=url, - event=message_json, - status_code=resp.status_code)) -+ -+ -+class LockedOpen(object): -+ -+ def __init__(self, filename, *args, **kwargs): -+ self.filename = filename -+ self.open_args = args -+ self.open_kwargs = kwargs -+ self.fileobj = None -+ -+ def __enter__(self): -+ """ -+ If two processes compete to update a file, The first process -+ gets the lock and the second process is blocked in the fcntl.flock() -+ call. When first process replaces the file and releases the lock, -+ the already open file descriptor in the second process now points -+ to a "ghost" file(not reachable by any path name) with old contents. -+ To avoid that conflict, check the fd already opened is same or -+ not. Open new one if not same -+ """ -+ f = open(self.filename, *self.open_args, **self.open_kwargs) -+ while True: -+ fcntl.flock(f, fcntl.LOCK_EX) -+ fnew = open(self.filename, *self.open_args, **self.open_kwargs) -+ if os.path.sameopenfile(f.fileno(), fnew.fileno()): -+ fnew.close() -+ break -+ else: -+ f.close() -+ f = fnew -+ self.fileobj = f -+ return f -+ -+ def __exit__(self, _exc_type, _exc_value, _traceback): -+ self.fileobj.close() -+ -+ -+class PidFileLockFailed(Exception): -+ pass -+ -+ -+class PidFile(object): -+ def __init__(self, filename): -+ self.filename = filename -+ self.pid = os.getpid() -+ self.fh = None -+ -+ def cleanup(self, remove_file=True): -+ try: -+ if self.fh is not None: -+ self.fh.close() -+ except IOError as exc: -+ if exc.errno != EBADF: -+ raise -+ finally: -+ if os.path.isfile(self.filename) and remove_file: -+ os.remove(self.filename) -+ -+ def __enter__(self): -+ self.fh = open(self.filename, 'a+') -+ try: -+ fcntl.flock(self.fh.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) -+ except IOError as exc: -+ self.cleanup(remove_file=False) -+ raise PidFileLockFailed(exc) -+ -+ self.fh.seek(0) -+ self.fh.truncate() -+ self.fh.write("%d\n" % self.pid) -+ self.fh.flush() -+ self.fh.seek(0) -+ return self -+ -+ def __exit__(self, _exc_type, _exc_value, _traceback): -+ self.cleanup() -diff --git a/extras/init.d/Makefile.am b/extras/init.d/Makefile.am -index 8c43e51..bd8837b 100644 ---- a/extras/init.d/Makefile.am -+++ b/extras/init.d/Makefile.am -@@ -1,5 +1,7 @@ - --EXTRA_DIST = glusterd-Debian glusterd-FreeBSD glusterd-Redhat glusterd-SuSE glusterd.plist rhel5-load-fuse.modules -+EXTRA_DIST = glusterd-Debian glusterd-FreeBSD glusterd-Redhat glusterd-SuSE \ -+ glusterd.plist rhel5-load-fuse.modules \ -+ glustereventsd-FreeBSD glustereventsd-Redhat - - CLEANFILES = - -@@ -13,6 +15,13 @@ $(GF_DISTRIBUTION): - $(INSTALL_PROGRAM) glusterd-$(GF_DISTRIBUTION) $(DESTDIR)$(INIT_DIR)/glusterd; \ - fi - -+if BUILD_EVENTS -+ @if [ ! -d $(SYSTEMD_DIR) ]; then \ -+ $(mkdir_p) $(DESTDIR)$(INIT_DIR); \ -+ $(INSTALL_PROGRAM) glustereventsd-$(GF_DISTRIBUTION) $(DESTDIR)$(INIT_DIR)/glustereventsd; \ -+ fi -+endif -+ - install-exec-local: $(GF_DISTRIBUTION) - - install-data-local: -diff --git a/extras/init.d/glustereventsd-FreeBSD.in b/extras/init.d/glustereventsd-FreeBSD.in -new file mode 100644 -index 0000000..2e8303e ---- /dev/null -+++ b/extras/init.d/glustereventsd-FreeBSD.in -@@ -0,0 +1,19 @@ -+#!/bin/sh -+# -+# $FreeBSD$ -+# -+ -+# PROVIDE: glustereventsd -+ -+. /etc/rc.subr -+ -+name="glustereventsd" -+rcvar=`set_rcvar` -+command=@prefix@/sbin/${name} -+command_interpreter=/usr/local/bin/python -+pidfile="/var/run/${name}.pid" -+glustereventsd_flags="-p /var/run/${name}.pid" -+start_cmd="/usr/sbin/daemon $command ${glustereventsd_flags}" -+ -+load_rc_config $name -+run_rc_command "$1" -diff --git a/extras/init.d/glustereventsd-Redhat.in b/extras/init.d/glustereventsd-Redhat.in -new file mode 100644 -index 0000000..d23ce4c ---- /dev/null -+++ b/extras/init.d/glustereventsd-Redhat.in -@@ -0,0 +1,129 @@ -+#!/bin/bash -+# -+# glustereventsd Startup script for the glusterfs Events server -+# -+# chkconfig: - 20 80 -+# description: Gluster Events Server -+ -+### BEGIN INIT INFO -+# Provides: glustereventsd -+# Required-Start: $local_fs $network -+# Required-Stop: $local_fs $network -+# Should-Start: -+# Should-Stop: -+# Default-Start: 2 3 4 5 -+# Default-Stop: 0 1 6 -+# Short-Description: glusterfs Events server -+# Description: GlusterFS Events Server -+### END INIT INFO -+# -+ -+# Source function library. -+. /etc/rc.d/init.d/functions -+ -+BASE=glustereventsd -+ -+# Fedora File System Layout dictates /run -+[ -e /run ] && RUNDIR="/run" -+PIDFILE="${RUNDIR:-/var/run}/${BASE}.pid" -+ -+PID=`test -f $PIDFILE && cat $PIDFILE` -+ -+GLUSTEREVENTSD_BIN=@prefix@/sbin/$BASE -+GLUSTEREVENTSD_OPTS="--pid-file=$PIDFILE" -+GLUSTEREVENTSD="$GLUSTEREVENTSD_BIN $GLUSTEREVENTSD_OPTS" -+RETVAL=0 -+ -+LOCKFILE=/var/lock/subsys/${BASE} -+ -+# Start the service $BASE -+start() -+{ -+ if pidofproc -p $PIDFILE $GLUSTEREVENTSD_BIN &> /dev/null; then -+ echo "glustereventsd service is already running with pid $PID" -+ return 0 -+ else -+ echo -n $"Starting $BASE:" -+ daemon $GLUSTEREVENTSD & -+ RETVAL=$? -+ echo -+ [ $RETVAL -eq 0 ] && touch $LOCKFILE -+ return $RETVAL -+ fi -+} -+ -+# Stop the service $BASE -+stop() -+{ -+ echo -n $"Stopping $BASE:" -+ if pidofproc -p $PIDFILE $GLUSTEREVENTSD_BIN &> /dev/null; then -+ killproc -p $PIDFILE $BASE -+ else -+ killproc $BASE -+ fi -+ RETVAL=$? -+ echo -+ [ $RETVAL -eq 0 ] && rm -f $LOCKFILE -+ return $RETVAL -+} -+ -+restart() -+{ -+ stop -+ start -+} -+ -+reload() -+{ -+ restart -+} -+ -+force_reload() -+{ -+ restart -+} -+ -+rh_status() -+{ -+ status $BASE -+} -+ -+rh_status_q() -+{ -+ rh_status &>/dev/null -+} -+ -+ -+### service arguments ### -+case $1 in -+ start) -+ rh_status_q && exit 0 -+ $1 -+ ;; -+ stop) -+ rh_status_q || exit 0 -+ $1 -+ ;; -+ restart) -+ $1 -+ ;; -+ reload) -+ rh_status_q || exit 7 -+ $1 -+ ;; -+ force-reload) -+ force_reload -+ ;; -+ status) -+ rh_status -+ ;; -+ condrestart|try-restart) -+ rh_status_q || exit 0 -+ restart -+ ;; -+ *) -+ echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" -+ exit 1 -+esac -+ -+exit $? -diff --git a/extras/systemd/glustereventsd.service.in b/extras/systemd/glustereventsd.service.in -index 75cca16..4bfcf42 100644 ---- a/extras/systemd/glustereventsd.service.in -+++ b/extras/systemd/glustereventsd.service.in -@@ -5,9 +5,10 @@ After=syslog.target network.target - [Service] - Environment=PYTHONPATH=@BUILD_PYTHON_SITE_PACKAGES_EXPANDED@:$PYTHONPATH - Type=simple --ExecStart=@SBIN_DIR@/glustereventsd -+ExecStart=@SBIN_DIR@/glustereventsd --pid-file @localstatedir@/run/glustereventsd.pid - ExecReload=/bin/kill -SIGUSR2 $MAINPID - KillMode=control-group -+PIDFile=@localstatedir@/run/glustereventsd.pid - - [Install] - WantedBy=multi-user.target -diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index cb90eef..27032f4 100644 ---- a/glusterfs.spec.in -+++ b/glusterfs.spec.in -@@ -617,8 +617,7 @@ This package provides the translators needed on any GlusterFS client. - Summary: GlusterFS Events - Group: Applications/File - Requires: %{name}-server%{?_isa} = %{version}-%{release} --Requires: python python-fasteners python-requests python-flask --Requires: python-prettytable -+Requires: python python-requests python-prettytable - Requires: python-gluster = %{version}-%{release} - %if ( 0%{?rhel} && 0%{?rhel} <= 6 ) - Requires: python-argparse -@@ -942,6 +941,15 @@ fi - %postun api - /sbin/ldconfig - -+%if 0%{?_build_server} -+%postun events -+%if ( 0%{!?_without_events:1} ) -+%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} >= 6 ) -+%_init_restart glustereventsd -+%endif -+%endif -+%endif -+ - %postun libs - /sbin/ldconfig - -@@ -1000,6 +1008,8 @@ exit 0 - %exclude %{_datadir}/glusterfs/scripts/eventsdash.py* - %if ( 0%{?_with_systemd:1} ) - %exclude %{_unitdir}/glustereventsd.service -+%else -+%exclude %{_sysconfdir}/init.d/glustereventsd - %endif - # exclude server files - %exclude %{_sharedstatedir}/glusterd/* -@@ -1400,6 +1410,8 @@ exit 0 - %{_datadir}/glusterfs/scripts/eventsdash.py* - %if ( 0%{?_with_systemd:1} ) - %{_unitdir}/glustereventsd.service -+%else -+%{_sysconfdir}/init.d/glustereventsd - %endif - %endif - %endif -@@ -1994,6 +2006,9 @@ end - %endif - - %changelog -+* Fri Sep 16 2016 Aravinda VK -+- Added init script for glustereventsd (#1365395) -+ - * Thu Sep 15 2016 Aravinda VK - - Added new subpackage events(glusterfs-events) (#1334044) - --- -1.7.1 - diff --git a/SOURCES/0044-glusterd-fix-brick-restart-parallelism.patch b/SOURCES/0044-glusterd-fix-brick-restart-parallelism.patch new file mode 100644 index 0000000..920801f --- /dev/null +++ b/SOURCES/0044-glusterd-fix-brick-restart-parallelism.patch @@ -0,0 +1,283 @@ +From 938ee38c02cce2a743c672f9c03798ebcbb1e348 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Thu, 26 Oct 2017 14:26:30 +0530 +Subject: [PATCH 44/74] glusterd: fix brick restart parallelism + +glusterd's brick restart logic is not always sequential as there is +atleast three different ways how the bricks are restarted. +1. through friend-sm and glusterd_spawn_daemons () +2. through friend-sm and handling volume quorum action +3. through friend handshaking when there is a mimatch on quorum on +friend import. + +In a brick multiplexing setup, glusterd ended up trying to spawn the +same brick process couple of times as almost in fraction of milliseconds +two threads hit glusterd_brick_start () because of which glusterd didn't +have any choice of rejecting any one of them as for both the case brick +start criteria met. + +As a solution, it'd be better to control this madness by two different +flags, one is a boolean called start_triggered which indicates a brick +start has been triggered and it continues to be true till a brick dies +or killed, the second is a mutex lock to ensure for a particular brick +we don't end up getting into glusterd_brick_start () more than once at +same point of time. + +>mainline patch : https://review.gluster.org/#/c/18577 + +Change-Id: I292f1e58d6971e111725e1baea1fe98b890b43e2 +BUG: 1505363 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/123056 +Reviewed-by: Gaurav Yadav +--- + xlators/mgmt/glusterd/src/glusterd-handler.c | 24 ++++++++----- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 31 ++++++++++------- + xlators/mgmt/glusterd/src/glusterd-server-quorum.c | 15 +++++++-- + xlators/mgmt/glusterd/src/glusterd-utils.c | 39 +++++++++++++++++----- + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 8 +++++ + xlators/mgmt/glusterd/src/glusterd.h | 2 ++ + 6 files changed, 87 insertions(+), 32 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c +index 34e751c..c3b9252 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handler.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handler.c +@@ -5946,16 +5946,22 @@ glusterd_mark_bricks_stopped_by_proc (glusterd_brick_proc_t *brick_proc) { + int ret = -1; + + cds_list_for_each_entry (brickinfo, &brick_proc->bricks, brick_list) { +- ret = glusterd_get_volinfo_from_brick (brickinfo->path, &volinfo); ++ ret = glusterd_get_volinfo_from_brick (brickinfo->path, ++ &volinfo); + if (ret) { +- gf_msg (THIS->name, GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL, +- "Failed to get volinfo from brick(%s)", +- brickinfo->path); ++ gf_msg (THIS->name, GF_LOG_ERROR, 0, ++ GD_MSG_VOLINFO_GET_FAIL, "Failed to get volinfo" ++ " from brick(%s)", brickinfo->path); + goto out; + } +- cds_list_for_each_entry (brickinfo_tmp, &volinfo->bricks, brick_list) { +- if (strcmp (brickinfo->path, brickinfo_tmp->path) == 0) +- glusterd_set_brick_status (brickinfo_tmp, GF_BRICK_STOPPED); ++ cds_list_for_each_entry (brickinfo_tmp, &volinfo->bricks, ++ brick_list) { ++ if (strcmp (brickinfo->path, ++ brickinfo_tmp->path) == 0) { ++ glusterd_set_brick_status (brickinfo_tmp, ++ GF_BRICK_STOPPED); ++ brickinfo_tmp->start_triggered = _gf_false; ++ } + } + } + return 0; +@@ -6129,8 +6135,10 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, + if (temp == 1) + break; + } +- } else ++ } else { + glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED); ++ brickinfo->start_triggered = _gf_false; ++ } + break; + + case RPC_CLNT_DESTROY: +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 9641b4f..5b8f833 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -2402,18 +2402,25 @@ glusterd_start_bricks (glusterd_volinfo_t *volinfo) + GF_ASSERT (volinfo); + + cds_list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +- ret = glusterd_brick_start (volinfo, brickinfo, _gf_false); +- if (ret) { +- gf_msg (THIS->name, GF_LOG_ERROR, 0, +- GD_MSG_BRICK_DISCONNECTED, +- "Failed to start %s:%s for %s", +- brickinfo->hostname, brickinfo->path, +- volinfo->volname); +- gf_event (EVENT_BRICK_START_FAILED, +- "peer=%s;volume=%s;brick=%s", +- brickinfo->hostname, volinfo->volname, +- brickinfo->path); +- goto out; ++ if (!brickinfo->start_triggered) { ++ pthread_mutex_lock (&brickinfo->restart_mutex); ++ { ++ ret = glusterd_brick_start (volinfo, brickinfo, ++ _gf_false); ++ } ++ pthread_mutex_unlock (&brickinfo->restart_mutex); ++ if (ret) { ++ gf_msg (THIS->name, GF_LOG_ERROR, 0, ++ GD_MSG_BRICK_DISCONNECTED, ++ "Failed to start %s:%s for %s", ++ brickinfo->hostname, brickinfo->path, ++ volinfo->volname); ++ gf_event (EVENT_BRICK_START_FAILED, ++ "peer=%s;volume=%s;brick=%s", ++ brickinfo->hostname, volinfo->volname, ++ brickinfo->path); ++ goto out; ++ } + } + + } +diff --git a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +index 4706403..995a568 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c ++++ b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +@@ -362,10 +362,19 @@ glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo, + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + if (!glusterd_is_local_brick (this, volinfo, brickinfo)) + continue; +- if (quorum_status == DOESNT_MEET_QUORUM) ++ if (quorum_status == DOESNT_MEET_QUORUM) { + glusterd_brick_stop (volinfo, brickinfo, _gf_false); +- else +- glusterd_brick_start (volinfo, brickinfo, _gf_false); ++ } else { ++ if (!brickinfo->start_triggered) { ++ pthread_mutex_lock (&brickinfo->restart_mutex); ++ { ++ glusterd_brick_start (volinfo, ++ brickinfo, ++ _gf_false); ++ } ++ pthread_mutex_unlock (&brickinfo->restart_mutex); ++ } ++ } + } + volinfo->quorum_status = quorum_status; + if (quorum_status == MEETS_QUORUM) { +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index bb236df..18de517 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -1084,7 +1084,7 @@ glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo) + goto out; + + CDS_INIT_LIST_HEAD (&new_brickinfo->brick_list); +- ++ pthread_mutex_init (&new_brickinfo->restart_mutex, NULL); + *brickinfo = new_brickinfo; + + ret = 0; +@@ -2481,7 +2481,7 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo, + (void) sys_unlink (pidfile); + + brickinfo->status = GF_BRICK_STOPPED; +- ++ brickinfo->start_triggered = _gf_false; + if (del_brick) + glusterd_delete_brick (volinfo, brickinfo); + out: +@@ -5817,13 +5817,14 @@ glusterd_brick_start (glusterd_volinfo_t *volinfo, + * three different triggers for an attempt to start the brick process + * due to the quorum handling code in glusterd_friend_sm. + */ +- if (brickinfo->status == GF_BRICK_STARTING) { ++ if (brickinfo->status == GF_BRICK_STARTING || ++ brickinfo->start_triggered) { + gf_msg_debug (this->name, 0, "brick %s is already in starting " + "phase", brickinfo->path); + ret = 0; + goto out; + } +- ++ brickinfo->start_triggered = _gf_true; + GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, brickinfo, conf); + if (gf_is_service_running (pidfile, &pid)) { + if (brickinfo->status != GF_BRICK_STARTING && +@@ -5936,6 +5937,9 @@ run: + } + + out: ++ if (ret && brickinfo) { ++ brickinfo->start_triggered = _gf_false; ++ } + gf_msg_debug (this->name, 0, "returning %d ", ret); + return ret; + } +@@ -5997,11 +6001,19 @@ glusterd_restart_bricks (glusterd_conf_t *conf) + start_svcs = _gf_true; + glusterd_svcs_manager (NULL); + } +- + cds_list_for_each_entry (brickinfo, &volinfo->bricks, + brick_list) { +- glusterd_brick_start (volinfo, brickinfo, +- _gf_false); ++ if (!brickinfo->start_triggered) { ++ pthread_mutex_lock ++ (&brickinfo->restart_mutex); ++ { ++ glusterd_brick_start ++ (volinfo, brickinfo, ++ _gf_false); ++ } ++ pthread_mutex_unlock ++ (&brickinfo->restart_mutex); ++ } + } + ret = glusterd_store_volinfo + (volinfo, GLUSTERD_VOLINFO_VER_AC_NONE); +@@ -6040,8 +6052,17 @@ glusterd_restart_bricks (glusterd_conf_t *conf) + "volume %s", volinfo->volname); + cds_list_for_each_entry (brickinfo, &volinfo->bricks, + brick_list) { +- glusterd_brick_start (volinfo, brickinfo, +- _gf_false); ++ if (!brickinfo->start_triggered) { ++ pthread_mutex_lock ++ (&brickinfo->restart_mutex); ++ { ++ glusterd_brick_start ++ (volinfo, brickinfo, ++ _gf_false); ++ } ++ pthread_mutex_unlock ++ (&brickinfo->restart_mutex); ++ } + } + ret = glusterd_store_volinfo + (volinfo, GLUSTERD_VOLINFO_VER_AC_NONE); +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +index 834acab..bec5f72 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +@@ -2545,6 +2545,14 @@ glusterd_start_volume (glusterd_volinfo_t *volinfo, int flags, + GF_ASSERT (volinfo); + + cds_list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { ++ /* Mark start_triggered to false so that in case if this brick ++ * was brought down through gf_attach utility, the ++ * brickinfo->start_triggered wouldn't have been updated to ++ * _gf_false ++ */ ++ if (flags & GF_CLI_FLAG_OP_FORCE) { ++ brickinfo->start_triggered = _gf_false; ++ } + ret = glusterd_brick_start (volinfo, brickinfo, wait); + /* If 'force' try to start all bricks regardless of success or + * failure +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index 722d2f8..d4bb236 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -240,6 +240,8 @@ struct glusterd_brickinfo { + uint64_t statfs_fsid; + uint32_t fs_share_count; + gf_boolean_t port_registered; ++ gf_boolean_t start_triggered; ++ pthread_mutex_t restart_mutex; + }; + + typedef struct glusterd_brickinfo glusterd_brickinfo_t; +-- +1.8.3.1 + diff --git a/SOURCES/0045-eventsapi-Add-conditional-import-for-requests-librar.patch b/SOURCES/0045-eventsapi-Add-conditional-import-for-requests-librar.patch deleted file mode 100644 index 14b2fda..0000000 --- a/SOURCES/0045-eventsapi-Add-conditional-import-for-requests-librar.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 1632c1a3abbc35c76bfaf932e40d18d078f6abfb Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Fri, 9 Sep 2016 12:40:38 +0530 -Subject: [PATCH 45/86] eventsapi: Add conditional import for requests library - -requests lib is used only during publishing event. gf_event python -imports utils.py, and indirectly imports requests lib even though -it is not required while sending event to eventsd. - -Moved "import requests" inside the "plugin_webhook" function. - -> Reviewed-on: http://review.gluster.org/15439 -> Reviewed-by: Prashanth Pai -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> Reviewed-by: Kotresh HR -> CentOS-regression: Gluster Build System - -BUG: 1351589 -Change-Id: Ie3c8088b43d4d7952d01352731999bf8519c73c4 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84748 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - events/src/utils.py | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/events/src/utils.py b/events/src/utils.py -index db8ebfe..dadd9ae 100644 ---- a/events/src/utils.py -+++ b/events/src/utils.py -@@ -15,7 +15,6 @@ import logging - import fcntl - from errno import ESRCH, EBADF - --import requests - from eventsapiconf import (LOG_FILE, - WEBHOOKS_FILE, - DEFAULT_CONFIG_FILE, -@@ -145,6 +144,9 @@ def publish(ts, event_key, data): - - - def plugin_webhook(message): -+ # Import requests here since not used in any other place -+ import requests -+ - message_json = json.dumps(message, sort_keys=True) - logger.debug("EVENT: {0}".format(message_json)) - for url, token in _webhooks.items(): --- -1.7.1 - diff --git a/SOURCES/0045-glusterd-introduce-max-port-range.patch b/SOURCES/0045-glusterd-introduce-max-port-range.patch new file mode 100644 index 0000000..b9079d4 --- /dev/null +++ b/SOURCES/0045-glusterd-introduce-max-port-range.patch @@ -0,0 +1,265 @@ +From b027d2fdd184d2ee2b2c4236603200be344156f8 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Thu, 10 Aug 2017 18:31:55 +0530 +Subject: [PATCH 45/74] glusterd: introduce max-port range + +glusterd.vol file always had an option (commented out) to indicate the +base-port to start the portmapper allocation. This patch brings in the +max-port configuration where one can limit the range of ports which +gluster can be allowed to bind. + +>Fixes: #305 +>Change-Id: Id7a864f818227b9530a07e13d605138edacd9aa9 +>Signed-off-by: Atin Mukherjee +>Reviewed-on: https://review.gluster.org/18016 +>Smoke: Gluster Build System +>Reviewed-by: Prashanth Pai +>Reviewed-by: Niels de Vos +>CentOS-regression: Gluster Build System +>Reviewed-by: Gaurav Yadav + +Change-Id: Id7a864f818227b9530a07e13d605138edacd9aa9 +BUG: 1474745 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/123060 +Reviewed-by: Gaurav Yadav +--- + extras/glusterd.vol.in | 1 + + xlators/mgmt/glusterd/src/glusterd-messages.h | 10 +++++++++- + xlators/mgmt/glusterd/src/glusterd-pmap.c | 20 +++++++++++--------- + xlators/mgmt/glusterd/src/glusterd-pmap.h | 3 ++- + xlators/mgmt/glusterd/src/glusterd-snapd-svc.c | 8 ++++++++ + xlators/mgmt/glusterd/src/glusterd-utils.c | 18 +++++++++++++++++- + xlators/mgmt/glusterd/src/glusterd.c | 17 +++++++++++++++-- + xlators/mgmt/glusterd/src/glusterd.h | 1 + + 8 files changed, 64 insertions(+), 14 deletions(-) + +diff --git a/extras/glusterd.vol.in b/extras/glusterd.vol.in +index 957b277..0152996 100644 +--- a/extras/glusterd.vol.in ++++ b/extras/glusterd.vol.in +@@ -9,4 +9,5 @@ volume management + option event-threads 1 + # option transport.address-family inet6 + # option base-port 49152 ++# option max-port 65535 + end-volume +diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h +index 8bb4c43..de9ae92 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-messages.h ++++ b/xlators/mgmt/glusterd/src/glusterd-messages.h +@@ -41,7 +41,7 @@ + + #define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD + +-#define GLFS_NUM_MESSAGES 611 ++#define GLFS_NUM_MESSAGES 612 + + #define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1) + /* Messaged with message IDs */ +@@ -4945,6 +4945,14 @@ + */ + #define GD_MSG_SVC_START_FAIL (GLUSTERD_COMP_BASE + 590) + ++/*! ++ * @messageid ++ * @diagnosis ++ * @recommendedaction ++ * ++ */ ++#define GD_MSG_PORTS_EXHAUSTED (GLUSTERD_COMP_BASE + 612) ++ + /*------------*/ + + #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" +diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c +index 1b547e7..4f045ab 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-pmap.c ++++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c +@@ -61,8 +61,8 @@ pmap_registry_new (xlator_t *this) + + pmap->base_port = pmap->last_alloc = + ((glusterd_conf_t *)(this->private))->base_port; +- +- for (i = pmap->base_port; i <= GF_PORT_MAX; i++) { ++ pmap->max_port = ((glusterd_conf_t *)(this->private))->max_port; ++ for (i = pmap->base_port; i <= pmap->max_port; i++) { + if (pmap_port_isfree (i)) + pmap->ports[i].type = GF_PMAP_PORT_FREE; + else +@@ -184,10 +184,12 @@ pmap_registry_search_by_xprt (xlator_t *this, void *xprt, + static char * + pmap_registry_search_by_port (xlator_t *this, int port) + { +- struct pmap_registry *pmap = NULL; +- char *brickname = NULL; ++ struct pmap_registry *pmap = NULL; ++ char *brickname = NULL; ++ int max_port = 0; + +- if (port > GF_PORT_MAX) ++ max_port = ((glusterd_conf_t *)(this->private))->max_port; ++ if (port > max_port) + goto out; + + pmap = pmap_registry_get (this); +@@ -209,7 +211,7 @@ pmap_registry_alloc (xlator_t *this) + + pmap = pmap_registry_get (this); + +- for (p = pmap->base_port; p <= GF_PORT_MAX; p++) { ++ for (p = pmap->base_port; p <= pmap->max_port; p++) { + /* GF_PMAP_PORT_FOREIGN may be freed up ? */ + if ((pmap->ports[p].type == GF_PMAP_PORT_FREE) || + (pmap->ports[p].type == GF_PMAP_PORT_FOREIGN)) { +@@ -261,7 +263,7 @@ pmap_registry_bind (xlator_t *this, int port, const char *brickname, + + pmap = pmap_registry_get (this); + +- if (port > GF_PORT_MAX) ++ if (port > pmap->max_port) + goto out; + + p = port; +@@ -297,7 +299,7 @@ pmap_registry_extend (xlator_t *this, int port, const char *brickname) + + pmap = pmap_registry_get (this); + +- if (port > GF_PORT_MAX) { ++ if (port > pmap->max_port) { + return -1; + } + +@@ -357,7 +359,7 @@ pmap_registry_remove (xlator_t *this, int port, const char *brickname, + goto out; + + if (port) { +- if (port > GF_PORT_MAX) ++ if (port > pmap->max_port) + goto out; + + p = port; +diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.h b/xlators/mgmt/glusterd/src/glusterd-pmap.h +index 253b4cc..f642d66 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-pmap.h ++++ b/xlators/mgmt/glusterd/src/glusterd-pmap.h +@@ -31,8 +31,9 @@ struct pmap_port_status { + + struct pmap_registry { + int base_port; ++ int max_port; + int last_alloc; +- struct pmap_port_status ports[65536]; ++ struct pmap_port_status ports[GF_PORT_MAX + 1]; + }; + + int pmap_assign_port (xlator_t *this, int port, const char *path); +diff --git a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c +index 59d8fbd..5621852 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c ++++ b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c +@@ -300,6 +300,14 @@ glusterd_snapdsvc_start (glusterd_svc_t *svc, int flags) + "-S", svc->conn.sockpath, NULL); + + snapd_port = pmap_assign_port (THIS, volinfo->snapd.port, snapd_id); ++ if (!snapd_port) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_PORTS_EXHAUSTED, ++ "All the ports in the range are exhausted, can't start " ++ "snapd for volume %s", volinfo->volname); ++ ret = -1; ++ goto out; ++ } ++ + volinfo->snapd.port = snapd_port; + + runner_add_arg (&runner, "--brick-port"); +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index 18de517..55c4fa7 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -2002,7 +2002,14 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo, + } + + port = pmap_assign_port (THIS, brickinfo->port, brickinfo->path); +- ++ if (!port) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_PORTS_EXHAUSTED, ++ "All the ports in the range are exhausted, can't start " ++ "brick %s for volume %s", brickinfo->path, ++ volinfo->volname); ++ ret = -1; ++ goto out; ++ } + /* Build the exp_path, before starting the glusterfsd even in + valgrind mode. Otherwise all the glusterfsd processes start + writing the valgrind log to the same file. +@@ -2076,6 +2083,15 @@ retry: + brickinfo->path); + rdma_port = pmap_assign_port (THIS, brickinfo->rdma_port, + rdma_brick_path); ++ if (!rdma_port) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_PORTS_EXHAUSTED, "All rdma ports in the " ++ "range are exhausted, can't start brick %s for " ++ "volume %s", rdma_brick_path, ++ volinfo->volname); ++ ret = -1; ++ goto out; ++ } + runner_argprintf (&runner, "%d,%d", port, rdma_port); + runner_add_arg (&runner, "--xlator-option"); + runner_argprintf (&runner, "%s-server.transport.rdma.listen-port=%d", +diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c +index 81a3206..68d3e90 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.c ++++ b/xlators/mgmt/glusterd/src/glusterd.c +@@ -1824,12 +1824,20 @@ init (xlator_t *this) + if (ret) + goto out; + +- conf->base_port = GF_IANA_PRIV_PORTS_START; +- if (dict_get_uint32(this->options, "base-port", &conf->base_port) == 0) { ++ conf->base_port = GF_IANA_PRIV_PORTS_START; ++ if (dict_get_uint32 (this->options, "base-port", ++ &conf->base_port) == 0) { + gf_msg (this->name, GF_LOG_INFO, 0, + GD_MSG_DICT_SET_FAILED, + "base-port override: %d", conf->base_port); + } ++ conf->max_port = GF_PORT_MAX; ++ if (dict_get_uint32 (this->options, "max-port", ++ &conf->max_port) == 0) { ++ gf_msg (this->name, GF_LOG_INFO, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "max-port override: %d", conf->max_port); ++ } + + /* Set option to run bricks on valgrind if enabled in glusterd.vol */ + this->ctx->cmd_args.valgrind = valgrind; +@@ -2135,6 +2143,11 @@ struct volume_options options[] = { + .type = GF_OPTION_TYPE_INT, + .description = "Sets the base port for portmap query" + }, ++ { .key = {"max-port"}, ++ .type = GF_OPTION_TYPE_INT, ++ .max = GF_PORT_MAX, ++ .description = "Sets the max port for portmap query" ++ }, + { .key = {"snap-brick-path"}, + .type = GF_OPTION_TYPE_STR, + .description = "directory where the bricks for the snapshots will be created" +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index d4bb236..291f2f7 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -187,6 +187,7 @@ typedef struct { + gf_boolean_t restart_done; + rpcsvc_t *uds_rpc; /* RPCSVC for the unix domain socket */ + uint32_t base_port; ++ uint32_t max_port; + char *snap_bricks_directory; + gf_store_handle_t *missed_snaps_list_shandle; + struct cds_list_head missed_snaps_list; +-- +1.8.3.1 + diff --git a/SOURCES/0046-Revert-build-conditionally-build-legacy-gNFS-server-.patch b/SOURCES/0046-Revert-build-conditionally-build-legacy-gNFS-server-.patch new file mode 100644 index 0000000..eb696b5 --- /dev/null +++ b/SOURCES/0046-Revert-build-conditionally-build-legacy-gNFS-server-.patch @@ -0,0 +1,424 @@ +From 538b92ebe180186d84e3f5288f168c404e8957d4 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Mon, 13 Nov 2017 18:41:58 +0530 +Subject: [PATCH 46/74] Revert "build: conditionally build legacy gNFS server + and associated sub-packaging" + +This reverts commit 83abcba6b42f94eb5a6495a634d4055362a9d79d. + +Conflicts: + glusterfs.spec.in + xlators/Makefile.am + xlators/mgmt/glusterd/src/glusterd-messages.h +--- + configure.ac | 12 ----- + extras/LinuxRPM/Makefile.am | 4 +- + glusterfs.spec.in | 65 +++++++-------------------- + xlators/Makefile.am | 6 +-- + xlators/mgmt/glusterd/src/Makefile.am | 4 +- + xlators/mgmt/glusterd/src/glusterd-nfs-svc.c | 28 ++++++------ + xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h | 1 + + xlators/mgmt/glusterd/src/glusterd-utils.c | 7 ++- + xlators/mgmt/glusterd/src/glusterd.c | 35 ++++++++++++--- + 9 files changed, 68 insertions(+), 94 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 3841959..dfccd40 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1345,17 +1345,6 @@ if test "x$enable_glupy" = "xyes"; then + fi + dnl end glupy section + +-dnl gnfs section +-BUILD_GNFS="no" +-AC_ARG_ENABLE([gnfs], +- AC_HELP_STRING([--enable-gnfs], +- [Enable legacy gnfs server xlator.])) +-if test "x$enable_gnfs" = "xyes"; then +- BUILD_GNFS="yes" +-fi +-AM_CONDITIONAL([BUILD_GNFS], [test x$BUILD_GNFS = xyes]) +-dnl end gnfs section +- + dnl Check for userspace-rcu + PKG_CHECK_MODULES([URCU], [liburcu-bp], [], + [AC_CHECK_HEADERS([urcu-bp.h], +@@ -1590,5 +1579,4 @@ echo "Events : $BUILD_EVENTS" + echo "EC dynamic support : $EC_DYNAMIC_SUPPORT" + echo "Use memory pools : $USE_MEMPOOL" + echo "Nanosecond m/atimes : $BUILD_NANOSECOND_TIMESTAMPS" +-echo "Legacy gNFS server : $BUILD_GNFS" + echo +diff --git a/extras/LinuxRPM/Makefile.am b/extras/LinuxRPM/Makefile.am +index f028537..61fd6da 100644 +--- a/extras/LinuxRPM/Makefile.am ++++ b/extras/LinuxRPM/Makefile.am +@@ -18,7 +18,7 @@ autogen: + cd ../.. && \ + rm -rf autom4te.cache && \ + ./autogen.sh && \ +- ./configure --enable-gnfs --with-previous-options ++ ./configure --with-previous-options + + prep: + $(MAKE) -C ../.. dist; +@@ -36,7 +36,7 @@ srcrpm: + mv rpmbuild/SRPMS/* . + + rpms: +- rpmbuild --define '_topdir $(shell pwd)/rpmbuild' --with gnfs -bb rpmbuild/SPECS/glusterfs.spec ++ rpmbuild --define '_topdir $(shell pwd)/rpmbuild' -bb rpmbuild/SPECS/glusterfs.spec + mv rpmbuild/RPMS/*/* . + + # EPEL-5 does not like new versions of rpmbuild and requires some +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 8c16477..10339fe 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -47,10 +47,6 @@ + %global _without_georeplication --disable-georeplication + %endif + +-# if you wish to compile an rpm with the legacy gNFS server xlator +-# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with gnfs +-%{?_with_gnfs:%global _with_gnfs --enable-gnfs} +- + # if you wish to compile an rpm without the OCF resource agents... + # rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without ocf + %{?_without_ocf:%global _without_ocf --without-ocf} +@@ -122,7 +118,7 @@ + %endif + + # From https://fedoraproject.org/wiki/Packaging:Python#Macros +-%if ( 0%{?rhel} && 0%{?rhel} <= 6 ) ++%if ( 0%{?rhel} && 0%{?rhel} <= 5 ) + %{!?python2_sitelib: %global python2_sitelib %(python2 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} + %{!?python2_sitearch: %global python2_sitearch %(python2 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} + %global _rundir %{_localstatedir}/run +@@ -461,26 +457,6 @@ This package provides support to geo-replication. + %endif + %endif + +-%if ( 0%{?_with_gnfs:1} ) +-%package gnfs +-Summary: GlusterFS gNFS server +-Group: System Environment/Daemons +-Requires: %{name}%{?_isa} = %{version}-%{release} +-Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} +-Requires: nfs-utils +- +-%description gnfs +-GlusterFS is a distributed file-system capable of scaling to several +-petabytes. It aggregates various storage bricks over Infiniband RDMA +-or TCP/IP interconnect into one large parallel network file +-system. GlusterFS is one of the most sophisticated file systems in +-terms of features and extensibility. It borrows a powerful concept +-called Translators from GNU Hurd kernel. Much of the code in GlusterFS +-is in user space and easily manageable. +- +-This package provides the glusterfs legacy gNFS server xlator +-%endif +- + %package libs + Summary: GlusterFS common libraries + Group: Applications/File +@@ -621,6 +597,7 @@ Requires: %{name}-api%{?_isa} = %{version}-%{release} + Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} + # lvm2 for snapshot, and nfs-utils and rpcbind/portmap for gnfs server + Requires: lvm2 ++Requires: nfs-utils + %if ( 0%{?_with_systemd:1} ) + %{?systemd_requires} + %else +@@ -736,19 +713,18 @@ export LDFLAGS + ./autogen.sh && %configure \ + %{?_with_cmocka} \ + %{?_with_debug} \ +- %{?_with_firewalld} \ +- %{?_with_gnfs} \ +- %{?_with_tmpfilesdir} \ + %{?_with_valgrind} \ ++ %{?_with_tmpfilesdir} \ + %{?_without_bd} \ + %{?_without_epoll} \ +- %{?_without_events} \ + %{?_without_fusermount} \ + %{?_without_georeplication} \ ++ %{?_with_firewalld} \ + %{?_without_ocf} \ + %{?_without_rdma} \ + %{?_without_syslog} \ +- %{?_without_tiering} ++ %{?_without_tiering} \ ++ %{?_without_events} + + # fix hardening and remove rpath in shlibs + %if ( 0%{?fedora} && 0%{?fedora} > 17 ) || ( 0%{?rhel} && 0%{?rhel} > 6 ) +@@ -1105,6 +1081,7 @@ exit 0 + %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/trash.so + %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/upcall.so + %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mgmt* ++%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs* + %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/decompounder.so + %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/server* + %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/storage* +@@ -1297,19 +1274,6 @@ exit 0 + %endif + + %if ( 0%{?_build_server} ) +-%if ( 0%{?_with_gnfs:1} ) +-%files gnfs +-%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator +-%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs +- %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs/server.so +-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs +-%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/nfs-server.vol +-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs/run +-%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/run/nfs.pid +-%endif +-%endif +- +-%if ( 0%{?_build_server} ) + %files ganesha + %endif + +@@ -1399,11 +1363,6 @@ exit 0 + # sysconf + %config(noreplace) %{_sysconfdir}/glusterfs + %exclude %{_sysconfdir}/glusterfs/eventsconfig.json +-%exclude %{_sharedstatedir}/glusterd/nfs/nfs-server.vol +-%exclude %{_sharedstatedir}/glusterd/nfs/run/nfs.pid +-%if ( 0%{?_with_gnfs:1} ) +-%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs/* +-%endif + %config(noreplace) %{_sysconfdir}/sysconfig/glusterd + %if ( 0%{_for_fedora_koji_builds} ) + %config(noreplace) %{_sysconfdir}/sysconfig/glusterfsd +@@ -1450,6 +1409,7 @@ exit 0 + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/trash.so + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/upcall.so + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/leases.so ++ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs* + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mgmt + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mgmt/glusterd.so + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol +@@ -1517,7 +1477,11 @@ exit 0 + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre + %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre/S30samba-stop.sh + %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre/S29CTDB-teardown.sh +-%config(noreplace) %ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/options ++%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs ++%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/nfs-server.vol ++%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs/run ++%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/run/nfs.pid ++%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/options + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/peers + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/quotad + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/scrub +@@ -2156,6 +2120,9 @@ fi + %endif + + %changelog ++* Mon Nov 13 2017 Jiffin Tony Thottan ++- DOWNSTREAM ONLY - revert of 83abcb(gnfs in an optional subpackage) ++ + * Tue Oct 10 2017 Milind Changire + - DOWNSTREAM ONLY patch - launch glusterd in upgrade mode after all new bits have been installed + +diff --git a/xlators/Makefile.am b/xlators/Makefile.am +index 29549db..c3c9cf2 100644 +--- a/xlators/Makefile.am ++++ b/xlators/Makefile.am +@@ -1,12 +1,8 @@ +-if BUILD_GNFS +- GNFS_DIR = nfs +-endif +- + DIST_SUBDIRS = cluster storage protocol performance debug features encryption \ + mount nfs mgmt system playground meta + + SUBDIRS = cluster storage protocol performance debug features encryption \ +- mount ${GNFS_DIR} mgmt system playground meta ++ mount nfs mgmt system playground meta + + EXTRA_DIST = xlator.sym + +diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am +index b0f5a9b..4858dee 100644 +--- a/xlators/mgmt/glusterd/src/Makefile.am ++++ b/xlators/mgmt/glusterd/src/Makefile.am +@@ -1,8 +1,6 @@ + xlator_LTLIBRARIES = glusterd.la + xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mgmt +-glusterd_la_CPPFLAGS = $(AM_CPPFLAGS) \ +- -DFILTERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/filter\" \ +- -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" ++glusterd_la_CPPFLAGS = $(AM_CPPFLAGS) "-DFILTERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/filter\"" + glusterd_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) + glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \ + glusterd-op-sm.c glusterd-utils.c glusterd-rpc-ops.c \ +diff --git a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c +index 32b1064..eab9746 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c ++++ b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c +@@ -10,7 +10,6 @@ + + #include "globals.h" + #include "run.h" +-#include "syscall.h" + #include "glusterd.h" + #include "glusterd-utils.h" + #include "glusterd-volgen.h" +@@ -18,6 +17,8 @@ + #include "glusterd-messages.h" + #include "glusterd-svc-helper.h" + ++static char *nfs_svc_name = "nfs"; ++ + static gf_boolean_t + glusterd_nfssvc_need_start () + { +@@ -40,13 +41,19 @@ glusterd_nfssvc_need_start () + return start; + } + ++int ++glusterd_nfssvc_init (glusterd_svc_t *svc) ++{ ++ return glusterd_svc_init (svc, nfs_svc_name); ++} ++ + static int + glusterd_nfssvc_create_volfile () + { + char filepath[PATH_MAX] = {0,}; + glusterd_conf_t *conf = THIS->private; + +- glusterd_svc_build_volfile_path (conf->nfs_svc.name, conf->workdir, ++ glusterd_svc_build_volfile_path (nfs_svc_name, conf->workdir, + filepath, sizeof (filepath)); + return glusterd_create_global_volfile (build_nfs_graph, + filepath, NULL); +@@ -58,16 +65,15 @@ glusterd_nfssvc_manager (glusterd_svc_t *svc, void *data, int flags) + int ret = -1; + + if (!svc->inited) { +- ret = glusterd_svc_init (svc, "nfs"); ++ ret = glusterd_nfssvc_init (svc); + if (ret) { + gf_msg (THIS->name, GF_LOG_ERROR, 0, +- GD_MSG_FAILED_INIT_NFSSVC, +- "Failed to init nfs service"); ++ GD_MSG_FAILED_INIT_NFSSVC, "Failed to init nfs " ++ "service"); + goto out; + } else { + svc->inited = _gf_true; +- gf_msg_debug (THIS->name, 0, +- "nfs service initialized"); ++ gf_msg_debug (THIS->name, 0, "nfs service initialized"); + } + } + +@@ -75,14 +81,6 @@ glusterd_nfssvc_manager (glusterd_svc_t *svc, void *data, int flags) + if (ret) + goto out; + +- /* not an error, or a (very) soft error at best */ +- if (sys_access (XLATORDIR "/nfs/server.so", R_OK) != 0) { +- gf_msg (THIS->name, GF_LOG_INFO, 0, +- GD_MSG_GNFS_XLATOR_NOT_INSTALLED, +- "nfs/server.so xlator is not installed"); +- goto out; +- } +- + ret = glusterd_nfssvc_create_volfile (); + if (ret) + goto out; +diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h +index 8b70a62..c505d1e 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h ++++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h +@@ -29,6 +29,7 @@ struct glusterd_svc_ { + char name[PATH_MAX]; + glusterd_conn_t conn; + glusterd_proc_t proc; ++ glusterd_svc_build_t build; + glusterd_svc_manager_t manager; + glusterd_svc_start_t start; + glusterd_svc_stop_t stop; +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index 55c4fa7..f611fbb 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -668,8 +668,11 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo) + + new_volinfo->xl = THIS; + +- glusterd_snapdsvc_build (&new_volinfo->snapd.svc); +- glusterd_tierdsvc_build (&new_volinfo->tierd.svc); ++ new_volinfo->snapd.svc.build = glusterd_snapdsvc_build; ++ new_volinfo->snapd.svc.build (&(new_volinfo->snapd.svc)); ++ ++ new_volinfo->tierd.svc.build = glusterd_tierdsvc_build; ++ new_volinfo->tierd.svc.build (&(new_volinfo->tierd.svc)); + + pthread_mutex_init (&new_volinfo->reflock, NULL); + *volinfo = glusterd_volinfo_ref (new_volinfo); +diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c +index 68d3e90..6ce4156 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.c ++++ b/xlators/mgmt/glusterd/src/glusterd.c +@@ -1330,6 +1330,34 @@ out: + return ret; + } + ++static void ++glusterd_svcs_build () ++{ ++ xlator_t *this = NULL; ++ glusterd_conf_t *priv = NULL; ++ ++ this = THIS; ++ GF_ASSERT (this); ++ ++ priv = this->private; ++ GF_ASSERT (priv); ++ ++ priv->shd_svc.build = glusterd_shdsvc_build; ++ priv->shd_svc.build (&(priv->shd_svc)); ++ ++ priv->nfs_svc.build = glusterd_nfssvc_build; ++ priv->nfs_svc.build (&(priv->nfs_svc)); ++ ++ priv->quotad_svc.build = glusterd_quotadsvc_build; ++ priv->quotad_svc.build (&(priv->quotad_svc)); ++ ++ priv->bitd_svc.build = glusterd_bitdsvc_build; ++ priv->bitd_svc.build (&(priv->bitd_svc)); ++ ++ priv->scrub_svc.build = glusterd_scrubsvc_build; ++ priv->scrub_svc.build (&(priv->scrub_svc)); ++} ++ + static int + is_upgrade (dict_t *options, gf_boolean_t *upgrade) + { +@@ -1864,12 +1892,7 @@ init (xlator_t *this) + this->private = conf; + glusterd_mgmt_v3_lock_init (); + glusterd_txn_opinfo_dict_init (); +- +- glusterd_shdsvc_build (&conf->shd_svc); +- glusterd_nfssvc_build (&conf->nfs_svc); +- glusterd_quotadsvc_build (&conf->quotad_svc); +- glusterd_bitdsvc_build (&conf->bitd_svc); +- glusterd_scrubsvc_build (&conf->scrub_svc); ++ glusterd_svcs_build (); + + /* Make install copies few of the hook-scripts by creating hooks + * directory. Hence purposefully not doing the check for the presence of +-- +1.8.3.1 + diff --git a/SOURCES/0046-eventsapi-packaging-Fix-conflict-during-rpm-install.patch b/SOURCES/0046-eventsapi-packaging-Fix-conflict-during-rpm-install.patch deleted file mode 100644 index 2e450af..0000000 --- a/SOURCES/0046-eventsapi-packaging-Fix-conflict-during-rpm-install.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 796910b3d7f2a6455f57ed04e4d34142dba82808 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Tue, 13 Sep 2016 15:38:24 +0530 -Subject: [PATCH 46/86] eventsapi/packaging: Fix conflict during rpm install - -RPM installation fails with following error - - Error: Transaction check error: - file /etc/glusterfs/eventsconfig.json conflicts between attempted - installs of glusterfs-events-3.10dev-0.51.gitc9271ff.fc24.x86_64 - and glusterfs-server-3.10dev-0.51.gitc9271ff.fc24.x86_64 - -Changed attributes of eventsconfig.json file as same as other -config files and excluded this file in server rpm. - -> Reviewed-on: http://review.gluster.org/15486 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Niels de Vos -> NetBSD-regression: NetBSD Build System - -BUG: 1351589 -Change-Id: I3708c8fc58448cd5a6ebe611250f10e0658bdd58 -Signed-off-by: Aravinda VK - -Reviewed-on: https://code.engineering.redhat.com/gerrit/84749 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - glusterfs.spec.in | 6 +++++- - 1 files changed, 5 insertions(+), 1 deletions(-) - -diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 27032f4..06f1de1 100644 ---- a/glusterfs.spec.in -+++ b/glusterfs.spec.in -@@ -1279,6 +1279,7 @@ exit 0 - %doc extras/clear_xattrs.sh - # sysconf - %config(noreplace) %{_sysconfdir}/glusterfs -+%exclude %{_sysconfdir}/glusterfs/eventsconfig.json - %config(noreplace) %{_sysconfdir}/sysconfig/glusterd - %if ( 0%{_for_fedora_koji_builds} ) - %config(noreplace) %{_sysconfdir}/sysconfig/glusterfsd -@@ -1401,7 +1402,7 @@ exit 0 - %if 0%{?_build_server} - %if ( 0%{!?_without_events:1} ) - %files events --%config %attr(0600, root, root) %{_sysconfdir}/glusterfs/eventsconfig.json -+%config(noreplace) %{_sysconfdir}/glusterfs/eventsconfig.json - %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/events - %{_libexecdir}/glusterfs/events - %{_libexecdir}/glusterfs/peer_eventsapi.py* -@@ -2007,6 +2008,9 @@ end - - %changelog - * Fri Sep 16 2016 Aravinda VK -+- Changed attribute of eventsconfig.json file as same as other configs (#1375532) -+ -+* Fri Sep 16 2016 Aravinda VK - - Added init script for glustereventsd (#1365395) - - * Thu Sep 15 2016 Aravinda VK --- -1.7.1 - diff --git a/SOURCES/0047-Revert-glusterd-skip-nfs-svc-reconfigure-if-nfs-xlat.patch b/SOURCES/0047-Revert-glusterd-skip-nfs-svc-reconfigure-if-nfs-xlat.patch new file mode 100644 index 0000000..bd323a5 --- /dev/null +++ b/SOURCES/0047-Revert-glusterd-skip-nfs-svc-reconfigure-if-nfs-xlat.patch @@ -0,0 +1,34 @@ +From 7dd54e4e500a41105f375b2aa3620fcd619d5148 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Mon, 13 Nov 2017 18:43:00 +0530 +Subject: [PATCH 47/74] Revert "glusterd: skip nfs svc reconfigure if nfs + xlator is not installed" + +This reverts commit 316e3300cfaa646b7fa45fcc7f57b81c7bb15a0e. +--- + xlators/mgmt/glusterd/src/glusterd-nfs-svc.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c +index eab9746..da34342 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c ++++ b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c +@@ -154,15 +154,6 @@ glusterd_nfssvc_reconfigure () + priv = this->private; + GF_VALIDATE_OR_GOTO (this->name, priv, out); + +- /* not an error, or a (very) soft error at best */ +- if (sys_access (XLATORDIR "/nfs/server.so", R_OK) != 0) { +- gf_msg (THIS->name, GF_LOG_INFO, 0, +- GD_MSG_GNFS_XLATOR_NOT_INSTALLED, +- "nfs/server.so xlator is not installed"); +- ret = 0; +- goto out; +- } +- + cds_list_for_each_entry (volinfo, &priv->volumes, vol_list) { + if (GLUSTERD_STATUS_STARTED == volinfo->status) { + vol_started = _gf_true; +-- +1.8.3.1 + diff --git a/SOURCES/0047-eventsapi-Bitrot-events.patch b/SOURCES/0047-eventsapi-Bitrot-events.patch deleted file mode 100644 index bbf0313..0000000 --- a/SOURCES/0047-eventsapi-Bitrot-events.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 3a683040b602e9c981e9fb2beb28dc20d802ef10 Mon Sep 17 00:00:00 2001 -From: Kotresh HR -Date: Wed, 17 Aug 2016 19:52:29 +0530 -Subject: [PATCH 47/86] eventsapi: Bitrot events - -Following Bitrot Events are added - -BITROT_ENABLE/BITROT_DISABLE -{ - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": EVENT_TYPE, - "message": { - "name": VOLUME_NAME, - } -} - -BITROT_SCRUB_THROTTLE/BITROT_SCRUB_FREQ/BITROT_SCRUB -{ - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": EVENT_TYPE, - "message": { - "name": VOLUME_NAME, - "value": OPTION_VALUE - } -} - -EVENT_BITROT_BAD_FILE -{ - "nodeid": NODEID, - "ts": TIMESTAMP, - "event": EVENT_TYPE, - "message": { - "gfid": GFID_OF_FILE, - "brick": BRICK_ROOT, - "path": FILE_PATH_FROM_BRICK_ROOT (if available) - } -} - ->Reviewed-on: http://review.gluster.org/15190 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->Reviewed-by: Atin Mukherjee ->CentOS-regression: Gluster Build System ->Reviewed-by: Aravinda VK - -Change-Id: I8c37b0e9db9f4f0f3d05d8f78b5521c7db0e2237 -BUG: 1361170 -Signed-off-by: Kotresh HR -Reviewed-on: https://code.engineering.redhat.com/gerrit/84792 -Reviewed-by: Milind Changire -Reviewed-by: Aravinda Vishwanathapura Krishna Murthy -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 64 +++++++++++++++++++++ - events/eventskeygen.py | 7 ++ - xlators/features/bit-rot/src/bitd/bit-rot-scrub.c | 2 + - 3 files changed, 73 insertions(+), 0 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 3a7c9ed..0ea461e 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -1519,6 +1519,13 @@ cli_cmd_bitrot_cbk (struct cli_state *state, struct cli_cmd_word *word, - cli_local_t *local = NULL; - rpc_clnt_procedure_t *proc = NULL; - int sent = 0; -+#if (USE_EVENTS) -+ int cmd_type = -1; -+ int ret1 = -1; -+ int event_type = -1; -+ char *tmp = NULL; -+ char *events_str = NULL; -+#endif - - ret = cli_cmd_bitrot_parse (words, wordcount, &options); - if (ret < 0) { -@@ -1554,6 +1561,63 @@ out: - - } - -+#if (USE_EVENTS) -+ if (ret == 0) { -+ ret1 = dict_get_int32 (options, "type", &cmd_type); -+ if (ret1) -+ cmd_type = -1; -+ else { -+ ret1 = dict_get_str (options, "volname", &tmp); -+ if (ret1) -+ tmp = ""; -+ gf_asprintf (&events_str, "name=%s", tmp); -+ } -+ -+ switch (cmd_type) { -+ case GF_BITROT_OPTION_TYPE_ENABLE: -+ event_type = EVENT_BITROT_ENABLE; -+ break; -+ case GF_BITROT_OPTION_TYPE_DISABLE: -+ event_type = EVENT_BITROT_DISABLE; -+ break; -+ case GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE: -+ event_type = EVENT_BITROT_SCRUB_THROTTLE; -+ ret1 = dict_get_str (options, "scrub-throttle-value", -+ &tmp); -+ if (ret1) -+ tmp = ""; -+ gf_asprintf (&events_str, "%s;value=%s", events_str, -+ tmp); -+ break; -+ case GF_BITROT_OPTION_TYPE_SCRUB_FREQ: -+ event_type = EVENT_BITROT_SCRUB_FREQ; -+ ret1 = dict_get_str (options, "scrub-frequency-value", -+ &tmp); -+ if (ret1) -+ tmp = ""; -+ gf_asprintf (&events_str, "%s;value=%s", events_str, -+ tmp); -+ break; -+ case GF_BITROT_OPTION_TYPE_SCRUB: -+ event_type = EVENT_BITROT_SCRUB_OPTION; -+ ret1 = dict_get_str (options, "scrub-value", &tmp); -+ if (ret1) -+ tmp = ""; -+ gf_asprintf (&events_str, "%s;value=%s", events_str, -+ tmp); -+ break; -+ default: -+ break; -+ } -+ -+ if (event_type > -1) -+ gf_event (event_type, "%s", events_str); -+ -+ if (events_str) -+ GF_FREE (events_str); -+ } -+#endif -+ - CLI_STACK_DESTROY (frame); - - return ret; -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 468c795..cac8b7e 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -39,6 +39,13 @@ keys = ( - "EVENT_GEOREP_DELETE", - "EVENT_GEOREP_CONFIG_SET", - "EVENT_GEOREP_CONFIG_RESET", -+ -+ "EVENT_BITROT_ENABLE", -+ "EVENT_BITROT_DISABLE", -+ "EVENT_BITROT_SCRUB_THROTTLE", -+ "EVENT_BITROT_SCRUB_FREQ", -+ "EVENT_BITROT_SCRUB_OPTION", -+ "EVENT_BITROT_BAD_FILE", - ) - - LAST_EVENT = "EVENT_LAST" -diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -index abf8dcf..265fe60 100644 ---- a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -+++ b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c -@@ -262,6 +262,8 @@ bitd_compare_ckum (xlator_t *this, - gf_msg (this->name, GF_LOG_ALERT, 0, BRB_MSG_MARK_CORRUPTED, "Marking" - " %s [GFID: %s | Brick: %s] as corrupted..", loc->path, - uuid_utoa (linked_inode->gfid), child->brick_path); -+ gf_event (EVENT_BITROT_BAD_FILE, "gfid=%s;path=%s;brick=%s", -+ uuid_utoa (linked_inode->gfid), loc->path, child->brick_path); - ret = syncop_fsetxattr (child->xl, fd, xattr, 0, NULL, NULL); - if (ret) - gf_msg (this->name, GF_LOG_ERROR, 0, BRB_MSG_MARK_BAD_FILE, --- -1.7.1 - diff --git a/SOURCES/0048-glusterd-Add-async-events.patch b/SOURCES/0048-glusterd-Add-async-events.patch deleted file mode 100644 index e2a7600..0000000 --- a/SOURCES/0048-glusterd-Add-async-events.patch +++ /dev/null @@ -1,367 +0,0 @@ -From 0d3829f2b5cea0cfce4cbd784c66c0d32997b144 Mon Sep 17 00:00:00 2001 -From: Atin Mukherjee -Date: Tue, 26 Jul 2016 16:01:56 +0530 -Subject: [PATCH 48/86] glusterd: Add async events - -As the eventing framework is already in the code, this patch targets to capture -all the async glusterd events which are important to be notified to the higher -layers which consume the eventing framework. - -I plan to break this work into two different patches where this patch set covers -the first set of events. - ->Reviewed-on: http://review.gluster.org/15015 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Rohan Kanade ->Reviewed-by: Samikshan Bairagya - -Change-Id: Ie1bd4f6fa84117b26ccb4c75bc4dc68e6ef19134 -BUG: 1360807 -Signed-off-by: Atin Mukherjee -Reviewed-on: https://code.engineering.redhat.com/gerrit/84793 ---- - events/eventskeygen.py | 20 ++++++++ - xlators/mgmt/glusterd/src/glusterd-bitd-svc.c | 3 + - xlators/mgmt/glusterd/src/glusterd-handler.c | 59 ++++++++++++++++++---- - xlators/mgmt/glusterd/src/glusterd-handshake.c | 3 + - xlators/mgmt/glusterd/src/glusterd-nfs-svc.c | 3 + - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 11 ++++- - xlators/mgmt/glusterd/src/glusterd-pmap.c | 2 +- - xlators/mgmt/glusterd/src/glusterd-quotad-svc.c | 3 + - xlators/mgmt/glusterd/src/glusterd-rebalance.c | 5 ++- - xlators/mgmt/glusterd/src/glusterd-svc-helper.c | 4 +- - 10 files changed, 98 insertions(+), 15 deletions(-) - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index cac8b7e..570c905 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -46,6 +46,26 @@ keys = ( - "EVENT_BITROT_SCRUB_FREQ", - "EVENT_BITROT_SCRUB_OPTION", - "EVENT_BITROT_BAD_FILE", -+ -+ "EVENT_SVC_MANAGER_FAILED", -+ "EVENT_SVC_RECONFIGURE_FAILED", -+ -+ "EVENT_DEFRAG_STATUS_UPDATE_FAILED", -+ -+ "EVENT_PEER_STORE_FAILURE", -+ "EVENT_PEER_RPC_CREATE_FAILED", -+ "EVENT_PEER_REJECT", -+ "EVENT_PEER_CONNECT", -+ "EVENT_PEER_DISCONNECT", -+ "EVENT_PEER_NOT_FOUND", -+ "EVENT_UNKNOWN_PEER", -+ -+ "EVENT_BRICK_START_FAILED", -+ "EVENT_BRICK_STOP_FAILED", -+ "EVENT_BRICK_DISCONNECTED", -+ "EVENT_BRICK_CONNECTED", -+ -+ "EVENT_NOTIFY_UNKNOWN_OP", - ) - - LAST_EVENT = "EVENT_LAST" -diff --git a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c -index ee96ccb..f929401 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c -+++ b/xlators/mgmt/glusterd/src/glusterd-bitd-svc.c -@@ -106,6 +106,9 @@ glusterd_bitdsvc_manager (glusterd_svc_t *svc, void *data, int flags) - } - - out: -+ if (ret) -+ gf_event (EVENT_SVC_MANAGER_FAILED, "svc_name=%s", svc->name); -+ - gf_msg_debug (THIS->name, 0, "Returning %d", ret); - - return ret; -diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c -index 7009231..b024fdb 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-handler.c -+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c -@@ -2776,6 +2776,8 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) - GD_MSG_REQ_FROM_UNKNOWN_PEER, - "Received friend update request " - "from unknown peer %s", uuid_utoa (friend_req.uuid)); -+ gf_event (EVENT_UNKNOWN_PEER, "peer=%s", -+ uuid_utoa (friend_req.uuid)); - goto out; - } - -@@ -2872,10 +2874,13 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) - goto unlock; - } - ret = glusterd_store_peerinfo (peerinfo); -- if (ret) -+ if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_PEERINFO_CREATE_FAIL, - "Failed to store peerinfo"); -+ gf_event (EVENT_PEER_STORE_FAILURE, "peer=%s", -+ peerinfo->hostname); -+ } - } - unlock: - rcu_read_unlock (); -@@ -3530,6 +3535,8 @@ glusterd_friend_rpc_create (xlator_t *this, glusterd_peerinfo_t *peerinfo, - GD_MSG_RPC_CREATE_FAIL, - "failed to create rpc for" - " peer %s", peerinfo->hostname); -+ gf_event (EVENT_PEER_RPC_CREATE_FAILED, "peer=%s", -+ peerinfo->hostname); - goto out; - } - peerctx = NULL; -@@ -3585,6 +3592,8 @@ glusterd_friend_add (const char *hoststr, int port, - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_PEERINFO_CREATE_FAIL, - "Failed to store peerinfo"); -+ gf_event (EVENT_PEER_STORE_FAILURE, "peer=%s", -+ (*friend)->hostname); - } - } - -@@ -3640,6 +3649,8 @@ glusterd_friend_add_from_peerinfo (glusterd_peerinfo_t *friend, - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_PEERINFO_CREATE_FAIL, - "Failed to store peerinfo"); -+ gf_event (EVENT_PEER_STORE_FAILURE, "peer=%s", -+ friend->hostname); - } - } - -@@ -5519,6 +5530,14 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, - - switch (event) { - case RPC_CLNT_CONNECT: -+ ret = get_volinfo_from_brickid (brickid, &volinfo); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_VOLINFO_GET_FAIL, -+ "Failed to get volinfo from " -+ "brickid(%s)", brickid); -+ goto out; -+ } - /* If a node on coming back up, already starts a brick - * before the handshake, and the notification comes after - * the handshake is done, then we need to check if this -@@ -5532,15 +5551,6 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, - "Hence not starting the brick", - brickinfo->hostname, - brickinfo->path); -- ret = get_volinfo_from_brickid (brickid, &volinfo); -- if (ret) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_VOLINFO_GET_FAIL, -- "Failed to get volinfo from " -- "brickid(%s)", brickid); -- goto out; -- } -- - ret = glusterd_brick_stop (volinfo, brickinfo, - _gf_false); - if (ret) { -@@ -5557,17 +5567,34 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, - gf_msg_debug (this->name, 0, "Connected to %s:%s", - brickinfo->hostname, brickinfo->path); - glusterd_set_brick_status (brickinfo, GF_BRICK_STARTED); -+ gf_event (EVENT_BRICK_CONNECTED, "peer=%s;volume=%s;brick=%s", -+ brickinfo->hostname, volinfo->volname, -+ brickinfo->path); -+ - ret = default_notify (this, GF_EVENT_CHILD_UP, NULL); - - break; - - case RPC_CLNT_DISCONNECT: - rpc_clnt_unset_connected (&rpc->conn); -- if (glusterd_is_brick_started (brickinfo)) -+ if (glusterd_is_brick_started (brickinfo)) { - gf_msg (this->name, GF_LOG_INFO, 0, - GD_MSG_BRICK_DISCONNECTED, - "Brick %s:%s has disconnected from glusterd.", - brickinfo->hostname, brickinfo->path); -+ ret = get_volinfo_from_brickid (brickid, &volinfo); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_VOLINFO_GET_FAIL, -+ "Failed to get volinfo from " -+ "brickid(%s)", brickid); -+ goto out; -+ } -+ gf_event (EVENT_BRICK_DISCONNECTED, -+ "peer=%s;volume=%s;brick=%s", -+ brickinfo->hostname, volinfo->volname, -+ brickinfo->path); -+ } - - glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED); - break; -@@ -5694,6 +5721,11 @@ __glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, - "%s(%s)", peerctx->peername, - uuid_utoa (peerctx->peerid)); - -+ if (RPC_CLNT_CONNECT == event) { -+ gf_event (EVENT_PEER_NOT_FOUND, "peer=%s;uuid=%s", -+ peerctx->peername, -+ uuid_utoa (peerctx->peerid)); -+ } - ret = -1; - goto out; - } -@@ -5708,6 +5740,8 @@ __glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, - peerinfo->generation = uatomic_add_return - (&conf->generation, 1); - peerctx->peerinfo_gen = peerinfo->generation; -+ gf_event (EVENT_PEER_CONNECT, "host=%s;uuid=%s", -+ peerinfo->hostname, uuid_utoa (peerinfo->uuid)); - - ret = glusterd_peer_dump_version (this, rpc, peerctx); - if (ret) -@@ -5732,6 +5766,9 @@ __glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, - "from glusterd.", - peerinfo->hostname, uuid_utoa (peerinfo->uuid), - glusterd_friend_sm_state_name_get (peerinfo->state.state)); -+ gf_event (EVENT_PEER_DISCONNECT, "peer=%s;uuid=%s;state=%s", -+ peerinfo->hostname, uuid_utoa (peerinfo->uuid), -+ glusterd_friend_sm_state_name_get (peerinfo->state.state)); - - if (peerinfo->connected) { - if (conf->op_version < GD_OP_VERSION_RHS_3_0) { -diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c -index 0ea66a0..9f162d8 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-handshake.c -+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c -@@ -984,6 +984,7 @@ __server_event_notify (rpcsvc_request_t *req) - gf_msg ("glusterd", GF_LOG_ERROR, EINVAL, - GD_MSG_OP_UNSUPPORTED, "Unknown op received in event " - "notify"); -+ gf_event (EVENT_NOTIFY_UNKNOWN_OP, "op=%d", args.op); - ret = -1; - break; - } -@@ -1118,6 +1119,8 @@ gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req, dict_t *dict) - GD_MSG_HANDSHAKE_REQ_REJECTED, "Rejecting management " - "handshake request from unknown peer %s", - req->trans->peerinfo.identifier); -+ gf_event (EVENT_PEER_REJECT, "peer=%s", -+ req->trans->peerinfo.identifier); - return _gf_false; - } - -diff --git a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c -index 60b792f..c6ab0c5 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c -+++ b/xlators/mgmt/glusterd/src/glusterd-nfs-svc.c -@@ -95,6 +95,9 @@ glusterd_nfssvc_manager (glusterd_svc_t *svc, void *data, int flags) - goto out; - } - out: -+ if (ret) -+ gf_event (EVENT_SVC_MANAGER_FAILED, "svc_name=%s", svc->name); -+ - gf_msg_debug (THIS->name, 0, "Returning %d", ret); - - return ret; -diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index 409a205..d138e81 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c -+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -2195,8 +2195,13 @@ glusterd_stop_bricks (glusterd_volinfo_t *volinfo) - cds_list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { - /*TODO: Need to change @del_brick in brick_stop to _gf_true - * once we enable synctask in peer rpc prog */ -- if (glusterd_brick_stop (volinfo, brickinfo, _gf_false)) -+ if (glusterd_brick_stop (volinfo, brickinfo, _gf_false)) { -+ gf_event (EVENT_BRICK_STOP_FAILED, -+ "peer=%s;volume=%s;brick=%s", -+ brickinfo->hostname, volinfo->volname, -+ brickinfo->path); - return -1; -+ } - } - - return 0; -@@ -2218,6 +2223,10 @@ glusterd_start_bricks (glusterd_volinfo_t *volinfo) - "Failed to start %s:%s for %s", - brickinfo->hostname, brickinfo->path, - volinfo->volname); -+ gf_event (EVENT_BRICK_START_FAILED, -+ "peer=%s;volume=%s;brick=%s", -+ brickinfo->hostname, volinfo->volname, -+ brickinfo->path); - goto out; - } - } -diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c -index 377d206..2698160 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-pmap.c -+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c -@@ -217,7 +217,7 @@ pmap_assign_port (xlator_t *this, int old_port, const char *path) - GF_PMAP_PORT_BRICKSERVER, NULL); - if (ret) { - gf_msg (this->name, GF_LOG_WARNING, -- GD_MSG_PMAP_REGISTRY_REMOVE_FAIL, 0, "Failed toi" -+ GD_MSG_PMAP_REGISTRY_REMOVE_FAIL, 0, "Failed to" - "remove pmap registry for older signin for path" - " %s", path); - } -diff --git a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c -index f3475a3..3c457be 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c -+++ b/xlators/mgmt/glusterd/src/glusterd-quotad-svc.c -@@ -108,6 +108,9 @@ glusterd_quotadsvc_manager (glusterd_svc_t *svc, void *data, int flags) - } - } - out: -+ if (ret) -+ gf_event (EVENT_SVC_MANAGER_FAILED, "svc_name=%s", svc->name); -+ - gf_msg_debug (THIS->name, 0, "Returning %d", ret); - - return ret; -diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c -index 9ecbdfb..67d1c82 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c -+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c -@@ -1124,10 +1124,13 @@ glusterd_defrag_event_notify_handle (dict_t *dict) - - ret = glusterd_defrag_volume_status_update (volinfo, dict); - -- if (ret) -+ if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_DEFRAG_STATUS_UPDATE_FAIL, - "Failed to update status"); -+ gf_event (EVENT_DEFRAG_STATUS_UPDATE_FAILED, "volume=%s", -+ volinfo->volname); -+ } - - out: - return ret; -diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c -index 44ee6d0..72f0092 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c -+++ b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c -@@ -52,11 +52,13 @@ glusterd_svcs_reconfigure () - ret = glusterd_bitdsvc_reconfigure (); - if (ret) - goto out; -- - ret = glusterd_scrubsvc_reconfigure (); - if (ret) - goto out; - out: -+ if (ret) -+ gf_event (EVENT_SVC_RECONFIGURE_FAILED, ""); -+ - return ret; - } - --- -1.7.1 - diff --git a/SOURCES/0048-glusterd-introduce-timer-in-mgmt_v3_lock.patch b/SOURCES/0048-glusterd-introduce-timer-in-mgmt_v3_lock.patch new file mode 100644 index 0000000..2575bd2 --- /dev/null +++ b/SOURCES/0048-glusterd-introduce-timer-in-mgmt_v3_lock.patch @@ -0,0 +1,473 @@ +From f37a409a8c0fa683ad95a61bf71e949f215e2f81 Mon Sep 17 00:00:00 2001 +From: Gaurav Yadav +Date: Thu, 5 Oct 2017 23:44:46 +0530 +Subject: [PATCH 48/74] glusterd : introduce timer in mgmt_v3_lock + +Problem: +In a multinode environment, if two of the op-sm transactions +are initiated on one of the receiver nodes at the same time, +there might be a possibility that glusterd may end up in +stale lock. + +Solution: +During mgmt_v3_lock a registration is made to gf_timer_call_after +which release the lock after certain period of time + +>mainline patch : https://review.gluster.org/#/c/18437 + +Change-Id: I16cc2e5186a2e8a5e35eca2468b031811e093843 +BUG: 1442983 +Signed-off-by: Gaurav Yadav +Reviewed-on: https://code.engineering.redhat.com/gerrit/123069 +Reviewed-by: Atin Mukherjee +--- + extras/glusterd.vol.in | 1 + + libglusterfs/src/common-utils.h | 2 +- + libglusterfs/src/mem-types.h | 1 + + xlators/mgmt/glusterd/src/glusterd-locks.c | 219 +++++++++++++++++++++++++++-- + xlators/mgmt/glusterd/src/glusterd-locks.h | 13 ++ + xlators/mgmt/glusterd/src/glusterd.c | 28 +++- + xlators/mgmt/glusterd/src/glusterd.h | 2 + + 7 files changed, 246 insertions(+), 20 deletions(-) + +diff --git a/extras/glusterd.vol.in b/extras/glusterd.vol.in +index 0152996..fe413a9 100644 +--- a/extras/glusterd.vol.in ++++ b/extras/glusterd.vol.in +@@ -7,6 +7,7 @@ volume management + option transport.socket.read-fail-log off + option ping-timeout 0 + option event-threads 1 ++# option lock-timer 180 + # option transport.address-family inet6 + # option base-port 49152 + # option max-port 65535 +diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h +index e1c5f66..0131070 100644 +--- a/libglusterfs/src/common-utils.h ++++ b/libglusterfs/src/common-utils.h +@@ -102,7 +102,7 @@ void trap (void); + #define GF_CLNT_INSECURE_PORT_CEILING (GF_IANA_PRIV_PORTS_START - 1) + #define GF_PORT_MAX 65535 + #define GF_PORT_ARRAY_SIZE ((GF_PORT_MAX + 7) / 8) +- ++#define GF_LOCK_TIMER 180 + #define GF_MINUTE_IN_SECONDS 60 + #define GF_HOUR_IN_SECONDS (60*60) + #define GF_DAY_IN_SECONDS (24*60*60) +diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h +index d244fb5..85cb5d2 100644 +--- a/libglusterfs/src/mem-types.h ++++ b/libglusterfs/src/mem-types.h +@@ -177,6 +177,7 @@ enum gf_common_mem_types_ { + gf_common_mt_pthread_t, + gf_common_ping_local_t, + gf_common_volfile_t, ++ gf_common_mt_mgmt_v3_lock_timer_t, + gf_common_mt_end + }; + #endif +diff --git a/xlators/mgmt/glusterd/src/glusterd-locks.c b/xlators/mgmt/glusterd/src/glusterd-locks.c +index 146092d..bd73b37 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-locks.c ++++ b/xlators/mgmt/glusterd/src/glusterd-locks.c +@@ -94,6 +94,50 @@ glusterd_mgmt_v3_lock_fini () + dict_unref (priv->mgmt_v3_lock); + } + ++/* Initialize the global mgmt_v3_timer lock list(dict) when ++ * glusterd is spawned */ ++int32_t ++glusterd_mgmt_v3_lock_timer_init () ++{ ++ int32_t ret = -1; ++ xlator_t *this = NULL; ++ glusterd_conf_t *priv = NULL; ++ ++ this = THIS; ++ GF_VALIDATE_OR_GOTO ("glusterd", this, out); ++ ++ priv = this->private; ++ GF_VALIDATE_OR_GOTO (this->name, priv, out); ++ ++ priv->mgmt_v3_lock_timer = dict_new (); ++ if (!priv->mgmt_v3_lock_timer) ++ goto out; ++ ++ ret = 0; ++out: ++ return ret; ++} ++ ++/* Destroy the global mgmt_v3_timer lock list(dict) when ++ * glusterd cleanup is performed */ ++void ++glusterd_mgmt_v3_lock_timer_fini () ++{ ++ xlator_t *this = NULL; ++ glusterd_conf_t *priv = NULL; ++ ++ this = THIS; ++ GF_VALIDATE_OR_GOTO ("glusterd", this, out); ++ ++ priv = this->private; ++ GF_VALIDATE_OR_GOTO (this->name, priv, out); ++ ++ if (priv->mgmt_v3_lock_timer) ++ dict_unref (priv->mgmt_v3_lock_timer); ++out: ++ return; ++} ++ + int32_t + glusterd_get_mgmt_v3_lock_owner (char *key, uuid_t *uuid) + { +@@ -513,17 +557,23 @@ int32_t + glusterd_mgmt_v3_lock (const char *name, uuid_t uuid, uint32_t *op_errno, + char *type) + { +- char key[PATH_MAX] = ""; +- int32_t ret = -1; +- glusterd_mgmt_v3_lock_obj *lock_obj = NULL; +- glusterd_conf_t *priv = NULL; +- gf_boolean_t is_valid = _gf_true; +- uuid_t owner = {0}; +- xlator_t *this = NULL; +- char *bt = NULL; ++ char key[PATH_MAX] = ""; ++ int32_t ret = -1; ++ glusterd_mgmt_v3_lock_obj *lock_obj = NULL; ++ glusterd_mgmt_v3_lock_timer *mgmt_lock_timer = NULL; ++ glusterd_conf_t *priv = NULL; ++ gf_boolean_t is_valid = _gf_true; ++ uuid_t owner = {0}; ++ xlator_t *this = NULL; ++ char *bt = NULL; ++ struct timespec delay = {0}; ++ char *key_dup = NULL; ++ glusterfs_ctx_t *mgmt_lock_timer_ctx = NULL; ++ xlator_t *mgmt_lock_timer_xl = NULL; + + this = THIS; + GF_ASSERT (this); ++ + priv = this->private; + GF_ASSERT (priv); + +@@ -594,6 +644,42 @@ glusterd_mgmt_v3_lock (const char *name, uuid_t uuid, uint32_t *op_errno, + goto out; + } + ++ mgmt_lock_timer = GF_CALLOC (1, sizeof(glusterd_mgmt_v3_lock_timer), ++ gf_common_mt_mgmt_v3_lock_timer_t); ++ ++ if (!mgmt_lock_timer) { ++ ret = -1; ++ goto out; ++ } ++ ++ mgmt_lock_timer->xl = THIS; ++ key_dup = gf_strdup (key); ++ delay.tv_sec = priv->mgmt_v3_lock_timeout; ++ delay.tv_nsec = 0; ++ ++ ret = -1; ++ mgmt_lock_timer_xl = mgmt_lock_timer->xl; ++ GF_VALIDATE_OR_GOTO (this->name, mgmt_lock_timer_xl, out); ++ ++ mgmt_lock_timer_ctx = mgmt_lock_timer_xl->ctx; ++ GF_VALIDATE_OR_GOTO (this->name, mgmt_lock_timer_ctx, out); ++ ++ mgmt_lock_timer->timer = gf_timer_call_after ++ (mgmt_lock_timer_ctx, delay, ++ gd_mgmt_v3_unlock_timer_cbk, ++ key_dup); ++ ++ ret = dict_set_bin (priv->mgmt_v3_lock_timer, key, mgmt_lock_timer, ++ sizeof (glusterd_mgmt_v3_lock_timer)); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "Unable to set timer in mgmt_v3 lock"); ++ GF_FREE (mgmt_lock_timer); ++ goto out; ++ } ++ ++ + /* Saving the backtrace into the pre-allocated buffer, ctx->btbuf*/ + if ((bt = gf_backtrace_save (NULL))) { + snprintf (key, sizeof (key), "debug.last-success-bt-%s-%s", +@@ -617,18 +703,98 @@ out: + return ret; + } + ++/* ++ * This call back will ensure to unlock the lock_obj, in case we hit a situation ++ * where unlocking failed and stale lock exist*/ ++void ++gd_mgmt_v3_unlock_timer_cbk (void *data) ++{ ++ xlator_t *this = NULL; ++ glusterd_conf_t *conf = NULL; ++ glusterd_mgmt_v3_lock_timer *mgmt_lock_timer = NULL; ++ char *key = NULL; ++ char *type = NULL; ++ char bt_key[PATH_MAX] = ""; ++ char name[PATH_MAX] = ""; ++ int32_t ret = -1; ++ glusterfs_ctx_t *mgmt_lock_timer_ctx = NULL; ++ xlator_t *mgmt_lock_timer_xl = NULL; ++ ++ this = THIS; ++ GF_VALIDATE_OR_GOTO ("glusterd", this, out); ++ ++ conf = this->private; ++ GF_VALIDATE_OR_GOTO (this->name, conf, out); ++ ++ gf_log (THIS->name, GF_LOG_INFO, "In gd_mgmt_v3_unlock_timer_cbk"); ++ GF_ASSERT (NULL != data); ++ key = (char *)data; ++ ++ dict_del (conf->mgmt_v3_lock, key); ++ ++ type = strrchr (key, '_'); ++ strncpy (name, key, strlen (key) - strlen (type) - 1); ++ ++ ret = snprintf (bt_key, PATH_MAX, "debug.last-success-bt-%s-%s", ++ name, type + 1); ++ if (ret != strlen ("debug.last-success-bt-") + strlen (name) + ++ strlen (type)) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_CREATE_KEY_FAIL, "Unable to create backtrace " ++ "key"); ++ goto out; ++ } ++ ++ dict_del (conf->mgmt_v3_lock, bt_key); ++ ++ ret = dict_get_bin (conf->mgmt_v3_lock_timer, key, ++ (void **)&mgmt_lock_timer); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "Unable to get lock owner in mgmt_v3 lock"); ++ goto out; ++ } ++ ++out: ++ if (mgmt_lock_timer->timer) { ++ mgmt_lock_timer_xl = mgmt_lock_timer->xl; ++ GF_VALIDATE_OR_GOTO (this->name, mgmt_lock_timer_xl, ++ ret_function); ++ ++ mgmt_lock_timer_ctx = mgmt_lock_timer_xl->ctx; ++ GF_VALIDATE_OR_GOTO (this->name, mgmt_lock_timer_ctx, ++ ret_function); ++ ++ gf_timer_call_cancel (mgmt_lock_timer_ctx, ++ mgmt_lock_timer->timer); ++ GF_FREE(key); ++ dict_del (conf->mgmt_v3_lock_timer, bt_key); ++ mgmt_lock_timer->timer = NULL; ++ } ++ ++ret_function: ++ ++ return; ++} ++ + int32_t + glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type) + { +- char key[PATH_MAX] = ""; +- int32_t ret = -1; +- gf_boolean_t is_valid = _gf_true; +- glusterd_conf_t *priv = NULL; +- uuid_t owner = {0}; +- xlator_t *this = NULL; ++ char key[PATH_MAX] = ""; ++ char key_dup[PATH_MAX] = ""; ++ int32_t ret = -1; ++ gf_boolean_t is_valid = _gf_true; ++ glusterd_conf_t *priv = NULL; ++ glusterd_mgmt_v3_lock_timer *mgmt_lock_timer = NULL; ++ uuid_t owner = {0}; ++ xlator_t *this = NULL; ++ glusterfs_ctx_t *mgmt_lock_timer_ctx = NULL; ++ xlator_t *mgmt_lock_timer_xl = NULL; + + this = THIS; + GF_ASSERT (this); ++ + priv = this->private; + GF_ASSERT (priv); + +@@ -657,6 +823,7 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type) + ret = -1; + goto out; + } ++ strncpy (key_dup, key, strlen(key)); + + gf_msg_debug (this->name, 0, + "Trying to release lock of %s %s for %s as %s", +@@ -690,6 +857,15 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type) + /* Removing the mgmt_v3 lock from the global list */ + dict_del (priv->mgmt_v3_lock, key); + ++ ret = dict_get_bin (priv->mgmt_v3_lock_timer, key, ++ (void **)&mgmt_lock_timer); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "Unable to get mgmt lock key in mgmt_v3 lock"); ++ goto out; ++ } ++ + /* Remove the backtrace key as well */ + ret = snprintf (key, sizeof(key), "debug.last-success-bt-%s-%s", name, + type); +@@ -708,7 +884,22 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type) + type, name); + + ret = 0; ++ /* Release owner refernce which was held during lock */ ++ if (mgmt_lock_timer->timer) { ++ ret = -1; ++ mgmt_lock_timer_xl = mgmt_lock_timer->xl; ++ GF_VALIDATE_OR_GOTO (this->name, mgmt_lock_timer_xl, out); ++ ++ mgmt_lock_timer_ctx = mgmt_lock_timer_xl->ctx; ++ GF_VALIDATE_OR_GOTO (this->name, mgmt_lock_timer_ctx, out); ++ ret = 0; ++ gf_timer_call_cancel (mgmt_lock_timer_ctx, ++ mgmt_lock_timer->timer); ++ dict_del (priv->mgmt_v3_lock_timer, key_dup); ++ mgmt_lock_timer->timer = NULL; ++ } + out: ++ + gf_msg_trace (this->name, 0, "Returning %d", ret); + return ret; + } +diff --git a/xlators/mgmt/glusterd/src/glusterd-locks.h b/xlators/mgmt/glusterd/src/glusterd-locks.h +index 437053d..226d5c6 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-locks.h ++++ b/xlators/mgmt/glusterd/src/glusterd-locks.h +@@ -14,6 +14,11 @@ typedef struct glusterd_mgmt_v3_lock_object_ { + uuid_t lock_owner; + } glusterd_mgmt_v3_lock_obj; + ++typedef struct glusterd_mgmt_v3_lock_timer_ { ++ gf_timer_t *timer; ++ xlator_t *xl; ++} glusterd_mgmt_v3_lock_timer; ++ + typedef struct glusterd_mgmt_v3_lock_valid_entities { + char *type; /* Entity type like vol, snap */ + gf_boolean_t default_value; /* The default value that * +@@ -29,6 +34,12 @@ void + glusterd_mgmt_v3_lock_fini (); + + int32_t ++glusterd_mgmt_v3_lock_timer_init (); ++ ++void ++glusterd_mgmt_v3_lock_timer_fini (); ++ ++int32_t + glusterd_get_mgmt_v3_lock_owner (char *volname, uuid_t *uuid); + + int32_t +@@ -44,4 +55,6 @@ glusterd_multiple_mgmt_v3_lock (dict_t *dict, uuid_t uuid, uint32_t *op_errno); + int32_t + glusterd_multiple_mgmt_v3_unlock (dict_t *dict, uuid_t uuid); + ++void ++gd_mgmt_v3_unlock_timer_cbk(void *data); + #endif +diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c +index 6ce4156..ed01b93 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.c ++++ b/xlators/mgmt/glusterd/src/glusterd.c +@@ -1858,14 +1858,22 @@ init (xlator_t *this) + gf_msg (this->name, GF_LOG_INFO, 0, + GD_MSG_DICT_SET_FAILED, + "base-port override: %d", conf->base_port); +- } +- conf->max_port = GF_PORT_MAX; +- if (dict_get_uint32 (this->options, "max-port", +- &conf->max_port) == 0) { ++ } ++ conf->max_port = GF_PORT_MAX; ++ if (dict_get_uint32 (this->options, "max-port", ++ &conf->max_port) == 0) { + gf_msg (this->name, GF_LOG_INFO, 0, + GD_MSG_DICT_SET_FAILED, + "max-port override: %d", conf->max_port); +- } ++ } ++ ++ conf->mgmt_v3_lock_timeout = GF_LOCK_TIMER; ++ if (dict_get_uint32 (this->options, "lock-timer", ++ &conf->mgmt_v3_lock_timeout) == 0) { ++ gf_msg (this->name, GF_LOG_INFO, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "lock-timer override: %d", conf->mgmt_v3_lock_timeout); ++ } + + /* Set option to run bricks on valgrind if enabled in glusterd.vol */ + this->ctx->cmd_args.valgrind = valgrind; +@@ -1891,6 +1899,7 @@ init (xlator_t *this) + + this->private = conf; + glusterd_mgmt_v3_lock_init (); ++ glusterd_mgmt_v3_lock_timer_init(); + glusterd_txn_opinfo_dict_init (); + glusterd_svcs_build (); + +@@ -2048,6 +2057,7 @@ fini (xlator_t *this) + gf_store_handle_destroy (conf->handle); + glusterd_sm_tr_log_delete (&conf->op_sm_log); + glusterd_mgmt_v3_lock_fini (); ++ glusterd_mgmt_v3_lock_timer_fini (); + glusterd_txn_opinfo_dict_fini (); + GF_FREE (conf); + +@@ -2171,6 +2181,14 @@ struct volume_options options[] = { + .max = GF_PORT_MAX, + .description = "Sets the max port for portmap query" + }, ++ { .key = {"mgmt-v3-lock-timeout"}, ++ .type = GF_OPTION_TYPE_INT, ++ .max = 600, ++ .description = "Sets the mgmt-v3-lock-timeout for transactions." ++ "Specifes the default timeout value after which " ++ "lock acquired while performing transaction will " ++ "be released." ++ }, + { .key = {"snap-brick-path"}, + .type = GF_OPTION_TYPE_STR, + .description = "directory where the bricks for the snapshots will be created" +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index 291f2f7..59b1775 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -174,6 +174,7 @@ typedef struct { + * cluster with no + * transaction ids */ + ++ dict_t *mgmt_v3_lock_timer; + struct cds_list_head mount_specs; + pthread_t brick_thread; + void *hooks_priv; +@@ -195,6 +196,7 @@ typedef struct { + uint32_t generation; + int32_t workers; + uint32_t blockers; ++ uint32_t mgmt_v3_lock_timeout; + } glusterd_conf_t; + + +-- +1.8.3.1 + diff --git a/SOURCES/0049-Revert-packaging-ganesha-remove-glusterfs-ganesha-su.patch b/SOURCES/0049-Revert-packaging-ganesha-remove-glusterfs-ganesha-su.patch new file mode 100644 index 0000000..c112911 --- /dev/null +++ b/SOURCES/0049-Revert-packaging-ganesha-remove-glusterfs-ganesha-su.patch @@ -0,0 +1,514 @@ +From 2278782dddf80611c7305ed982532647e38b5664 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Mon, 16 Oct 2017 14:18:31 +0530 +Subject: [PATCH 49/74] Revert "packaging: (ganesha) remove glusterfs-ganesha + subpackage and related files)" + +This reverts commit 0cf2963f12a8b540a7042605d8c79f638fdf6cee. + +Change-Id: Id6e7585021bd4dd78a59580cfa4838bdd4e539a0 +Signed-off-by: Jiffin Tony Thottan +--- + configure.ac | 3 + + extras/Makefile.am | 2 +- + extras/ganesha/Makefile.am | 2 + + extras/ganesha/config/Makefile.am | 4 + + extras/ganesha/config/ganesha-ha.conf.sample | 19 ++++ + extras/ganesha/scripts/Makefile.am | 4 + + extras/ganesha/scripts/create-export-ganesha.sh | 91 +++++++++++++++ + extras/ganesha/scripts/dbus-send.sh | 61 +++++++++++ + extras/ganesha/scripts/generate-epoch.py | 48 ++++++++ + extras/hook-scripts/start/post/Makefile.am | 2 +- + extras/hook-scripts/start/post/S31ganesha-start.sh | 122 +++++++++++++++++++++ + glusterfs.spec.in | 10 +- + 12 files changed, 362 insertions(+), 6 deletions(-) + create mode 100644 extras/ganesha/Makefile.am + create mode 100644 extras/ganesha/config/Makefile.am + create mode 100644 extras/ganesha/config/ganesha-ha.conf.sample + create mode 100644 extras/ganesha/scripts/Makefile.am + create mode 100755 extras/ganesha/scripts/create-export-ganesha.sh + create mode 100755 extras/ganesha/scripts/dbus-send.sh + create mode 100755 extras/ganesha/scripts/generate-epoch.py + create mode 100755 extras/hook-scripts/start/post/S31ganesha-start.sh + +diff --git a/configure.ac b/configure.ac +index dfccd40..c8e6e44 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -207,6 +207,9 @@ AC_CONFIG_FILES([Makefile + extras/init.d/glustereventsd-Debian + extras/init.d/glustereventsd-Redhat + extras/init.d/glustereventsd-FreeBSD ++ extras/ganesha/Makefile ++ extras/ganesha/config/Makefile ++ extras/ganesha/scripts/Makefile + extras/systemd/Makefile + extras/systemd/glusterd.service + extras/systemd/glustereventsd.service +diff --git a/extras/Makefile.am b/extras/Makefile.am +index 6863772..2812a4c 100644 +--- a/extras/Makefile.am ++++ b/extras/Makefile.am +@@ -8,7 +8,7 @@ EditorModedir = $(docdir) + EditorMode_DATA = glusterfs-mode.el glusterfs.vim + + SUBDIRS = init.d systemd benchmarking hook-scripts $(OCF_SUBDIR) LinuxRPM \ +- $(GEOREP_EXTRAS_SUBDIR) snap_scheduler firewalld cliutils ++ $(GEOREP_EXTRAS_SUBDIR) ganesha snap_scheduler firewalld cliutils + + confdir = $(sysconfdir)/glusterfs + conf_DATA = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \ +diff --git a/extras/ganesha/Makefile.am b/extras/ganesha/Makefile.am +new file mode 100644 +index 0000000..542de68 +--- /dev/null ++++ b/extras/ganesha/Makefile.am +@@ -0,0 +1,2 @@ ++SUBDIRS = scripts config ++CLEANFILES = +diff --git a/extras/ganesha/config/Makefile.am b/extras/ganesha/config/Makefile.am +new file mode 100644 +index 0000000..c729273 +--- /dev/null ++++ b/extras/ganesha/config/Makefile.am +@@ -0,0 +1,4 @@ ++EXTRA_DIST= ganesha-ha.conf.sample ++ ++confdir = $(sysconfdir)/ganesha ++conf_DATA = ganesha-ha.conf.sample +diff --git a/extras/ganesha/config/ganesha-ha.conf.sample b/extras/ganesha/config/ganesha-ha.conf.sample +new file mode 100644 +index 0000000..c22892b +--- /dev/null ++++ b/extras/ganesha/config/ganesha-ha.conf.sample +@@ -0,0 +1,19 @@ ++# Name of the HA cluster created. ++# must be unique within the subnet ++HA_NAME="ganesha-ha-360" ++# ++# N.B. you may use short names or long names; you may not use IP addrs. ++# Once you select one, stay with it as it will be mildly unpleasant to ++# clean up if you switch later on. Ensure that all names - short and/or ++# long - are in DNS or /etc/hosts on all machines in the cluster. ++# ++# The subset of nodes of the Gluster Trusted Pool that form the ganesha ++# HA cluster. Hostname is specified. ++HA_CLUSTER_NODES="server1,server2,..." ++#HA_CLUSTER_NODES="server1.lab.redhat.com,server2.lab.redhat.com,..." ++# ++# Virtual IPs for each of the nodes specified above. ++VIP_server1="10.0.2.1" ++VIP_server2="10.0.2.2" ++#VIP_server1_lab_redhat_com="10.0.2.1" ++#VIP_server2_lab_redhat_com="10.0.2.2" +diff --git a/extras/ganesha/scripts/Makefile.am b/extras/ganesha/scripts/Makefile.am +new file mode 100644 +index 0000000..9ee8867 +--- /dev/null ++++ b/extras/ganesha/scripts/Makefile.am +@@ -0,0 +1,4 @@ ++EXTRA_DIST= create-export-ganesha.sh generate-epoch.py dbus-send.sh ++ ++scriptsdir = $(libexecdir)/ganesha ++scripts_SCRIPTS = create-export-ganesha.sh generate-epoch.py +diff --git a/extras/ganesha/scripts/create-export-ganesha.sh b/extras/ganesha/scripts/create-export-ganesha.sh +new file mode 100755 +index 0000000..1ffba42 +--- /dev/null ++++ b/extras/ganesha/scripts/create-export-ganesha.sh +@@ -0,0 +1,91 @@ ++#!/bin/bash ++ ++#This script is called by glusterd when the user ++#tries to export a volume via NFS-Ganesha. ++#An export file specific to a volume ++#is created in GANESHA_DIR/exports. ++ ++# Try loading the config from any of the distro ++# specific configuration locations ++if [ -f /etc/sysconfig/ganesha ] ++ then ++ . /etc/sysconfig/ganesha ++fi ++if [ -f /etc/conf.d/ganesha ] ++ then ++ . /etc/conf.d/ganesha ++fi ++if [ -f /etc/default/ganesha ] ++ then ++ . /etc/default/ganesha ++fi ++ ++GANESHA_DIR=${1%/} ++OPTION=$2 ++VOL=$3 ++CONF=$GANESHA_DIR"/ganesha.conf" ++declare -i EXPORT_ID ++ ++function check_cmd_status() ++{ ++ if [ "$1" != "0" ] ++ then ++ rm -rf $GANESHA_DIR/exports/export.$VOL.conf ++ sed -i /$VOL.conf/d $CONF ++ exit 1 ++ fi ++} ++ ++ ++if [ ! -d "$GANESHA_DIR/exports" ]; ++ then ++ mkdir $GANESHA_DIR/exports ++ check_cmd_status `echo $?` ++fi ++ ++function write_conf() ++{ ++echo -e "# WARNING : Using Gluster CLI will overwrite manual ++# changes made to this file. To avoid it, edit the ++# file and run ganesha-ha.sh --refresh-config." ++ ++echo "EXPORT{" ++echo " Export_Id = 2;" ++echo " Path = \"/$VOL\";" ++echo " FSAL {" ++echo " name = "GLUSTER";" ++echo " hostname=\"localhost\";" ++echo " volume=\"$VOL\";" ++echo " }" ++echo " Access_type = RW;" ++echo " Disable_ACL = true;" ++echo ' Squash="No_root_squash";' ++echo " Pseudo=\"/$VOL\";" ++echo ' Protocols = "3", "4" ;' ++echo ' Transports = "UDP","TCP";' ++echo ' SecType = "sys";' ++echo " }" ++} ++if [ "$OPTION" = "on" ]; ++then ++ if ! (cat $CONF | grep $VOL.conf\"$ ) ++ then ++ write_conf $@ > $GANESHA_DIR/exports/export.$VOL.conf ++ echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF ++ count=`ls -l $GANESHA_DIR/exports/*.conf | wc -l` ++ if [ "$count" = "1" ] ; then ++ EXPORT_ID=2 ++ else ++ EXPORT_ID=`cat $GANESHA_DIR/.export_added` ++ check_cmd_status `echo $?` ++ EXPORT_ID=EXPORT_ID+1 ++ sed -i s/Export_Id.*/"Export_Id= $EXPORT_ID ;"/ \ ++ $GANESHA_DIR/exports/export.$VOL.conf ++ check_cmd_status `echo $?` ++ fi ++ echo $EXPORT_ID > $GANESHA_DIR/.export_added ++ fi ++else ++ rm -rf $GANESHA_DIR/exports/export.$VOL.conf ++ sed -i /$VOL.conf/d $CONF ++fi +diff --git a/extras/ganesha/scripts/dbus-send.sh b/extras/ganesha/scripts/dbus-send.sh +new file mode 100755 +index 0000000..c071d03 +--- /dev/null ++++ b/extras/ganesha/scripts/dbus-send.sh +@@ -0,0 +1,61 @@ ++#!/bin/bash ++ ++# Try loading the config from any of the distro ++# specific configuration locations ++if [ -f /etc/sysconfig/ganesha ] ++ then ++ . /etc/sysconfig/ganesha ++fi ++if [ -f /etc/conf.d/ganesha ] ++ then ++ . /etc/conf.d/ganesha ++fi ++if [ -f /etc/default/ganesha ] ++ then ++ . /etc/default/ganesha ++fi ++ ++GANESHA_DIR=${1%/} ++OPTION=$2 ++VOL=$3 ++CONF=$GANESHA_DIR"/ganesha.conf" ++ ++function check_cmd_status() ++{ ++ if [ "$1" != "0" ] ++ then ++ logger "dynamic export failed on node :${hostname -s}" ++ fi ++} ++ ++#This function keeps track of export IDs and increments it with every new entry ++function dynamic_export_add() ++{ ++ dbus-send --system \ ++--dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ ++org.ganesha.nfsd.exportmgr.AddExport string:$GANESHA_DIR/exports/export.$VOL.conf \ ++string:"EXPORT(Path=/$VOL)" ++ check_cmd_status `echo $?` ++} ++ ++#This function removes an export dynamically(uses the export_id of the export) ++function dynamic_export_remove() ++{ ++ removed_id=`cat $GANESHA_DIR/exports/export.$VOL.conf |\ ++grep Export_Id | awk -F"[=,;]" '{print$2}'| tr -d '[[:space:]]'` ++ dbus-send --print-reply --system \ ++--dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ ++org.ganesha.nfsd.exportmgr.RemoveExport uint16:$removed_id ++ check_cmd_status `echo $?` ++} ++ ++if [ "$OPTION" = "on" ]; ++then ++ dynamic_export_add $@ ++fi ++ ++if [ "$OPTION" = "off" ]; ++then ++ dynamic_export_remove $@ ++fi ++ +diff --git a/extras/ganesha/scripts/generate-epoch.py b/extras/ganesha/scripts/generate-epoch.py +new file mode 100755 +index 0000000..5db5e56 +--- /dev/null ++++ b/extras/ganesha/scripts/generate-epoch.py +@@ -0,0 +1,48 @@ ++#!/usr/bin/python ++# ++# Copyright (c) 2016 Red Hat, Inc. ++# This file is part of GlusterFS. ++# ++# This file is licensed to you under your choice of the GNU Lesser ++# General Public License, version 3 or any later version (LGPLv3 or ++# later), or the GNU General Public License, version 2 (GPLv2), in all ++# cases as published by the Free Software Foundation. ++# ++# Generates unique epoch value on each gluster node to be used by ++# nfs-ganesha service on that node. ++# ++# Configure 'EPOCH_EXEC' option to this script path in ++# '/etc/sysconfig/ganesha' file used by nfs-ganesha service. ++# ++# Construct epoch as follows - ++# first 32-bit contains the now() time ++# rest 32-bit value contains the local glusterd node uuid ++ ++import time ++import binascii ++ ++# Calculate the now() time into a 64-bit integer value ++def epoch_now(): ++ epoch_time = int(time.mktime(time.localtime())) << 32 ++ return epoch_time ++ ++# Read glusterd UUID and extract first 32-bit of it ++def epoch_uuid(): ++ file_name = '/var/lib/glusterd/glusterd.info' ++ ++ for line in open(file_name): ++ if "UUID" in line: ++ glusterd_uuid = line.split('=')[1].strip() ++ ++ uuid_bin = binascii.unhexlify(glusterd_uuid.replace("-","")) ++ ++ epoch_uuid = int(uuid_bin.encode('hex'), 32) & 0xFFFF0000 ++ return epoch_uuid ++ ++# Construct epoch as follows - ++# first 32-bit contains the now() time ++# rest 32-bit value contains the local glusterd node uuid ++epoch = (epoch_now() | epoch_uuid()) ++print str(epoch) ++ ++exit(0) +diff --git a/extras/hook-scripts/start/post/Makefile.am b/extras/hook-scripts/start/post/Makefile.am +index 384a582..03bb300 100644 +--- a/extras/hook-scripts/start/post/Makefile.am ++++ b/extras/hook-scripts/start/post/Makefile.am +@@ -1,4 +1,4 @@ +-EXTRA_DIST = S29CTDBsetup.sh S30samba-start.sh ++EXTRA_DIST = S29CTDBsetup.sh S30samba-start.sh S31ganesha-start.sh + + hookdir = $(GLUSTERD_WORKDIR)/hooks/1/start/post/ + hook_SCRIPTS = $(EXTRA_DIST) +diff --git a/extras/hook-scripts/start/post/S31ganesha-start.sh b/extras/hook-scripts/start/post/S31ganesha-start.sh +new file mode 100755 +index 0000000..90ba6bc +--- /dev/null ++++ b/extras/hook-scripts/start/post/S31ganesha-start.sh +@@ -0,0 +1,122 @@ ++#!/bin/bash ++PROGNAME="Sganesha-start" ++OPTSPEC="volname:,gd-workdir:" ++VOL= ++declare -i EXPORT_ID ++ganesha_key="ganesha.enable" ++GANESHA_DIR="/var/run/gluster/shared_storage/nfs-ganesha" ++CONF1="$GANESHA_DIR/ganesha.conf" ++GLUSTERD_WORKDIR= ++ ++function parse_args () ++{ ++ ARGS=$(getopt -l $OPTSPEC -o "o" -name $PROGNAME $@) ++ eval set -- "$ARGS" ++ ++ while true; do ++ case $1 in ++ --volname) ++ shift ++ VOL=$1 ++ ;; ++ --gd-workdir) ++ shift ++ GLUSTERD_WORKDIR=$1 ++ ;; ++ *) ++ shift ++ break ++ ;; ++ esac ++ shift ++ done ++} ++ ++ ++ ++#This function generates a new export entry as export.volume_name.conf ++function write_conf() ++{ ++echo -e "# WARNING : Using Gluster CLI will overwrite manual ++# changes made to this file. To avoid it, edit the ++# file, copy it over to all the NFS-Ganesha nodes ++# and run ganesha-ha.sh --refresh-config." ++ ++echo "EXPORT{" ++echo " Export_Id = 2;" ++echo " Path = \"/$VOL\";" ++echo " FSAL {" ++echo " name = \"GLUSTER\";" ++echo " hostname=\"localhost\";" ++echo " volume=\"$VOL\";" ++echo " }" ++echo " Access_type = RW;" ++echo " Disable_ACL = true;" ++echo " Squash=\"No_root_squash\";" ++echo " Pseudo=\"/$VOL\";" ++echo " Protocols = \"3\", \"4\" ;" ++echo " Transports = \"UDP\",\"TCP\";" ++echo " SecType = \"sys\";" ++echo "}" ++} ++ ++#It adds the export dynamically by sending dbus signals ++function export_add() ++{ ++ dbus-send --print-reply --system --dest=org.ganesha.nfsd \ ++/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.AddExport \ ++string:$GANESHA_DIR/exports/export.$VOL.conf string:"EXPORT(Export_Id=$EXPORT_ID)" ++ ++} ++ ++# based on src/scripts/ganeshactl/Ganesha/export_mgr.py ++function is_exported() ++{ ++ local volume="${1}" ++ ++ dbus-send --type=method_call --print-reply --system \ ++ --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ ++ org.ganesha.nfsd.exportmgr.ShowExports \ ++ | grep -w -q "/${volume}" ++ ++ return $? ++} ++ ++# Check the info file (contains the volume options) to see if Ganesha is ++# enabled for this volume. ++function ganesha_enabled() ++{ ++ local volume="${1}" ++ local info_file="${GLUSTERD_WORKDIR}/vols/${VOL}/info" ++ local enabled="off" ++ ++ enabled=$(grep -w ${ganesha_key} ${info_file} | cut -d"=" -f2) ++ ++ [ "${enabled}" == "on" ] ++ ++ return $? ++} ++ ++parse_args $@ ++ ++if ganesha_enabled ${VOL} && ! is_exported ${VOL} ++then ++ if [ ! -e ${GANESHA_DIR}/exports/export.${VOL}.conf ] ++ then ++ #Remove export entry from nfs-ganesha.conf ++ sed -i /$VOL.conf/d $CONF1 ++ write_conf ${VOL} > ${GANESHA_DIR}/exports/export.${VOL}.conf ++ EXPORT_ID=`cat $GANESHA_DIR/.export_added` ++ EXPORT_ID=EXPORT_ID+1 ++ echo $EXPORT_ID > $GANESHA_DIR/.export_added ++ sed -i s/Export_Id.*/"Export_Id=$EXPORT_ID;"/ \ ++ $GANESHA_DIR/exports/export.$VOL.conf ++ echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF1 ++ else ++ EXPORT_ID=$(grep ^[[:space:]]*Export_Id $GANESHA_DIR/exports/export.$VOL.conf |\ ++ awk -F"[=,;]" '{print $2}' | tr -d '[[:space:]]') ++ fi ++ export_add $VOL ++fi ++ ++exit 0 +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 10339fe..6e710e5 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -262,7 +262,6 @@ Obsoletes: hekafs + Obsoletes: %{name}-common < %{version}-%{release} + Obsoletes: %{name}-core < %{version}-%{release} + Obsoletes: %{name}-ufo +-Obsoletes: %{name}-ganesha + Provides: %{name}-common = %{version}-%{release} + Provides: %{name}-core = %{version}-%{release} + +@@ -1275,6 +1274,9 @@ exit 0 + + %if ( 0%{?_build_server} ) + %files ganesha ++%{_sysconfdir}/ganesha/* ++%{_libexecdir}/ganesha/* ++%{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh + %endif + + %if ( 0%{?_build_server} ) +@@ -2121,6 +2123,9 @@ fi + + %changelog + * Mon Nov 13 2017 Jiffin Tony Thottan ++- Adding ganesha bits back in gluster repository #1499784 ++ ++* Mon Nov 13 2017 Jiffin Tony Thottan + - DOWNSTREAM ONLY - revert of 83abcb(gnfs in an optional subpackage) + + * Tue Oct 10 2017 Milind Changire +@@ -2178,9 +2183,6 @@ fi + * Thu Feb 16 2017 Niels de Vos + - Obsolete and Provide python-gluster for upgrading from glusterfs < 3.10 + +-* Tue Feb 7 2017 Kaleb S. KEITHLEY +-- remove ganesha (#1418417) +- + * Wed Feb 1 2017 Poornima G + - Install /var/lib/glusterd/groups/metadata-cache by default + +-- +1.8.3.1 + diff --git a/SOURCES/0049-glusterd-add-async-events-part-2.patch b/SOURCES/0049-glusterd-add-async-events-part-2.patch deleted file mode 100644 index eafa33f..0000000 --- a/SOURCES/0049-glusterd-add-async-events-part-2.patch +++ /dev/null @@ -1,389 +0,0 @@ -From 8cb14d157652ca92c927a61476263c238195548a Mon Sep 17 00:00:00 2001 -From: Atin Mukherjee -Date: Fri, 12 Aug 2016 10:22:17 +0530 -Subject: [PATCH 49/86] glusterd: add async events (part 2) - ->Reviewed-on: http://review.gluster.org/15153 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Samikshan Bairagya - -Change-Id: I7a5687143713c283f0051aac2383f780e3e43646 -BUG: 1360807 -Signed-off-by: Atin Mukherjee -Reviewed-on: https://code.engineering.redhat.com/gerrit/84795 ---- - events/eventskeygen.py | 14 ++++- - xlators/mgmt/glusterd/src/glusterd-rebalance.c | 2 +- - xlators/mgmt/glusterd/src/glusterd-scrub-svc.c | 2 + - xlators/mgmt/glusterd/src/glusterd-server-quorum.c | 2 + - xlators/mgmt/glusterd/src/glusterd-shd-svc.c | 2 + - xlators/mgmt/glusterd/src/glusterd-snapd-svc.c | 42 +++++++++----- - xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c | 3 + - xlators/mgmt/glusterd/src/glusterd-utils.c | 60 ++++++++++++++++---- - 8 files changed, 99 insertions(+), 28 deletions(-) - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 570c905..885c9de 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -49,8 +49,9 @@ keys = ( - - "EVENT_SVC_MANAGER_FAILED", - "EVENT_SVC_RECONFIGURE_FAILED", -+ "EVENT_SVC_CONNECTED", -+ "EVENT_SVC_DISCONNECTED", - -- "EVENT_DEFRAG_STATUS_UPDATE_FAILED", - - "EVENT_PEER_STORE_FAILURE", - "EVENT_PEER_RPC_CREATE_FAILED", -@@ -64,8 +65,19 @@ keys = ( - "EVENT_BRICK_STOP_FAILED", - "EVENT_BRICK_DISCONNECTED", - "EVENT_BRICK_CONNECTED", -+ "EVENT_BRICKS_START_FAILED", -+ "EVENT_BRICKPATH_RESOLVE_FAILED", - - "EVENT_NOTIFY_UNKNOWN_OP", -+ "EVENT_QUORUM_LOST", -+ "EVENT_QUORUM_REGAINED", -+ "EVENT_REBALANCE_START_FAILED", -+ "EVENT_REBALANCE_STATUS_UPDATE_FAILED", -+ "EVENT_IMPORT_QUOTA_CONF_FAILED", -+ "EVENT_IMPORT_VOLUME_FAILED", -+ "EVENT_IMPORT_BRICK_FAILED", -+ "EVENT_COMPARE_FRIEND_VOLUME_FAILED", -+ "EVENT_NFS_GANESHA_EXPORT_FAILED", - ) - - LAST_EVENT = "EVENT_LAST" -diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c -index 67d1c82..c2f1e45 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c -+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c -@@ -1128,7 +1128,7 @@ glusterd_defrag_event_notify_handle (dict_t *dict) - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_DEFRAG_STATUS_UPDATE_FAIL, - "Failed to update status"); -- gf_event (EVENT_DEFRAG_STATUS_UPDATE_FAILED, "volume=%s", -+ gf_event (EVENT_REBALANCE_STATUS_UPDATE_FAILED, "volume=%s", - volinfo->volname); - } - -diff --git a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c -index 3761dba..7544529 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c -+++ b/xlators/mgmt/glusterd/src/glusterd-scrub-svc.c -@@ -101,6 +101,8 @@ glusterd_scrubsvc_manager (glusterd_svc_t *svc, void *data, int flags) - } - - out: -+ if (ret) -+ gf_event (EVENT_SVC_MANAGER_FAILED, "svc_name=%s", svc->name); - gf_msg_debug (THIS->name, 0, "Returning %d", ret); - - return ret; -diff --git a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c -index ecf9d53..35f6ad1 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c -+++ b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c -@@ -339,11 +339,13 @@ glusterd_do_volume_quorum_action (xlator_t *this, glusterd_volinfo_t *volinfo, - GD_MSG_SERVER_QUORUM_MET_STARTING_BRICKS, - "Server quorum regained for volume %s. Starting local " - "bricks.", volinfo->volname); -+ gf_event (EVENT_QUORUM_REGAINED, "volume=%s", volinfo->volname); - } else if (quorum_status == DOESNT_MEET_QUORUM) { - gf_msg (this->name, GF_LOG_CRITICAL, 0, - GD_MSG_SERVER_QUORUM_LOST_STOPPING_BRICKS, - "Server quorum lost for volume %s. Stopping local " - "bricks.", volinfo->volname); -+ gf_event (EVENT_QUORUM_LOST, "volume=%s", volinfo->volname); - } - - list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { -diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c -index 0e664b5..e0135ea 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c -+++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c -@@ -136,6 +136,8 @@ glusterd_shdsvc_manager (glusterd_svc_t *svc, void *data, int flags) - } - } - out: -+ if (ret) -+ gf_event (EVENT_SVC_MANAGER_FAILED, "svc_name=%s", svc->name); - gf_msg_debug (THIS->name, 0, "Returning %d", ret); - - return ret; -diff --git a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c -index 36e4a19..acb24ff 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c -+++ b/xlators/mgmt/glusterd/src/glusterd-snapd-svc.c -@@ -204,6 +204,10 @@ glusterd_snapdsvc_manager (glusterd_svc_t *svc, void *data, int flags) - } - - out: -+ if (ret) { -+ gf_event (EVENT_SVC_MANAGER_FAILED, "volume=%s;svc_name=%s", -+ volinfo->volname, svc->name); -+ } - gf_msg_debug (THIS->name, 0, "Returning %d", ret); - - return ret; -@@ -347,6 +351,9 @@ glusterd_snapdsvc_restart () - GD_MSG_SNAPD_START_FAIL, - "Couldn't resolve snapd for " - "vol: %s on restart", volinfo->volname); -+ gf_event (EVENT_SVC_MANAGER_FAILED, -+ "volume=%s;svc_name=%s", -+ volinfo->volname, svc->name); - goto out; - } - } -@@ -373,11 +380,28 @@ glusterd_snapdsvc_rpc_notify (glusterd_conn_t *conn, rpc_clnt_event_t event) - GD_MSG_SVC_GET_FAIL, "Failed to get the service"); - return -1; - } -+ snapd = cds_list_entry (svc, glusterd_snapdsvc_t, svc); -+ if (!snapd) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_SNAPD_OBJ_GET_FAIL, "Failed to get the " -+ "snapd object"); -+ return -1; -+ } -+ -+ volinfo = cds_list_entry (snapd, glusterd_volinfo_t, snapd); -+ if (!volinfo) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_VOLINFO_GET_FAIL, "Failed to get the " -+ "volinfo object"); -+ return -1; -+ } - - switch (event) { - case RPC_CLNT_CONNECT: - gf_msg_debug (this->name, 0, "%s has connected with " - "glusterd.", svc->name); -+ gf_event (EVENT_SVC_CONNECTED, "volume=%s;svc_name=%s", -+ volinfo->volname, svc->name); - svc->online = _gf_true; - break; - -@@ -386,26 +410,14 @@ glusterd_snapdsvc_rpc_notify (glusterd_conn_t *conn, rpc_clnt_event_t event) - gf_msg (this->name, GF_LOG_INFO, 0, - GD_MSG_NODE_DISCONNECTED, "%s has disconnected " - "from glusterd.", svc->name); -+ gf_event (EVENT_SVC_DISCONNECTED, -+ "volume=%s;svc_name=%s", volinfo->volname, -+ svc->name); - svc->online = _gf_false; - } - break; - - case RPC_CLNT_DESTROY: -- snapd = cds_list_entry (svc, glusterd_snapdsvc_t, svc); -- if (!snapd) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_SNAPD_OBJ_GET_FAIL, "Failed to get the " -- "snapd object"); -- return -1; -- } -- -- volinfo = cds_list_entry (snapd, glusterd_volinfo_t, snapd); -- if (!volinfo) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_VOLINFO_GET_FAIL, "Failed to get the " -- "volinfo object"); -- return -1; -- } - glusterd_volinfo_unref (volinfo); - - default: -diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c -index 454c2a4..d6e57a4 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c -+++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c -@@ -316,6 +316,7 @@ glusterd_svc_common_rpc_notify (glusterd_conn_t *conn, - case RPC_CLNT_CONNECT: - gf_msg_debug (this->name, 0, "%s has connected with " - "glusterd.", svc->name); -+ gf_event (EVENT_SVC_CONNECTED, "svc_name=%s", svc->name); - svc->online = _gf_true; - break; - -@@ -324,6 +325,8 @@ glusterd_svc_common_rpc_notify (glusterd_conn_t *conn, - gf_msg (this->name, GF_LOG_INFO, 0, - GD_MSG_NODE_DISCONNECTED, "%s has disconnected " - "from glusterd.", svc->name); -+ gf_event (EVENT_SVC_DISCONNECTED, "svc_name=%s", -+ svc->name); - svc->online = _gf_false; - } - break; -diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c -index 66c8b63..6b18d17 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c -@@ -2986,6 +2986,10 @@ glusterd_compare_friend_volume (dict_t *peer_data, int32_t count, - *status = GLUSTERD_VOL_COMP_SCS; - - out: -+ if (ret) { -+ gf_event (EVENT_COMPARE_FRIEND_VOLUME_FAILED, "volume=%s", -+ volinfo->volname); -+ } - gf_msg_debug (this->name, 0, "Returning with ret: %d, status: %d", - ret, *status); - return ret; -@@ -3204,9 +3208,12 @@ glusterd_import_new_brick (dict_t *peer_data, int32_t vol_count, - - *brickinfo = new_brickinfo; - out: -- if (msg[0]) -+ if (msg[0]) { - gf_msg ("glusterd", GF_LOG_ERROR, 0, - GD_MSG_BRICK_IMPORT_FAIL, "%s", msg); -+ gf_event (EVENT_IMPORT_BRICK_FAILED, "peer=%s;brick=%s", -+ new_brickinfo->hostname, new_brickinfo->path); -+ } - gf_msg_debug ("glusterd", 0, "Returning with %d", ret); - return ret; - } -@@ -3812,9 +3819,12 @@ glusterd_import_volinfo (dict_t *peer_data, int count, - - *volinfo = new_volinfo; - out: -- if (msg[0]) -+ if (msg[0]) { - gf_msg ("glusterd", GF_LOG_ERROR, 0, - GD_MSG_VOLINFO_IMPORT_FAIL, "%s", msg); -+ gf_event (EVENT_IMPORT_VOLUME_FAILED, "volume=%s", -+ new_volinfo->volname); -+ } - gf_msg_debug ("glusterd", 0, "Returning with %d", ret); - return ret; - } -@@ -4127,11 +4137,17 @@ glusterd_import_friend_volume (dict_t *peer_data, size_t count) - } - - if (glusterd_is_volume_started (new_volinfo)) { -- (void) glusterd_start_bricks (new_volinfo); -+ if (glusterd_start_bricks (new_volinfo)) { -+ gf_event (EVENT_BRICKS_START_FAILED, "volume=%s", -+ new_volinfo->volname); -+ } - if (glusterd_is_snapd_enabled (new_volinfo)) { - svc = &(new_volinfo->snapd.svc); -- (void) svc->manager (svc, new_volinfo, -- PROC_START_NO_WAIT); -+ if (svc->manager (svc, new_volinfo, -+ PROC_START_NO_WAIT)){ -+ gf_event (EVENT_SVC_MANAGER_FAILED, -+ "svc_name=%s", svc->name); -+ } - } - } - -@@ -4157,6 +4173,8 @@ glusterd_import_friend_volume (dict_t *peer_data, size_t count) - " ret: %d for volume %s ganesha.enable %s", - ret, new_volinfo->volname, - value); -+ gf_event (EVENT_NFS_GANESHA_EXPORT_FAILED, "volume=%s", -+ new_volinfo->volname); - goto out; - } - } -@@ -4174,9 +4192,11 @@ glusterd_import_friend_volume (dict_t *peer_data, size_t count) - - ret = glusterd_import_quota_conf (peer_data, count, - new_volinfo, "volume"); -- if (ret) -+ if (ret) { -+ gf_event (EVENT_IMPORT_QUOTA_CONF_FAILED, "volume=%s", -+ new_volinfo->volname); - goto out; -- -+ } - glusterd_list_add_order (&new_volinfo->vol_list, &priv->volumes, - glusterd_compare_volume_name); - -@@ -4393,7 +4413,9 @@ glusterd_compare_friend_data (dict_t *peer_data, int32_t *status, - if (ret) - goto out; - -- glusterd_svcs_manager (NULL); -+ if (glusterd_svcs_manager (NULL)) { -+ gf_event (EVENT_SVC_MANAGER_FAILED, ""); -+ } - } - - out: -@@ -4861,6 +4883,10 @@ glusterd_brick_start (glusterd_volinfo_t *volinfo, - GD_MSG_RESOLVE_BRICK_FAIL, - FMTSTR_RESOLVE_BRICK, - brickinfo->hostname, brickinfo->path); -+ gf_event (EVENT_BRICKPATH_RESOLVE_FAILED, -+ "peer=%s;volume=%s;brick=%s", -+ brickinfo->hostname, volinfo->volname, -+ brickinfo->path); - goto out; - } - } -@@ -4875,6 +4901,9 @@ glusterd_brick_start (glusterd_volinfo_t *volinfo, - GD_MSG_BRICK_DISCONNECTED, - "Unable to start brick %s:%s", - brickinfo->hostname, brickinfo->path); -+ gf_event (EVENT_BRICK_START_FAILED, -+ "peer=%s;volume=%s;brick=%s", brickinfo->hostname, -+ volinfo->volname, brickinfo->path); - goto out; - } - -@@ -4915,7 +4944,9 @@ glusterd_restart_bricks (glusterd_conf_t *conf) - continue; - if (start_svcs == _gf_false) { - start_svcs = _gf_true; -- glusterd_svcs_manager (NULL); -+ if (glusterd_svcs_manager (NULL)) { -+ gf_event (EVENT_SVC_MANAGER_FAILED, ""); -+ } - } - gf_msg_debug (this->name, 0, "starting the volume %s", - volinfo->volname); -@@ -4965,7 +4996,9 @@ glusterd_restart_bricks (glusterd_conf_t *conf) - } - if (start_svcs == _gf_false) { - start_svcs = _gf_true; -- glusterd_svcs_manager (volinfo); -+ if (glusterd_svcs_manager (volinfo)) { -+ gf_event (EVENT_SVC_MANAGER_FAILED, ""); -+ } - } - start_svcs = _gf_true; - gf_msg_debug (this->name, 0, "starting the snap " -@@ -7370,6 +7403,8 @@ glusterd_volume_defrag_restart (glusterd_volinfo_t *volinfo, char *op_errstr, - "Failed to initialize defrag." - "Not starting rebalance process for " - "%s.", volinfo->volname); -+ gf_event (EVENT_REBALANCE_START_FAILED, -+ "volume=%s", volinfo->volname); - goto out; - } - ret = glusterd_rebalance_rpc_create (volinfo, _gf_true); -@@ -7378,8 +7413,11 @@ glusterd_volume_defrag_restart (glusterd_volinfo_t *volinfo, char *op_errstr, - case GF_DEFRAG_STATUS_NOT_STARTED: - ret = glusterd_handle_defrag_start (volinfo, op_errstr, len, - cmd, cbk, volinfo->rebal.op); -- if (ret) -+ if (ret) { - volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_FAILED; -+ gf_event (EVENT_REBALANCE_START_FAILED, -+ "volume=%s", volinfo->volname); -+ } - break; - default: - gf_msg (this->name, GF_LOG_ERROR, 0, --- -1.7.1 - diff --git a/SOURCES/0050-Revert-glusterd-storhaug-remove-ganesha.patch b/SOURCES/0050-Revert-glusterd-storhaug-remove-ganesha.patch new file mode 100644 index 0000000..8a53d04 --- /dev/null +++ b/SOURCES/0050-Revert-glusterd-storhaug-remove-ganesha.patch @@ -0,0 +1,2012 @@ +From c45cba4e8959cc3224c293423fdc1f33d3e657c8 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Mon, 16 Oct 2017 14:24:29 +0530 +Subject: [PATCH 50/74] Revert "glusterd: (storhaug) remove ganesha" + +This reverts commit 843e1b04b554ab887ec656ae7b468bb93ee4e2f7. + +Change-Id: I06b5450344c33f26da3d94b6f67051d41dfbba17 +Signed-off-by: Jiffin Tony Thottan +--- + cli/src/cli-cmd-global.c | 54 ++ + cli/src/cli-cmd-parser.c | 106 +++ + cli/src/cli-cmd.c | 3 +- + cli/src/cli-rpc-ops.c | 79 ++ + cli/src/cli.h | 3 + + xlators/mgmt/glusterd/src/Makefile.am | 4 +- + xlators/mgmt/glusterd/src/glusterd-errno.h | 2 +- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 898 +++++++++++++++++++++ + xlators/mgmt/glusterd/src/glusterd-handler.c | 77 ++ + xlators/mgmt/glusterd/src/glusterd-messages.h | 8 + + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 47 ++ + .../mgmt/glusterd/src/glusterd-snapshot-utils.c | 196 +++++ + .../mgmt/glusterd/src/glusterd-snapshot-utils.h | 7 + + xlators/mgmt/glusterd/src/glusterd-snapshot.c | 96 +++ + xlators/mgmt/glusterd/src/glusterd-store.h | 1 + + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 34 + + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 6 + + xlators/mgmt/glusterd/src/glusterd.h | 16 +- + 18 files changed, 1633 insertions(+), 4 deletions(-) + create mode 100644 xlators/mgmt/glusterd/src/glusterd-ganesha.c + +diff --git a/cli/src/cli-cmd-global.c b/cli/src/cli-cmd-global.c +index 9873192..881506b 100644 +--- a/cli/src/cli-cmd-global.c ++++ b/cli/src/cli-cmd-global.c +@@ -32,6 +32,8 @@ extern rpc_clnt_prog_t *cli_rpc_prog; + int + cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, + const char **words, int wordcount); ++int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word, ++ const char **words, int wordcount); + int + cli_cmd_get_state_cbk (struct cli_state *state, struct cli_cmd_word *word, + const char **words, int wordcount); +@@ -46,6 +48,10 @@ struct cli_cmd global_cmds[] = { + cli_cmd_get_state_cbk, + "Get local state representation of mentioned daemon", + }, ++ { "nfs-ganesha {enable| disable} ", ++ cli_cmd_ganesha_cbk, ++ "Enable/disable NFS-Ganesha support", ++ }, + {NULL, NULL, NULL} + }; + +@@ -86,6 +92,54 @@ out: + + } + ++int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word, ++ const char **words, int wordcount) ++ ++{ ++ int sent = 0; ++ int parse_error = 0; ++ int ret = -1; ++ rpc_clnt_procedure_t *proc = NULL; ++ call_frame_t *frame = NULL; ++ dict_t *options = NULL; ++ cli_local_t *local = NULL; ++ char *op_errstr = NULL; ++ ++ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GANESHA]; ++ ++ frame = create_frame (THIS, THIS->ctx->pool); ++ if (!frame) ++ goto out; ++ ++ ret = cli_cmd_ganesha_parse (state, words, wordcount, ++ &options, &op_errstr); ++ if (ret) { ++ if (op_errstr) { ++ cli_err ("%s", op_errstr); ++ GF_FREE (op_errstr); ++ } else ++ cli_usage_out (word->pattern); ++ parse_error = 1; ++ goto out; ++ } ++ ++ CLI_LOCAL_INIT (local, words, frame, options); ++ ++ if (proc->fn) { ++ ret = proc->fn (frame, THIS, options); ++ } ++ ++out: ++ if (ret) { ++ cli_cmd_sent_status_get (&sent); ++ if ((sent == 0) && (parse_error == 0)) ++ cli_out ("Setting global option failed"); ++ } ++ ++ CLI_STACK_DESTROY (frame); ++ return ret; ++} ++ + int + cli_cmd_get_state_cbk (struct cli_state *state, struct cli_cmd_word *word, + const char **words, int wordcount) +diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c +index 216e050..a4c601b 100644 +--- a/cli/src/cli-cmd-parser.c ++++ b/cli/src/cli-cmd-parser.c +@@ -840,6 +840,112 @@ out: + return ret; + } + ++/* Parsing global option for NFS-Ganesha config ++ * gluster nfs-ganesha enable/disable */ ++ ++int32_t ++cli_cmd_ganesha_parse (struct cli_state *state, ++ const char **words, int wordcount, ++ dict_t **options, char **op_errstr) ++{ ++ dict_t *dict = NULL; ++ int ret = -1; ++ char *key = NULL; ++ char *value = NULL; ++ char *w = NULL; ++ char *opwords[] = { "enable", "disable", NULL }; ++ const char *question = NULL; ++ gf_answer_t answer = GF_ANSWER_NO; ++ ++ ++ GF_ASSERT (words); ++ GF_ASSERT (options); ++ ++ dict = dict_new (); ++ ++ if (!dict) ++ goto out; ++ ++ if (wordcount != 2) ++ goto out; ++ ++ key = (char *) words[0]; ++ value = (char *) words[1]; ++ ++ if (!key || !value) { ++ cli_out ("Usage : nfs-ganesha "); ++ ret = -1; ++ goto out; ++ } ++ ++ ret = gf_strip_whitespace (value, strlen (value)); ++ if (ret == -1) ++ goto out; ++ ++ if (strcmp (key, "nfs-ganesha")) { ++ gf_asprintf (op_errstr, "Global option: error: ' %s '" ++ "is not a valid global option.", key); ++ ret = -1; ++ goto out; ++ } ++ ++ w = str_getunamb (value, opwords); ++ if (!w) { ++ cli_out ("Invalid global option \n" ++ "Usage : nfs-ganesha "); ++ ret = -1; ++ goto out; ++ } ++ ++ question = "Enabling NFS-Ganesha requires Gluster-NFS to be" ++ " disabled across the trusted pool. Do you " ++ "still want to continue?\n"; ++ ++ if (strcmp (value, "enable") == 0) { ++ answer = cli_cmd_get_confirmation (state, question); ++ if (GF_ANSWER_NO == answer) { ++ gf_log ("cli", GF_LOG_ERROR, "Global operation " ++ "cancelled, exiting"); ++ ret = -1; ++ goto out; ++ } ++ } ++ cli_out ("This will take a few minutes to complete. Please wait .."); ++ ++ ret = dict_set_str (dict, "key", key); ++ if (ret) { ++ gf_log (THIS->name, GF_LOG_ERROR, "dict set on key failed"); ++ goto out; ++ } ++ ++ ret = dict_set_str (dict, "value", value); ++ if (ret) { ++ gf_log (THIS->name, GF_LOG_ERROR, "dict set on value failed"); ++ goto out; ++ } ++ ++ ret = dict_set_str (dict, "globalname", "All"); ++ if (ret) { ++ gf_log (THIS->name, GF_LOG_ERROR, "dict set on global" ++ " key failed."); ++ goto out; ++ } ++ ++ ret = dict_set_int32 (dict, "hold_global_locks", _gf_true); ++ if (ret) { ++ gf_log (THIS->name, GF_LOG_ERROR, "dict set on global key " ++ "failed."); ++ goto out; ++ } ++ ++ *options = dict; ++out: ++ if (ret) ++ dict_unref (dict); ++ ++ return ret; ++} ++ + int32_t + cli_cmd_get_state_parse (struct cli_state *state, + const char **words, int wordcount, +diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c +index 236009b..8a75041 100644 +--- a/cli/src/cli-cmd.c ++++ b/cli/src/cli-cmd.c +@@ -369,7 +369,8 @@ cli_cmd_submit (struct rpc_clnt* rpc, void *req, call_frame_t *frame, + unsigned timeout = 0; + + if ((GLUSTER_CLI_PROFILE_VOLUME == procnum) || +- (GLUSTER_CLI_HEAL_VOLUME == procnum)) ++ (GLUSTER_CLI_HEAL_VOLUME == procnum) || ++ (GLUSTER_CLI_GANESHA == procnum)) + timeout = cli_ten_minutes_timeout; + else + timeout = cli_default_conn_timeout; +diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c +index eb1ca77..67e29a0 100644 +--- a/cli/src/cli-rpc-ops.c ++++ b/cli/src/cli-rpc-ops.c +@@ -2232,6 +2232,60 @@ out: + return ret; + } + ++int ++gf_cli_ganesha_cbk (struct rpc_req *req, struct iovec *iov, ++ int count, void *myframe) ++{ ++ gf_cli_rsp rsp = {0,}; ++ int ret = -1; ++ dict_t *dict = NULL; ++ ++ GF_ASSERT (myframe); ++ ++ if (-1 == req->rpc_status) { ++ goto out; ++ } ++ ++ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp); ++ if (ret < 0) { ++ gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR, ++ "Failed to decode xdr response"); ++ goto out; ++ } ++ ++ gf_log ("cli", GF_LOG_DEBUG, "Received resp to ganesha"); ++ ++ dict = dict_new (); ++ ++ if (!dict) { ++ ret = -1; ++ goto out; ++ } ++ ++ ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict); ++ if (ret) ++ goto out; ++ ++ if (rsp.op_ret) { ++ if (strcmp (rsp.op_errstr, "")) ++ cli_err ("nfs-ganesha: failed: %s", rsp.op_errstr); ++ else ++ cli_err ("nfs-ganesha: failed"); ++ } ++ ++ else { ++ cli_out("nfs-ganesha : success "); ++ } ++ ++ ret = rsp.op_ret; ++ ++out: ++ if (dict) ++ dict_unref (dict); ++ cli_cmd_broadcast_response (ret); ++ return ret; ++} ++ + char * + is_server_debug_xlator (void *myframe) + { +@@ -4840,6 +4894,30 @@ out: + } + + int32_t ++gf_cli_ganesha (call_frame_t *frame, xlator_t *this, void *data) ++{ ++ gf_cli_req req = { {0,} } ; ++ int ret = 0; ++ dict_t *dict = NULL; ++ ++ if (!frame || !this || !data) { ++ ret = -1; ++ goto out; ++ } ++ ++ dict = data; ++ ++ ret = cli_to_glusterd (&req, frame, gf_cli_ganesha_cbk, ++ (xdrproc_t) xdr_gf_cli_req, dict, ++ GLUSTER_CLI_GANESHA, this, cli_rpc_prog, ++ NULL); ++out: ++ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); ++ ++ return ret; ++} ++ ++int32_t + gf_cli_set_volume (call_frame_t *frame, xlator_t *this, + void *data) + { +@@ -12008,6 +12086,7 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = { + [GLUSTER_CLI_SYS_EXEC] = {"SYS_EXEC", gf_cli_sys_exec}, + [GLUSTER_CLI_SNAP] = {"SNAP", gf_cli_snapshot}, + [GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER VOLUME", gf_cli_barrier_volume}, ++ [GLUSTER_CLI_GANESHA] = {"GANESHA", gf_cli_ganesha}, + [GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", gf_cli_get_vol_opt}, + [GLUSTER_CLI_BITROT] = {"BITROT", gf_cli_bitrot}, + [GLUSTER_CLI_ATTACH_TIER] = {"ATTACH_TIER", gf_cli_attach_tier}, +diff --git a/cli/src/cli.h b/cli/src/cli.h +index 68dcb8c..c9bf93d 100644 +--- a/cli/src/cli.h ++++ b/cli/src/cli.h +@@ -255,6 +255,9 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **opt); + int32_t + cli_cmd_volume_set_parse (struct cli_state *state, const char **words, + int wordcount, dict_t **options, char **op_errstr); ++int32_t ++cli_cmd_ganesha_parse (struct cli_state *state, const char **words, ++ int wordcount, dict_t **options, char **op_errstr); + + int32_t + cli_cmd_get_state_parse (struct cli_state *state, const char **words, +diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am +index 4858dee..23ebf37 100644 +--- a/xlators/mgmt/glusterd/src/Makefile.am ++++ b/xlators/mgmt/glusterd/src/Makefile.am +@@ -5,7 +5,7 @@ glusterd_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) + glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \ + glusterd-op-sm.c glusterd-utils.c glusterd-rpc-ops.c \ + glusterd-store.c glusterd-handshake.c glusterd-pmap.c \ +- glusterd-volgen.c glusterd-rebalance.c \ ++ glusterd-volgen.c glusterd-rebalance.c glusterd-ganesha.c \ + glusterd-quota.c glusterd-bitrot.c glusterd-geo-rep.c \ + glusterd-replace-brick.c glusterd-log-ops.c glusterd-tier.c \ + glusterd-volume-ops.c glusterd-brick-ops.c glusterd-mountbroker.c \ +@@ -48,6 +48,8 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(CONTRIBDIR)/mount -I$(CONTRIBDIR)/userspace-rcu \ + -DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \ + -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\" \ ++ -DCONFDIR=\"$(localstatedir)/run/gluster/shared_storage/nfs-ganesha\" \ ++ -DGANESHA_PREFIX=\"$(libexecdir)/ganesha\" \ + -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(XML_CPPFLAGS) + + +diff --git a/xlators/mgmt/glusterd/src/glusterd-errno.h b/xlators/mgmt/glusterd/src/glusterd-errno.h +index bfb56b5..3301e44 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-errno.h ++++ b/xlators/mgmt/glusterd/src/glusterd-errno.h +@@ -27,7 +27,7 @@ enum glusterd_op_errno { + EG_ISSNAP = 30813, /* Volume is a snap volume */ + EG_GEOREPRUN = 30814, /* Geo-Replication is running */ + EG_NOTTHINP = 30815, /* Bricks are not thinly provisioned */ +- EG_NOGANESHA = 30816, /* obsolete ganesha is not enabled */ ++ EG_NOGANESHA = 30816, /* Global nfs-ganesha is not enabled */ + }; + + #endif +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +new file mode 100644 +index 0000000..4346bad +--- /dev/null ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -0,0 +1,898 @@ ++/* ++ Copyright (c) 2015 Red Hat, Inc. ++ This file is part of GlusterFS. ++ ++ This file is licensed to you under your choice of the GNU Lesser ++ General Public License, version 3 or any later version (LGPLv3 or ++ later), or the GNU General Public License, version 2 (GPLv2), in all ++ cases as published by the Free Software Foundation. ++*/ ++ ++ ++ ++#include "common-utils.h" ++#include "glusterd.h" ++#include "glusterd-op-sm.h" ++#include "glusterd-store.h" ++#include "glusterd-utils.h" ++#include "glusterd-nfs-svc.h" ++#include "glusterd-volgen.h" ++#include "glusterd-messages.h" ++#include "syscall.h" ++ ++#include ++ ++int start_ganesha (char **op_errstr); ++ ++ ++typedef struct service_command { ++ char *binary; ++ char *service; ++ int (*action) (struct service_command *, char *); ++} service_command; ++ ++/* parsing_ganesha_ha_conf will allocate the returned string ++ * to be freed (GF_FREE) by the caller ++ * return NULL if error or not found */ ++static char* ++parsing_ganesha_ha_conf(const char *key) { ++#define MAX_LINE 1024 ++ char scratch[MAX_LINE * 2] = {0,}; ++ char *value = NULL, *pointer = NULL, *end_pointer = NULL; ++ FILE *fp; ++ ++ fp = fopen (GANESHA_HA_CONF, "r"); ++ if (fp == NULL) { ++ gf_msg (THIS->name, GF_LOG_ERROR, errno, ++ GD_MSG_FILE_OP_FAILED, "couldn't open the file %s", ++ GANESHA_HA_CONF); ++ goto end_ret; ++ } ++ while ((pointer = fgets (scratch, MAX_LINE, fp)) != NULL) { ++ /* Read config file until we get matching "^[[:space:]]*key" */ ++ if (*pointer == '#') { ++ continue; ++ } ++ while (isblank(*pointer)) { ++ pointer++; ++ } ++ if (strncmp (pointer, key, strlen (key))) { ++ continue; ++ } ++ pointer += strlen (key); ++ /* key found : if we fail to parse, we'll return an error ++ * rather than trying next one ++ * - supposition : conf file is bash compatible : no space ++ * around the '=' */ ++ if (*pointer != '=') { ++ gf_msg (THIS->name, GF_LOG_ERROR, errno, ++ GD_MSG_GET_CONFIG_INFO_FAILED, ++ "Parsing %s failed at key %s", ++ GANESHA_HA_CONF, key); ++ goto end_close; ++ } ++ pointer++; /* jump the '=' */ ++ ++ if (*pointer == '"' || *pointer == '\'') { ++ /* dont get the quote */ ++ pointer++; ++ } ++ end_pointer = pointer; ++ /* stop at the next closing quote or blank/newline */ ++ do { ++ end_pointer++; ++ } while (!(*end_pointer == '\'' || *end_pointer == '"' || ++ isspace(*end_pointer) || *end_pointer == '\0')); ++ *end_pointer = '\0'; ++ ++ /* got it. copy it and return */ ++ value = gf_strdup (pointer); ++ break; ++ } ++ ++end_close: ++ fclose(fp); ++end_ret: ++ return value; ++} ++ ++static int ++sc_systemctl_action (struct service_command *sc, char *command) ++{ ++ runner_t runner = {0,}; ++ ++ runinit (&runner); ++ runner_add_args (&runner, sc->binary, command, sc->service, NULL); ++ return runner_run (&runner); ++} ++ ++static int ++sc_service_action (struct service_command *sc, char *command) ++{ ++ runner_t runner = {0,}; ++ ++ runinit (&runner); ++ runner_add_args (&runner, sc->binary, sc->service, command, NULL); ++ return runner_run (&runner); ++} ++ ++static int ++manage_service (char *action) ++{ ++ struct stat stbuf = {0,}; ++ int i = 0; ++ int ret = 0; ++ struct service_command sc_list[] = { ++ { .binary = "/usr/bin/systemctl", ++ .service = "nfs-ganesha", ++ .action = sc_systemctl_action ++ }, ++ { .binary = "/sbin/invoke-rc.d", ++ .service = "nfs-ganesha", ++ .action = sc_service_action ++ }, ++ { .binary = "/sbin/service", ++ .service = "nfs-ganesha", ++ .action = sc_service_action ++ }, ++ { .binary = NULL ++ } ++ }; ++ ++ while (sc_list[i].binary != NULL) { ++ ret = sys_stat (sc_list[i].binary, &stbuf); ++ if (ret == 0) { ++ gf_msg_debug (THIS->name, 0, ++ "%s found.", sc_list[i].binary); ++ if (strcmp (sc_list[i].binary, "/usr/bin/systemctl") == 0) ++ ret = sc_systemctl_action (&sc_list[i], action); ++ else ++ ret = sc_service_action (&sc_list[i], action); ++ ++ return ret; ++ } ++ i++; ++ } ++ gf_msg (THIS->name, GF_LOG_ERROR, 0, ++ GD_MSG_UNRECOGNIZED_SVC_MNGR, ++ "Could not %s NFS-Ganesha.Service manager for distro" ++ " not recognized.", action); ++ return ret; ++} ++ ++/* ++ * Check if the cluster is a ganesha cluster or not * ++ */ ++gf_boolean_t ++glusterd_is_ganesha_cluster () { ++ int ret = -1; ++ glusterd_conf_t *priv = NULL; ++ xlator_t *this = NULL; ++ gf_boolean_t ret_bool = _gf_false; ++ ++ this = THIS; ++ GF_VALIDATE_OR_GOTO ("ganesha", this, out); ++ priv = this->private; ++ GF_VALIDATE_OR_GOTO (this->name, priv, out); ++ ++ ret = dict_get_str_boolean (priv->opts, ++ GLUSTERD_STORE_KEY_GANESHA_GLOBAL, ++ _gf_false); ++ if (ret == _gf_true) { ++ ret_bool = _gf_true; ++ gf_msg_debug (this->name, 0, ++ "nfs-ganesha is enabled for the cluster"); ++ } else ++ gf_msg_debug (this->name, 0, ++ "nfs-ganesha is disabled for the cluster"); ++ ++out: ++ return ret_bool; ++ ++} ++ ++/* Check if ganesha.enable is set to 'on', that checks if ++ * a particular volume is exported via NFS-Ganesha */ ++gf_boolean_t ++glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo) { ++ ++ char *value = NULL; ++ gf_boolean_t is_exported = _gf_false; ++ int ret = 0; ++ ++ ret = glusterd_volinfo_get (volinfo, "ganesha.enable", &value); ++ if ((ret == 0) && value) { ++ if (strcmp (value, "on") == 0) { ++ gf_msg_debug (THIS->name, 0, "ganesha.enable set" ++ " to %s", value); ++ is_exported = _gf_true; ++ } ++ } ++ return is_exported; ++} ++ ++/* * ++ * The below function is called as part of commit phase for volume set option ++ * "ganesha.enable". If the value is "on", it creates export configuration file ++ * and then export the volume via dbus command. Incase of "off", the volume ++ * will be already unexported during stage phase, so it will remove the conf ++ * file from shared storage ++ */ ++int ++glusterd_check_ganesha_cmd (char *key, char *value, char **errstr, dict_t *dict) ++{ ++ int ret = 0; ++ char *volname = NULL; ++ ++ GF_ASSERT (key); ++ GF_ASSERT (value); ++ GF_ASSERT (dict); ++ ++ if ((strcmp (key, "ganesha.enable") == 0)) { ++ if ((strcmp (value, "on")) && (strcmp (value, "off"))) { ++ gf_asprintf (errstr, "Invalid value" ++ " for volume set command. Use on/off only."); ++ ret = -1; ++ goto out; ++ } ++ if (strcmp (value, "on") == 0) { ++ ret = glusterd_handle_ganesha_op (dict, errstr, key, ++ value); ++ ++ } else if (is_origin_glusterd (dict)) { ++ ret = dict_get_str (dict, "volname", &volname); ++ if (ret) { ++ gf_msg ("glusterd-ganesha", GF_LOG_ERROR, errno, ++ GD_MSG_DICT_GET_FAILED, ++ "Unable to get volume name"); ++ goto out; ++ } ++ ret = manage_export_config (volname, "off", errstr); ++ } ++ } ++out: ++ if (ret) { ++ gf_msg ("glusterd-ganesha", GF_LOG_ERROR, 0, ++ GD_MSG_NFS_GNS_OP_HANDLE_FAIL, ++ "Handling NFS-Ganesha" ++ " op failed."); ++ } ++ return ret; ++} ++ ++int ++glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr) ++{ ++ int ret = -1; ++ int value = -1; ++ gf_boolean_t option = _gf_false; ++ char *str = NULL; ++ glusterd_conf_t *priv = NULL; ++ xlator_t *this = NULL; ++ ++ GF_ASSERT (dict); ++ this = THIS; ++ GF_ASSERT (this); ++ priv = this->private; ++ GF_ASSERT (priv); ++ ++ value = dict_get_str_boolean (dict, "value", _gf_false); ++ if (value == -1) { ++ gf_msg (this->name, GF_LOG_ERROR, errno, ++ GD_MSG_DICT_GET_FAILED, ++ "value not present."); ++ goto out; ++ } ++ /* This dict_get will fail if the user had never set the key before */ ++ /*Ignoring the ret value and proceeding */ ++ ret = dict_get_str (priv->opts, GLUSTERD_STORE_KEY_GANESHA_GLOBAL, &str); ++ if (ret == -1) { ++ gf_msg (this->name, GF_LOG_WARNING, errno, ++ GD_MSG_DICT_GET_FAILED, "Global dict not present."); ++ ret = 0; ++ goto out; ++ } ++ /* Validity of the value is already checked */ ++ ret = gf_string2boolean (str, &option); ++ /* Check if the feature is already enabled, fail in that case */ ++ if (value == option) { ++ gf_asprintf (op_errstr, "nfs-ganesha is already %sd.", str); ++ ret = -1; ++ goto out; ++ } ++ ++ if (value) { ++ ret = start_ganesha (op_errstr); ++ if (ret) { ++ gf_msg (THIS->name, GF_LOG_ERROR, 0, ++ GD_MSG_NFS_GNS_START_FAIL, ++ "Could not start NFS-Ganesha"); ++ ++ } ++ } else { ++ ret = stop_ganesha (op_errstr); ++ if (ret) ++ gf_msg_debug (THIS->name, 0, "Could not stop " ++ "NFS-Ganesha."); ++ } ++ ++out: ++ ++ if (ret) { ++ if (!(*op_errstr)) { ++ *op_errstr = gf_strdup ("Error, Validation Failed"); ++ gf_msg_debug (this->name, 0, ++ "Error, Cannot Validate option :%s", ++ GLUSTERD_STORE_KEY_GANESHA_GLOBAL); ++ } else { ++ gf_msg_debug (this->name, 0, ++ "Error, Cannot Validate option"); ++ } ++ } ++ return ret; ++} ++ ++int ++glusterd_op_set_ganesha (dict_t *dict, char **errstr) ++{ ++ int ret = 0; ++ xlator_t *this = NULL; ++ glusterd_conf_t *priv = NULL; ++ char *key = NULL; ++ char *value = NULL; ++ char *next_version = NULL; ++ ++ this = THIS; ++ GF_ASSERT (this); ++ GF_ASSERT (dict); ++ ++ priv = this->private; ++ GF_ASSERT (priv); ++ ++ ++ ret = dict_get_str (dict, "key", &key); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, errno, ++ GD_MSG_DICT_GET_FAILED, ++ "Couldn't get key in global option set"); ++ goto out; ++ } ++ ++ ret = dict_get_str (dict, "value", &value); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, errno, ++ GD_MSG_DICT_GET_FAILED, ++ "Couldn't get value in global option set"); ++ goto out; ++ } ++ ++ ret = glusterd_handle_ganesha_op (dict, errstr, key, value); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_NFS_GNS_SETUP_FAIL, ++ "Initial NFS-Ganesha set up failed"); ++ ret = -1; ++ goto out; ++ } ++ ret = dict_set_dynstr_with_alloc (priv->opts, ++ GLUSTERD_STORE_KEY_GANESHA_GLOBAL, ++ value); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_WARNING, errno, ++ GD_MSG_DICT_SET_FAILED, "Failed to set" ++ " nfs-ganesha in dict."); ++ goto out; ++ } ++ ret = glusterd_get_next_global_opt_version_str (priv->opts, ++ &next_version); ++ if (ret) { ++ gf_msg_debug (THIS->name, 0, "Could not fetch " ++ " global op version"); ++ goto out; ++ } ++ ret = dict_set_str (priv->opts, GLUSTERD_GLOBAL_OPT_VERSION, ++ next_version); ++ if (ret) ++ goto out; ++ ++ ret = glusterd_store_options (this, priv->opts); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_STORE_FAIL, "Failed to store options"); ++ goto out; ++ } ++ ++out: ++ gf_msg_debug (this->name, 0, "returning %d", ret); ++ return ret; ++} ++ ++/* Following function parse GANESHA_HA_CONF ++ * The sample file looks like below, ++ * HA_NAME="ganesha-ha-360" ++ * HA_VOL_NAME="ha-state" ++ * HA_CLUSTER_NODES="server1,server2" ++ * VIP_rhs_1="10.x.x.x" ++ * VIP_rhs_2="10.x.x.x." */ ++ ++/* Check if the localhost is listed as one of nfs-ganesha nodes */ ++gf_boolean_t ++check_host_list (void) ++{ ++ ++ glusterd_conf_t *priv = NULL; ++ char *hostname, *hostlist; ++ gf_boolean_t ret = _gf_false; ++ xlator_t *this = NULL; ++ ++ this = THIS; ++ priv = THIS->private; ++ GF_ASSERT (priv); ++ ++ hostlist = parsing_ganesha_ha_conf ("HA_CLUSTER_NODES"); ++ if (hostlist == NULL) { ++ gf_msg (this->name, GF_LOG_INFO, errno, ++ GD_MSG_GET_CONFIG_INFO_FAILED, ++ "couldn't get HA_CLUSTER_NODES from file %s", ++ GANESHA_HA_CONF); ++ return _gf_false; ++ } ++ ++ /* Hostlist is a comma separated list now */ ++ hostname = strtok (hostlist, ","); ++ while (hostname != NULL) { ++ ret = gf_is_local_addr (hostname); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_INFO, 0, ++ GD_MSG_NFS_GNS_HOST_FOUND, ++ "ganesha host found " ++ "Hostname is %s", hostname); ++ break; ++ } ++ hostname = strtok (NULL, ","); ++ } ++ ++ GF_FREE (hostlist); ++ return ret; ++ ++} ++ ++int ++manage_export_config (char *volname, char *value, char **op_errstr) ++{ ++ runner_t runner = {0,}; ++ int ret = -1; ++ ++ GF_ASSERT(volname); ++ runinit (&runner); ++ runner_add_args (&runner, "sh", ++ GANESHA_PREFIX"/create-export-ganesha.sh", ++ CONFDIR, value, volname, NULL); ++ ret = runner_run(&runner); ++ ++ if (ret) ++ gf_asprintf (op_errstr, "Failed to create" ++ " NFS-Ganesha export config file."); ++ ++ return ret; ++} ++ ++/* Exports and unexports a particular volume via NFS-Ganesha */ ++int ++ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) ++{ ++ runner_t runner = {0,}; ++ int ret = -1; ++ glusterd_volinfo_t *volinfo = NULL; ++ dict_t *vol_opts = NULL; ++ char *volname = NULL; ++ xlator_t *this = NULL; ++ glusterd_conf_t *priv = NULL; ++ gf_boolean_t option = _gf_false; ++ ++ runinit (&runner); ++ this = THIS; ++ GF_ASSERT (this); ++ priv = this->private; ++ ++ GF_ASSERT (value); ++ GF_ASSERT (dict); ++ GF_ASSERT (priv); ++ ++ ret = dict_get_str (dict, "volname", &volname); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, errno, ++ GD_MSG_DICT_GET_FAILED, ++ "Unable to get volume name"); ++ goto out; ++ } ++ ret = gf_string2boolean (value, &option); ++ if (ret == -1) { ++ gf_msg (this->name, GF_LOG_ERROR, EINVAL, ++ GD_MSG_INVALID_ENTRY, "invalid value."); ++ goto out; ++ } ++ ++ ret = glusterd_volinfo_find (volname, &volinfo); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, EINVAL, ++ GD_MSG_VOL_NOT_FOUND, ++ FMTSTR_CHECK_VOL_EXISTS, volname); ++ goto out; ++ } ++ ++ ret = glusterd_check_ganesha_export (volinfo); ++ if (ret && option) { ++ gf_asprintf (op_errstr, "ganesha.enable " ++ "is already 'on'."); ++ ret = -1; ++ goto out; ++ ++ } else if (!option && !ret) { ++ gf_asprintf (op_errstr, "ganesha.enable " ++ "is already 'off'."); ++ ret = -1; ++ goto out; ++ } ++ ++ /* Check if global option is enabled, proceed only then */ ++ ret = dict_get_str_boolean (priv->opts, ++ GLUSTERD_STORE_KEY_GANESHA_GLOBAL, _gf_false); ++ if (ret == -1) { ++ gf_msg_debug (this->name, 0, "Failed to get " ++ "global option dict."); ++ gf_asprintf (op_errstr, "The option " ++ "nfs-ganesha should be " ++ "enabled before setting ganesha.enable."); ++ goto out; ++ } ++ if (!ret) { ++ gf_asprintf (op_errstr, "The option " ++ "nfs-ganesha should be " ++ "enabled before setting ganesha.enable."); ++ ret = -1; ++ goto out; ++ } ++ ++ /* * ++ * Create the export file from the node where ganesha.enable "on" ++ * is executed ++ * */ ++ if (option) { ++ ret = manage_export_config (volname, "on", op_errstr); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_EXPORT_FILE_CREATE_FAIL, ++ "Failed to create" ++ "export file for NFS-Ganesha\n"); ++ goto out; ++ } ++ } ++ ++ if (check_host_list()) { ++ runner_add_args (&runner, "sh", GANESHA_PREFIX"/dbus-send.sh", ++ CONFDIR, value, volname, NULL); ++ ret = runner_run (&runner); ++ if (ret) { ++ gf_asprintf(op_errstr, "Dynamic export" ++ " addition/deletion failed." ++ " Please see log file for details"); ++ goto out; ++ } ++ } ++ ++ vol_opts = volinfo->dict; ++ ret = dict_set_dynstr_with_alloc (vol_opts, ++ "features.cache-invalidation", value); ++ if (ret) ++ gf_asprintf (op_errstr, "Cache-invalidation could not" ++ " be set to %s.", value); ++ ret = glusterd_store_volinfo (volinfo, ++ GLUSTERD_VOLINFO_VER_AC_INCREMENT); ++ if (ret) ++ gf_asprintf (op_errstr, "failed to store volinfo for %s" ++ , volinfo->volname); ++ ++out: ++ return ret; ++} ++ ++int ++tear_down_cluster(gf_boolean_t run_teardown) ++{ ++ int ret = 0; ++ runner_t runner = {0,}; ++ struct stat st = {0,}; ++ DIR *dir = NULL; ++ struct dirent *entry = NULL; ++ struct dirent scratch[2] = {{0,},}; ++ char path[PATH_MAX] = {0,}; ++ ++ if (run_teardown) { ++ runinit (&runner); ++ runner_add_args (&runner, "sh", ++ GANESHA_PREFIX"/ganesha-ha.sh", "teardown", ++ CONFDIR, NULL); ++ ret = runner_run(&runner); ++ /* * ++ * Remove all the entries in CONFDIR expect ganesha.conf and ++ * ganesha-ha.conf ++ */ ++ dir = sys_opendir (CONFDIR); ++ if (!dir) { ++ gf_msg_debug (THIS->name, 0, "Failed to open directory %s. " ++ "Reason : %s", CONFDIR, strerror (errno)); ++ ret = 0; ++ goto out; ++ } ++ ++ GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); ++ while (entry) { ++ snprintf (path, PATH_MAX, "%s/%s", CONFDIR, entry->d_name); ++ ret = sys_lstat (path, &st); ++ if (ret == -1) { ++ gf_msg_debug (THIS->name, 0, "Failed to stat entry %s :" ++ " %s", path, strerror (errno)); ++ goto out; ++ } ++ ++ if (strcmp(entry->d_name, "ganesha.conf") == 0 || ++ strcmp(entry->d_name, "ganesha-ha.conf") == 0) ++ gf_msg_debug (THIS->name, 0, " %s is not required" ++ " to remove", path); ++ else if (S_ISDIR (st.st_mode)) ++ ret = recursive_rmdir (path); ++ else ++ ret = sys_unlink (path); ++ ++ if (ret) { ++ gf_msg_debug (THIS->name, 0, " Failed to remove %s. " ++ "Reason : %s", path, strerror (errno)); ++ } ++ ++ gf_msg_debug (THIS->name, 0, "%s %s", ret ? ++ "Failed to remove" : "Removed", entry->d_name); ++ GF_FOR_EACH_ENTRY_IN_DIR (entry, dir, scratch); ++ } ++ ++ ret = sys_closedir (dir); ++ if (ret) { ++ gf_msg_debug (THIS->name, 0, "Failed to close dir %s. Reason :" ++ " %s", CONFDIR, strerror (errno)); ++ } ++ } ++ ++out: ++ return ret; ++} ++ ++ ++int ++setup_cluster(gf_boolean_t run_setup) ++{ ++ int ret = 0; ++ runner_t runner = {0,}; ++ ++ if (run_setup) { ++ runinit (&runner); ++ runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", ++ "setup", CONFDIR, NULL); ++ ret = runner_run (&runner); ++ } ++ return ret; ++} ++ ++ ++static int ++teardown (gf_boolean_t run_teardown, char **op_errstr) ++{ ++ runner_t runner = {0,}; ++ int ret = 1; ++ glusterd_volinfo_t *volinfo = NULL; ++ glusterd_conf_t *priv = NULL; ++ dict_t *vol_opts = NULL; ++ ++ priv = THIS->private; ++ ++ ret = tear_down_cluster (run_teardown); ++ if (ret == -1) { ++ gf_asprintf (op_errstr, "Cleanup of NFS-Ganesha" ++ " HA config failed."); ++ goto out; ++ } ++ ++ runinit (&runner); ++ runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", ++ "cleanup", CONFDIR, NULL); ++ ret = runner_run (&runner); ++ if (ret) ++ gf_msg_debug (THIS->name, 0, "Could not clean up" ++ " NFS-Ganesha related config"); ++ ++ cds_list_for_each_entry (volinfo, &priv->volumes, vol_list) { ++ vol_opts = volinfo->dict; ++ /* All the volumes exported via NFS-Ganesha will be ++ unexported, hence setting the appropriate keys */ ++ ret = dict_set_str (vol_opts, "features.cache-invalidation", ++ "off"); ++ if (ret) ++ gf_msg (THIS->name, GF_LOG_WARNING, errno, ++ GD_MSG_DICT_SET_FAILED, ++ "Could not set features.cache-invalidation " ++ "to off for %s", volinfo->volname); ++ ++ ret = dict_set_str (vol_opts, "ganesha.enable", "off"); ++ if (ret) ++ gf_msg (THIS->name, GF_LOG_WARNING, errno, ++ GD_MSG_DICT_SET_FAILED, ++ "Could not set ganesha.enable to off for %s", ++ volinfo->volname); ++ ++ ret = glusterd_store_volinfo (volinfo, ++ GLUSTERD_VOLINFO_VER_AC_INCREMENT); ++ if (ret) ++ gf_msg (THIS->name, GF_LOG_WARNING, 0, ++ GD_MSG_VOLINFO_SET_FAIL, ++ "failed to store volinfo for %s", ++ volinfo->volname); ++ } ++out: ++ return ret; ++} ++ ++int ++stop_ganesha (char **op_errstr) { ++ ++ int ret = 0; ++ runner_t runner = {0,}; ++ ++ runinit (&runner); ++ runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", ++ "--setup-ganesha-conf-files", CONFDIR, "no", NULL); ++ ret = runner_run (&runner); ++ if (ret) { ++ gf_asprintf (op_errstr, "removal of symlink ganesha.conf " ++ "in /etc/ganesha failed"); ++ } ++ ++ if (check_host_list ()) { ++ ret = manage_service ("stop"); ++ if (ret) ++ gf_asprintf (op_errstr, "NFS-Ganesha service could not" ++ "be stopped."); ++ } ++ return ret; ++ ++} ++ ++int ++start_ganesha (char **op_errstr) ++{ ++ int ret = -1; ++ dict_t *vol_opts = NULL; ++ glusterd_volinfo_t *volinfo = NULL; ++ glusterd_conf_t *priv = NULL; ++ runner_t runner = {0,}; ++ ++ priv = THIS->private; ++ GF_ASSERT (priv); ++ ++ cds_list_for_each_entry (volinfo, &priv->volumes, vol_list) { ++ vol_opts = volinfo->dict; ++ /* Gluster-nfs has to be disabled across the trusted pool */ ++ /* before attempting to start nfs-ganesha */ ++ ret = dict_set_str (vol_opts, NFS_DISABLE_MAP_KEY, "on"); ++ if (ret) ++ goto out; ++ ++ ret = glusterd_store_volinfo (volinfo, ++ GLUSTERD_VOLINFO_VER_AC_INCREMENT); ++ if (ret) { ++ *op_errstr = gf_strdup ("Failed to store the " ++ "Volume information"); ++ goto out; ++ } ++ } ++ ++ /* If the nfs svc is not initialized it means that the service is not ++ * running, hence we can skip the process of stopping gluster-nfs ++ * service ++ */ ++ if (priv->nfs_svc.inited) { ++ ret = priv->nfs_svc.stop (&(priv->nfs_svc), SIGKILL); ++ if (ret) { ++ ret = -1; ++ gf_asprintf (op_errstr, "Gluster-NFS service could" ++ "not be stopped, exiting."); ++ goto out; ++ } ++ } ++ ++ if (check_host_list()) { ++ runinit (&runner); ++ runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", ++ "--setup-ganesha-conf-files", CONFDIR, "yes", ++ NULL); ++ ret = runner_run (&runner); ++ if (ret) { ++ gf_asprintf (op_errstr, "creation of symlink ganesha.conf " ++ "in /etc/ganesha failed"); ++ goto out; ++ } ++ ret = manage_service ("start"); ++ if (ret) ++ gf_asprintf (op_errstr, "NFS-Ganesha failed to start." ++ "Please see log file for details"); ++ } ++ ++out: ++ return ret; ++} ++ ++static int ++pre_setup (gf_boolean_t run_setup, char **op_errstr) ++{ ++ int ret = 0; ++ ++ ret = check_host_list(); ++ ++ if (ret) { ++ ret = setup_cluster(run_setup); ++ if (ret == -1) ++ gf_asprintf (op_errstr, "Failed to set up HA " ++ "config for NFS-Ganesha. " ++ "Please check the log file for details"); ++ } ++ ++ return ret; ++} ++ ++int ++glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, ++ char *key, char *value) ++{ ++ ++ int32_t ret = -1; ++ gf_boolean_t option = _gf_false; ++ ++ GF_ASSERT (dict); ++ GF_ASSERT (op_errstr); ++ GF_ASSERT (key); ++ GF_ASSERT (value); ++ ++ ++ if (strcmp (key, "ganesha.enable") == 0) { ++ ret = ganesha_manage_export (dict, value, op_errstr); ++ if (ret < 0) ++ goto out; ++ } ++ ++ /* It is possible that the key might not be set */ ++ ret = gf_string2boolean (value, &option); ++ if (ret == -1) { ++ gf_asprintf (op_errstr, "Invalid value in key-value pair."); ++ goto out; ++ } ++ ++ if (strcmp (key, GLUSTERD_STORE_KEY_GANESHA_GLOBAL) == 0) { ++ /* * ++ * The set up/teardown of pcs cluster should be performed only ++ * once. This will done on the node in which the cli command ++ * 'gluster nfs-ganesha ' got executed. So that ++ * node should part of ganesha HA cluster ++ */ ++ if (option) { ++ ret = pre_setup (is_origin_glusterd (dict), op_errstr); ++ if (ret < 0) ++ goto out; ++ } else { ++ ret = teardown (is_origin_glusterd (dict), op_errstr); ++ if (ret < 0) ++ goto out; ++ } ++ } ++ ++out: ++ return ret; ++} ++ +diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c +index c3b9252..a3e1fdc 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handler.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handler.c +@@ -1884,6 +1884,82 @@ glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx, + return ret; + } + ++int ++__glusterd_handle_ganesha_cmd (rpcsvc_request_t *req) ++{ ++ int32_t ret = -1; ++ gf_cli_req cli_req = { {0,} } ; ++ dict_t *dict = NULL; ++ glusterd_op_t cli_op = GD_OP_GANESHA; ++ char *op_errstr = NULL; ++ char err_str[2048] = {0,}; ++ xlator_t *this = NULL; ++ ++ this = THIS; ++ GF_ASSERT (this); ++ ++ GF_ASSERT (req); ++ ++ ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); ++ if (ret < 0) { ++ snprintf (err_str, sizeof (err_str), "Failed to decode " ++ "request received from cli"); ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_REQ_DECODE_FAIL, "%s", err_str); ++ req->rpc_err = GARBAGE_ARGS; ++ goto out; ++ } ++ ++ if (cli_req.dict.dict_len) { ++ /* Unserialize the dictionary */ ++ dict = dict_new (); ++ if (!dict) { ++ ret = -1; ++ goto out; ++ } ++ ++ ret = dict_unserialize (cli_req.dict.dict_val, ++ cli_req.dict.dict_len, ++ &dict); ++ if (ret < 0) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_UNSERIALIZE_FAIL, ++ "failed to " ++ "unserialize req-buffer to dictionary"); ++ snprintf (err_str, sizeof (err_str), "Unable to decode " ++ "the command"); ++ goto out; ++ } else { ++ dict->extra_stdfree = cli_req.dict.dict_val; ++ } ++ } ++ ++ gf_msg_trace (this->name, 0, "Received global option request"); ++ ++ ret = glusterd_op_begin_synctask (req, GD_OP_GANESHA, dict); ++out: ++ if (ret) { ++ if (err_str[0] == '\0') ++ snprintf (err_str, sizeof (err_str), ++ "Operation failed"); ++ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, ++ dict, err_str); ++ } ++ if (op_errstr) ++ GF_FREE (op_errstr); ++ if (dict) ++ dict_unref(dict); ++ ++ return ret; ++} ++ ++ ++int ++glusterd_handle_ganesha_cmd (rpcsvc_request_t *req) ++{ ++ return glusterd_big_locked_handler (req, __glusterd_handle_ganesha_cmd); ++} ++ + static int + __glusterd_handle_reset_volume (rpcsvc_request_t *req) + { +@@ -6470,6 +6546,7 @@ rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = { + [GLUSTER_CLI_SYS_EXEC] = {"SYS_EXEC", GLUSTER_CLI_SYS_EXEC, glusterd_handle_sys_exec, NULL, 0, DRC_NA}, + [GLUSTER_CLI_SNAP] = {"SNAP", GLUSTER_CLI_SNAP, glusterd_handle_snapshot, NULL, 0, DRC_NA}, + [GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER_VOLUME", GLUSTER_CLI_BARRIER_VOLUME, glusterd_handle_barrier, NULL, 0, DRC_NA}, ++ [GLUSTER_CLI_GANESHA] = { "GANESHA" , GLUSTER_CLI_GANESHA, glusterd_handle_ganesha_cmd, NULL, 0, DRC_NA}, + [GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", GLUSTER_CLI_GET_VOL_OPT, glusterd_handle_get_vol_opt, NULL, 0, DRC_NA}, + [GLUSTER_CLI_BITROT] = {"BITROT", GLUSTER_CLI_BITROT, glusterd_handle_bitrot, NULL, 0, DRC_NA}, + [GLUSTER_CLI_GET_STATE] = {"GET_STATE", GLUSTER_CLI_GET_STATE, glusterd_handle_get_state, NULL, 0, DRC_NA}, +diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h +index de9ae92..cc7f371 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-messages.h ++++ b/xlators/mgmt/glusterd/src/glusterd-messages.h +@@ -4767,6 +4767,14 @@ + * @recommendedaction + * + */ ++#define GD_MSG_NFS_GANESHA_DISABLED (GLUSTERD_COMP_BASE + 589) ++ ++/*! ++ * @messageid ++ * @diagnosis ++ * @recommendedaction ++ * ++ */ + #define GD_MSG_TIERD_STOP_FAIL (GLUSTERD_COMP_BASE + 590) + + /*! +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 5b8f833..06e9e25 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -1126,6 +1126,12 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) + if (ret) + goto out; + ++ if ((strcmp (key, "ganesha.enable") == 0) && ++ (strcmp (value, "off") == 0)) { ++ ret = ganesha_manage_export (dict, "off", op_errstr); ++ if (ret) ++ goto out; ++ } + ret = glusterd_check_quota_cmd (key, value, errstr, sizeof (errstr)); + if (ret) + goto out; +@@ -1642,6 +1648,21 @@ glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr) + goto out; + } + ++ /* * ++ * If key ganesha.enable is set, then volume should be unexported from ++ * ganesha server. Also it is a volume-level option, perform only when ++ * volume name not equal to "all"(in other words if volinfo != NULL) ++ */ ++ if (volinfo && (!strcmp (key, "all") || !strcmp(key, "ganesha.enable"))) { ++ if (glusterd_check_ganesha_export (volinfo)) { ++ ret = ganesha_manage_export (dict, "off", op_errstr); ++ if (ret) ++ gf_msg (this->name, GF_LOG_WARNING, 0, ++ GD_MSG_NFS_GNS_RESET_FAIL, ++ "Could not reset ganesha.enable key"); ++ } ++ } ++ + if (strcmp(key, "all")) { + exists = glusterd_check_option_exists (key, &key_fixed); + if (exists == -1) { +@@ -2364,6 +2385,16 @@ glusterd_op_reset_volume (dict_t *dict, char **op_rspstr) + } + } + ++ if (!strcmp(key, "ganesha.enable") || !strcmp (key, "all")) { ++ if (glusterd_check_ganesha_export (volinfo)) { ++ ret = manage_export_config (volname, "off", op_rspstr); ++ if (ret) ++ gf_msg (this->name, GF_LOG_WARNING, 0, ++ GD_MSG_NFS_GNS_RESET_FAIL, ++ "Could not reset ganesha.enable key"); ++ } ++ } ++ + out: + GF_FREE (key_fixed); + if (quorum_action) +@@ -2960,6 +2991,9 @@ glusterd_op_set_volume (dict_t *dict, char **errstr) + } + } + ++ ret = glusterd_check_ganesha_cmd (key, value, errstr, dict); ++ if (ret == -1) ++ goto out; + if (!is_key_glusterd_hooks_friendly (key)) { + ret = glusterd_check_option_exists (key, &key_fixed); + GF_ASSERT (ret); +@@ -4568,6 +4602,12 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx) + } + break; + ++ case GD_OP_GANESHA: ++ { ++ dict_copy (dict, req_dict); ++ } ++ break; ++ + default: + break; + } +@@ -6062,6 +6102,10 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr, + ret = glusterd_op_stage_set_volume (dict, op_errstr); + break; + ++ case GD_OP_GANESHA: ++ ret = glusterd_op_stage_set_ganesha (dict, op_errstr); ++ break; ++ + case GD_OP_RESET_VOLUME: + ret = glusterd_op_stage_reset_volume (dict, op_errstr); + break; +@@ -6195,6 +6239,9 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr, + case GD_OP_SET_VOLUME: + ret = glusterd_op_set_volume (dict, op_errstr); + break; ++ case GD_OP_GANESHA: ++ ret = glusterd_op_set_ganesha (dict, op_errstr); ++ break; + + + case GD_OP_RESET_VOLUME: +diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +index 4cbade1..2a0d321 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +@@ -3702,6 +3702,146 @@ out: + + } + ++/* * ++ * Here there are two possibilities, either destination is snaphot or ++ * clone. In the case of snapshot nfs_ganesha export file will be copied ++ * to snapdir. If it is clone , then new export file will be created for ++ * the clone in the GANESHA_EXPORT_DIRECTORY, replacing occurences of ++ * volname with clonename ++ */ ++int ++glusterd_copy_nfs_ganesha_file (glusterd_volinfo_t *src_vol, ++ glusterd_volinfo_t *dest_vol) ++{ ++ ++ int32_t ret = -1; ++ char snap_dir[PATH_MAX] = {0,}; ++ char src_path[PATH_MAX] = {0,}; ++ char dest_path[PATH_MAX] = {0,}; ++ char buffer[BUFSIZ] = {0,}; ++ char *find_ptr = NULL; ++ char *buff_ptr = NULL; ++ char *tmp_ptr = NULL; ++ xlator_t *this = NULL; ++ glusterd_conf_t *priv = NULL; ++ struct stat stbuf = {0,}; ++ FILE *src = NULL; ++ FILE *dest = NULL; ++ ++ ++ this = THIS; ++ GF_VALIDATE_OR_GOTO ("snapshot", this, out); ++ priv = this->private; ++ GF_VALIDATE_OR_GOTO (this->name, priv, out); ++ ++ GF_VALIDATE_OR_GOTO (this->name, src_vol, out); ++ GF_VALIDATE_OR_GOTO (this->name, dest_vol, out); ++ ++ if (glusterd_check_ganesha_export(src_vol) == _gf_false) { ++ gf_msg_debug (this->name, 0, "%s is not exported via " ++ "NFS-Ganesha. Skipping copy of export conf.", ++ src_vol->volname); ++ ret = 0; ++ goto out; ++ } ++ ++ if (src_vol->is_snap_volume) { ++ GLUSTERD_GET_SNAP_DIR (snap_dir, src_vol->snapshot, priv); ++ ret = snprintf (src_path, PATH_MAX, "%s/export.%s.conf", ++ snap_dir, src_vol->snapshot->snapname); ++ } else { ++ ret = snprintf (src_path, PATH_MAX, "%s/export.%s.conf", ++ GANESHA_EXPORT_DIRECTORY, src_vol->volname); ++ } ++ if (ret < 0 || ret >= PATH_MAX) ++ goto out; ++ ++ ret = sys_lstat (src_path, &stbuf); ++ if (ret) { ++ /* ++ * This code path is hit, only when the src_vol is being * ++ * exported via NFS-Ganesha. So if the conf file is not * ++ * available, we fail the snapshot operation. * ++ */ ++ gf_msg (this->name, GF_LOG_ERROR, errno, ++ GD_MSG_FILE_OP_FAILED, ++ "Stat on %s failed with %s", ++ src_path, strerror (errno)); ++ goto out; ++ } ++ ++ if (dest_vol->is_snap_volume) { ++ memset (snap_dir, 0 , PATH_MAX); ++ GLUSTERD_GET_SNAP_DIR (snap_dir, dest_vol->snapshot, priv); ++ ret = snprintf (dest_path, sizeof (dest_path), ++ "%s/export.%s.conf", snap_dir, ++ dest_vol->snapshot->snapname); ++ if (ret < 0) ++ goto out; ++ ++ ret = glusterd_copy_file (src_path, dest_path); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, ENOMEM, ++ GD_MSG_NO_MEMORY, "Failed to copy %s in %s", ++ src_path, dest_path); ++ goto out; ++ } ++ ++ } else { ++ ret = snprintf (dest_path, sizeof (dest_path), ++ "%s/export.%s.conf", GANESHA_EXPORT_DIRECTORY, ++ dest_vol->volname); ++ if (ret < 0) ++ goto out; ++ ++ src = fopen (src_path, "r"); ++ dest = fopen (dest_path, "w"); ++ ++ if (!src || !dest) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_FILE_OP_FAILED, ++ "Failed to open %s", ++ dest ? src_path : dest_path); ++ ret = -1; ++ goto out; ++ } ++ ++ /* * ++ * if the source volume is snapshot, the export conf file ++ * consists of orginal volname ++ */ ++ if (src_vol->is_snap_volume) ++ find_ptr = gf_strdup (src_vol->parent_volname); ++ else ++ find_ptr = gf_strdup (src_vol->volname); ++ ++ if (!find_ptr) ++ goto out; ++ ++ /* Replacing volname with clonename */ ++ while (fgets(buffer, BUFSIZ, src)) { ++ buff_ptr = buffer; ++ while ((tmp_ptr = strstr(buff_ptr, find_ptr))) { ++ while (buff_ptr < tmp_ptr) ++ fputc((int)*buff_ptr++, dest); ++ fputs(dest_vol->volname, dest); ++ buff_ptr += strlen(find_ptr); ++ } ++ fputs(buff_ptr, dest); ++ memset (buffer, 0, BUFSIZ); ++ } ++ } ++out: ++ if (src) ++ fclose (src); ++ if (dest) ++ fclose (dest); ++ if (find_ptr) ++ GF_FREE(find_ptr); ++ ++ return ret; ++} ++ + int32_t + glusterd_restore_geo_rep_files (glusterd_volinfo_t *snap_vol) + { +@@ -3792,6 +3932,62 @@ out: + return ret; + } + ++int ++glusterd_restore_nfs_ganesha_file (glusterd_volinfo_t *src_vol, ++ glusterd_snap_t *snap) ++{ ++ ++ int32_t ret = -1; ++ char snap_dir[PATH_MAX] = ""; ++ char src_path[PATH_MAX] = ""; ++ char dest_path[PATH_MAX] = ""; ++ xlator_t *this = NULL; ++ glusterd_conf_t *priv = NULL; ++ struct stat stbuf = {0,}; ++ ++ this = THIS; ++ GF_VALIDATE_OR_GOTO ("snapshot", this, out); ++ priv = this->private; ++ GF_VALIDATE_OR_GOTO (this->name, priv, out); ++ ++ GF_VALIDATE_OR_GOTO (this->name, src_vol, out); ++ GF_VALIDATE_OR_GOTO (this->name, snap, out); ++ ++ GLUSTERD_GET_SNAP_DIR (snap_dir, snap, priv); ++ ++ ret = snprintf (src_path, sizeof (src_path), "%s/export.%s.conf", ++ snap_dir, snap->snapname); ++ if (ret < 0) ++ goto out; ++ ++ ret = sys_lstat (src_path, &stbuf); ++ if (ret) { ++ if (errno == ENOENT) { ++ ret = 0; ++ gf_msg_debug (this->name, 0, "%s not found", src_path); ++ } else ++ gf_msg (this->name, GF_LOG_WARNING, errno, ++ GD_MSG_FILE_OP_FAILED, ++ "Stat on %s failed with %s", ++ src_path, strerror (errno)); ++ goto out; ++ } ++ ++ ret = snprintf (dest_path, sizeof (dest_path), "%s/export.%s.conf", ++ GANESHA_EXPORT_DIRECTORY, src_vol->volname); ++ if (ret < 0) ++ goto out; ++ ++ ret = glusterd_copy_file (src_path, dest_path); ++ if (ret) ++ gf_msg (this->name, GF_LOG_ERROR, ENOMEM, ++ GD_MSG_NO_MEMORY, "Failed to copy %s in %s", ++ src_path, dest_path); ++ ++out: ++ return ret; ++ ++} + /* Snapd functions */ + int + glusterd_is_snapd_enabled (glusterd_volinfo_t *volinfo) +diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h +index b13493d..e050166 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h ++++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h +@@ -99,12 +99,19 @@ glusterd_get_geo_rep_session (char *slave_key, char *origin_volname, + int32_t + glusterd_restore_geo_rep_files (glusterd_volinfo_t *snap_vol); + ++int ++glusterd_restore_nfs_ganesha_file (glusterd_volinfo_t *src_vol, ++ glusterd_snap_t *snap); + int32_t + glusterd_copy_quota_files (glusterd_volinfo_t *src_vol, + glusterd_volinfo_t *dest_vol, + gf_boolean_t *conf_present); + + int ++glusterd_copy_nfs_ganesha_file (glusterd_volinfo_t *src_vol, ++ glusterd_volinfo_t *dest_vol); ++ ++int + glusterd_snap_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict); + + int +diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c +index 6306d29..c38d2ff 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c ++++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c +@@ -904,6 +904,76 @@ out: + return ret; + } + ++/* ++ * This function validates the particulat snapshot with respect to the current ++ * cluster. If the snapshot has ganesha enabled, and the cluster is not a nfs ++ * ganesha cluster, we fail the validation. Other scenarios where either the ++ * snapshot does not have ganesha enabled or it has and the cluster is a nfs ++ * ganesha cluster, we pass the validation ++ * ++ * @param snap snap object of the snapshot to be validated ++ * @return Negative value on Failure and 0 in success ++ */ ++int32_t ++glusterd_snapshot_validate_ganesha_conf (glusterd_snap_t *snap, ++ char **op_errstr, ++ uint32_t *op_errno) ++{ ++ int ret = -1; ++ glusterd_volinfo_t *snap_vol = NULL; ++ xlator_t *this = NULL; ++ ++ this = THIS; ++ GF_VALIDATE_OR_GOTO ("snapshot", this, out); ++ GF_VALIDATE_OR_GOTO (this->name, snap, out); ++ GF_VALIDATE_OR_GOTO (this->name, op_errstr, out); ++ GF_VALIDATE_OR_GOTO (this->name, op_errno, out); ++ ++ snap_vol = list_entry (snap->volumes.next, ++ glusterd_volinfo_t, vol_list); ++ ++ GF_VALIDATE_OR_GOTO (this->name, snap_vol, out); ++ ++ /* ++ * Check if the snapshot has ganesha enabled * ++ */ ++ if (glusterd_check_ganesha_export(snap_vol) == _gf_false) { ++ /* ++ * If the snapshot has not been exported via ganesha * ++ * then we can proceed. * ++ */ ++ ret = 0; ++ goto out; ++ } ++ ++ /* ++ * At this point we are certain that the snapshot has been exported * ++ * via ganesha. So we check if the cluster is a nfs-ganesha cluster * ++ * If it a nfs-ganesha cluster, then we proceed. Else we fail. * ++ */ ++ if (glusterd_is_ganesha_cluster() != _gf_true) { ++ ret = gf_asprintf (op_errstr, "Snapshot(%s) has a " ++ "nfs-ganesha export conf file. " ++ "cluster.enable-shared-storage and " ++ "nfs-ganesha should be enabled " ++ "before restoring this snapshot.", ++ snap->snapname); ++ *op_errno = EG_NOGANESHA; ++ if (ret < 0) { ++ goto out; ++ } ++ ++ gf_msg (this->name, GF_LOG_ERROR, EINVAL, ++ GD_MSG_NFS_GANESHA_DISABLED, "%s", *op_errstr); ++ ret = -1; ++ goto out; ++ } ++ ++ ret = 0; ++out: ++ return ret; ++} ++ + /* This function is called before actual restore is taken place. This function + * will validate whether the snapshot volumes are ready to be restored or not. + * +@@ -974,6 +1044,15 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr, + goto out; + } + ++ ret = glusterd_snapshot_validate_ganesha_conf (snap, op_errstr, ++ op_errno); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_SNAPSHOT_OP_FAILED, ++ "ganesha conf validation failed."); ++ goto out; ++ } ++ + ret = dict_set_str (rsp_dict, "snapname", snapname); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, +@@ -5369,6 +5448,13 @@ glusterd_do_snap_vol (glusterd_volinfo_t *origin_vol, glusterd_snap_t *snap, + + } + ++ ret = glusterd_copy_nfs_ganesha_file (origin_vol, snap_vol); ++ if (ret < 0) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_VOL_OP_FAILED, "Failed to copy export " ++ "file for volume %s", origin_vol->volname); ++ goto out; ++ } + glusterd_auth_set_username (snap_vol, username); + glusterd_auth_set_password (snap_vol, password); + +@@ -9968,6 +10054,16 @@ gd_restore_snap_volume (dict_t *dict, dict_t *rsp_dict, + snap_vol->snapshot->snapname); + } + ++ ret = glusterd_restore_nfs_ganesha_file (orig_vol, snap); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_WARNING, 0, ++ GD_MSG_SNAP_RESTORE_FAIL, ++ "Failed to restore " ++ "nfs-ganesha export file for snap %s", ++ snap_vol->snapshot->snapname); ++ goto out; ++ } ++ + /* Need not save cksum, as we will copy cksum file in * + * this function * + */ +diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h +index 603151a..bf504e0 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-store.h ++++ b/xlators/mgmt/glusterd/src/glusterd-store.h +@@ -83,6 +83,7 @@ typedef enum glusterd_store_ver_ac_{ + #define GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT "snap-max-soft-limit" + #define GLUSTERD_STORE_KEY_SNAPD_PORT "snapd-port" + #define GLUSTERD_STORE_KEY_SNAP_ACTIVATE "snap-activate-on-create" ++#define GLUSTERD_STORE_KEY_GANESHA_GLOBAL "nfs-ganesha" + + #define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname" + #define GLUSTERD_STORE_KEY_BRICK_PATH "path" +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +index bec5f72..0914fb1 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +@@ -1737,6 +1737,16 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) + ret = -1; + goto out; + } ++ ret = glusterd_check_ganesha_export (volinfo); ++ if (ret) { ++ ret = ganesha_manage_export(dict, "off", op_errstr); ++ if (ret) { ++ gf_msg (THIS->name, GF_LOG_WARNING, 0, ++ GD_MSG_NFS_GNS_UNEXPRT_VOL_FAIL, "Could not " ++ "unexport volume via NFS-Ganesha"); ++ ret = 0; ++ } ++ } + + if (glusterd_is_defrag_on (volinfo)) { + snprintf (msg, sizeof(msg), "rebalance session is " +@@ -2595,6 +2605,8 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) + char *brick_mount_dir = NULL; + char key[PATH_MAX] = ""; + char *volname = NULL; ++ char *str = NULL; ++ gf_boolean_t option = _gf_false; + int flags = 0; + glusterd_volinfo_t *volinfo = NULL; + glusterd_brickinfo_t *brickinfo = NULL; +@@ -2657,6 +2669,28 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) + } + } + ++ ret = dict_get_str (conf->opts, GLUSTERD_STORE_KEY_GANESHA_GLOBAL, &str); ++ if (ret != 0) { ++ gf_msg (this->name, GF_LOG_INFO, 0, ++ GD_MSG_DICT_GET_FAILED, "Global dict not present."); ++ ret = 0; ++ ++ } else { ++ ret = gf_string2boolean (str, &option); ++ /* Check if the feature is enabled and set nfs-disable to true */ ++ if (option) { ++ gf_msg_debug (this->name, 0, "NFS-Ganesha is enabled"); ++ /* Gluster-nfs should not start when NFS-Ganesha is enabled*/ ++ ret = dict_set_str (volinfo->dict, NFS_DISABLE_MAP_KEY, "on"); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_SET_FAILED, "Failed to set nfs.disable for" ++ "volume %s", volname); ++ goto out; ++ } ++ } ++ } ++ + ret = glusterd_start_volume (volinfo, flags, _gf_true); + if (ret) + goto out; +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +index 2210b82..7fe76e5 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +@@ -3210,6 +3210,12 @@ struct volopt_map_entry glusterd_volopt_map[] = { + .op_version = GD_OP_VERSION_3_7_0, + .flags = OPT_FLAG_CLIENT_OPT + }, ++ { .key = "ganesha.enable", ++ .voltype = "features/ganesha", ++ .value = "off", ++ .option = "ganesha.enable", ++ .op_version = GD_OP_VERSION_3_7_0, ++ }, + { .key = "features.shard", + .voltype = "features/shard", + .value = "off", +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index 59b1775..2d8dbb9 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -57,6 +57,8 @@ + #define GLUSTERD_BRICKMUX_LIMIT_KEY "cluster.max-bricks-per-process" + #define GLUSTERD_LOCALTIME_LOGGING_KEY "cluster.localtime-logging" + ++#define GANESHA_HA_CONF CONFDIR "/ganesha-ha.conf" ++#define GANESHA_EXPORT_DIRECTORY CONFDIR"/exports" + #define GLUSTERD_SNAPS_MAX_HARD_LIMIT 256 + #define GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT 90 + #define GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT 100 +@@ -117,7 +119,7 @@ typedef enum glusterd_op_ { + GD_OP_GSYNC_CREATE, + GD_OP_SNAP, + GD_OP_BARRIER, +- GD_OP_GANESHA, /* obsolete */ ++ GD_OP_GANESHA, + GD_OP_BITROT, + GD_OP_DETACH_TIER, + GD_OP_TIER_MIGRATE, +@@ -1168,8 +1170,20 @@ int glusterd_op_create_volume (dict_t *dict, char **op_errstr); + int glusterd_op_start_volume (dict_t *dict, char **op_errstr); + int glusterd_op_stop_volume (dict_t *dict); + int glusterd_op_delete_volume (dict_t *dict); ++int glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, ++ char *key, char *value); ++int glusterd_check_ganesha_cmd (char *key, char *value, ++ char **errstr, dict_t *dict); ++int glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr); ++int glusterd_op_set_ganesha (dict_t *dict, char **errstr); ++int ganesha_manage_export (dict_t *dict, char *value, char **op_errstr); + int manage_export_config (char *volname, char *value, char **op_errstr); + ++gf_boolean_t ++glusterd_is_ganesha_cluster (); ++gf_boolean_t glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo); ++int stop_ganesha (char **op_errstr); ++int tear_down_cluster (gf_boolean_t run_teardown); + int glusterd_op_add_brick (dict_t *dict, char **op_errstr); + int glusterd_op_add_tier_brick (dict_t *dict, char **op_errstr); + int glusterd_op_remove_brick (dict_t *dict, char **op_errstr); +-- +1.8.3.1 + diff --git a/SOURCES/0050-quota-cli-add-user-driven-quota-events.patch b/SOURCES/0050-quota-cli-add-user-driven-quota-events.patch deleted file mode 100644 index bebbf5e..0000000 --- a/SOURCES/0050-quota-cli-add-user-driven-quota-events.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 9f2bd89762a853b2af93d290db68017555ab6c1a Mon Sep 17 00:00:00 2001 -From: Manikandan Selvaganesh -Date: Mon, 22 Aug 2016 12:43:19 +0530 -Subject: [PATCH 50/86] quota/cli: add user driven quota events - -This patch targets to capture all the user driven quota related events -which are important to be notified. - ->Reviewed-on: http://review.gluster.org/15230 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Atin Mukherjee - -Change-Id: I90c0af434363465e9dbdf6fca65ac220251d8d3c -BUG: 1361078 -Signed-off-by: Manikandan Selvaganesh -Reviewed-on: https://code.engineering.redhat.com/gerrit/84797 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ - events/eventskeygen.py | 13 ++++++++++++ - 2 files changed, 60 insertions(+), 0 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 0ea461e..27cb9dd 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -1707,6 +1707,53 @@ out: - "logs for more details"); - } - -+ /* Events for Quota */ -+ if (ret == 0) { -+ switch (type) { -+ case GF_QUOTA_OPTION_TYPE_ENABLE: -+ gf_event (EVENT_QUOTA_ENABLE, "volume=%s", volname); -+ break; -+ case GF_QUOTA_OPTION_TYPE_DISABLE: -+ gf_event (EVENT_QUOTA_DISABLE, "volume=%s", volname); -+ break; -+ case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE: -+ gf_event (EVENT_QUOTA_SET_USAGE_LIMIT, "volume=%s;" -+ "path=%s;limit=%s", volname, words[4], -+ words[5]); -+ break; -+ case GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS: -+ gf_event (EVENT_QUOTA_SET_OBJECTS_LIMIT, "volume=%s;" -+ "path=%s;limit=%s", volname, words[4], -+ words[5]); -+ break; -+ case GF_QUOTA_OPTION_TYPE_REMOVE: -+ gf_event (EVENT_QUOTA_REMOVE_USAGE_LIMIT, "volume=%s;" -+ "path=%s", volname, words[4]); -+ break; -+ case GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS: -+ gf_event (EVENT_QUOTA_REMOVE_OBJECTS_LIMIT, -+ "volume=%s;" "path=%s", volname, words[4]); -+ break; -+ case GF_QUOTA_OPTION_TYPE_ALERT_TIME: -+ gf_event (EVENT_QUOTA_ALERT_TIME, "volume=%s;time=%s", -+ volname, words[4]); -+ break; -+ case GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT: -+ gf_event (EVENT_QUOTA_SOFT_TIMEOUT, "volume=%s;" -+ "soft-timeout=%s", volname, words[4]); -+ break; -+ case GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT: -+ gf_event (EVENT_QUOTA_HARD_TIMEOUT, "volume=%s;" -+ "hard-timeout=%s", volname, words[4]); -+ break; -+ case GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT: -+ gf_event (EVENT_QUOTA_DEFAULT_SOFT_LIMIT, "volume=%s;" -+ "default-soft-limit=%s", volname, words[4]); -+ break; -+ } -+ } -+ -+ - CLI_STACK_DESTROY (frame); - return ret; - } -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 885c9de..144c554 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -69,6 +69,7 @@ keys = ( - "EVENT_BRICKPATH_RESOLVE_FAILED", - - "EVENT_NOTIFY_UNKNOWN_OP", -+ - "EVENT_QUORUM_LOST", - "EVENT_QUORUM_REGAINED", - "EVENT_REBALANCE_START_FAILED", -@@ -78,6 +79,18 @@ keys = ( - "EVENT_IMPORT_BRICK_FAILED", - "EVENT_COMPARE_FRIEND_VOLUME_FAILED", - "EVENT_NFS_GANESHA_EXPORT_FAILED", -+ -+ "EVENT_QUOTA_ENABLE", -+ "EVENT_QUOTA_DISABLE", -+ "EVENT_QUOTA_SET_USAGE_LIMIT", -+ "EVENT_QUOTA_SET_OBJECTS_LIMIT", -+ "EVENT_QUOTA_REMOVE_USAGE_LIMIT", -+ "EVENT_QUOTA_REMOVE_OBJECTS_LIMIT", -+ "EVENT_QUOTA_ALERT_TIME", -+ "EVENT_QUOTA_SOFT_TIMEOUT", -+ "EVENT_QUOTA_HARD_TIMEOUT", -+ "EVENT_QUOTA_DEFAULT_SOFT_LIMIT", -+ - ) - - LAST_EVENT = "EVENT_LAST" --- -1.7.1 - diff --git a/SOURCES/0051-Revert-storhaug-HA-first-step-remove-resource-agents.patch b/SOURCES/0051-Revert-storhaug-HA-first-step-remove-resource-agents.patch new file mode 100644 index 0000000..ab69430 --- /dev/null +++ b/SOURCES/0051-Revert-storhaug-HA-first-step-remove-resource-agents.patch @@ -0,0 +1,1878 @@ +From 5883eed6d1480d178205d4de42d023c8d144a4ea Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Mon, 16 Oct 2017 16:58:28 +0530 +Subject: [PATCH 51/74] Revert "storhaug HA: first step, remove resource agents + and setup script" + +This reverts commit c822e354e16646adf18bbc5123798663faa543b2. + +Change-Id: Idd50fe1a5be5a3258d560518d810f9ec4c57621a +Signed-off-by: Jiffin Tony Thottan +--- + configure.ac | 1 + + extras/ganesha/Makefile.am | 2 +- + extras/ganesha/ocf/Makefile.am | 12 + + extras/ganesha/ocf/ganesha_grace | 222 +++++++ + extras/ganesha/ocf/ganesha_mon | 235 +++++++ + extras/ganesha/ocf/ganesha_nfsd | 168 +++++ + extras/ganesha/scripts/Makefile.am | 6 +- + extras/ganesha/scripts/ganesha-ha.sh | 1126 ++++++++++++++++++++++++++++++++++ + glusterfs.spec.in | 4 +- + 9 files changed, 1772 insertions(+), 4 deletions(-) + create mode 100644 extras/ganesha/ocf/Makefile.am + create mode 100644 extras/ganesha/ocf/ganesha_grace + create mode 100644 extras/ganesha/ocf/ganesha_mon + create mode 100644 extras/ganesha/ocf/ganesha_nfsd + create mode 100644 extras/ganesha/scripts/ganesha-ha.sh + +diff --git a/configure.ac b/configure.ac +index c8e6e44..c9a1cde 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -210,6 +210,7 @@ AC_CONFIG_FILES([Makefile + extras/ganesha/Makefile + extras/ganesha/config/Makefile + extras/ganesha/scripts/Makefile ++ extras/ganesha/ocf/Makefile + extras/systemd/Makefile + extras/systemd/glusterd.service + extras/systemd/glustereventsd.service +diff --git a/extras/ganesha/Makefile.am b/extras/ganesha/Makefile.am +index 542de68..9eaa401 100644 +--- a/extras/ganesha/Makefile.am ++++ b/extras/ganesha/Makefile.am +@@ -1,2 +1,2 @@ +-SUBDIRS = scripts config ++SUBDIRS = scripts config ocf + CLEANFILES = +diff --git a/extras/ganesha/ocf/Makefile.am b/extras/ganesha/ocf/Makefile.am +new file mode 100644 +index 0000000..6aed954 +--- /dev/null ++++ b/extras/ganesha/ocf/Makefile.am +@@ -0,0 +1,12 @@ ++EXTRA_DIST= ganesha_grace ganesha_mon ganesha_nfsd ++ ++# The root of the OCF resource agent hierarchy ++# Per the OCF standard, it's always "lib", ++# not "lib64" (even on 64-bit platforms). ++ocfdir = $(prefix)/lib/ocf ++ ++# The provider directory ++radir = $(ocfdir)/resource.d/heartbeat ++ ++ra_SCRIPTS = ganesha_grace ganesha_mon ganesha_nfsd ++ +diff --git a/extras/ganesha/ocf/ganesha_grace b/extras/ganesha/ocf/ganesha_grace +new file mode 100644 +index 0000000..cb6dcc4 +--- /dev/null ++++ b/extras/ganesha/ocf/ganesha_grace +@@ -0,0 +1,222 @@ ++#!/bin/bash ++# ++# Copyright (c) 2014 Anand Subramanian anands@redhat.com ++# Copyright (c) 2015 Red Hat Inc. ++# All Rights Reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it would be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++# ++# Further, this software is distributed without any warranty that it is ++# free of the rightful claim of any third person regarding infringement ++# or the like. Any license provided herein, whether implied or ++# otherwise, applies only to this software file. Patent licenses, if ++# any, provided herein do not apply to combinations of this program with ++# other software, or any other product whatsoever. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write the Free Software Foundation, ++# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++# ++# ++ ++# Initialization: ++: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++ ++if [ -n "$OCF_DEBUG_LIBRARY" ]; then ++ . $OCF_DEBUG_LIBRARY ++else ++ : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++ . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++fi ++ ++OCF_RESKEY_grace_active_default="grace-active" ++: ${OCF_RESKEY_grace_active=${OCF_RESKEY_grace_active_default}} ++ ++ganesha_meta_data() { ++ cat < ++ ++ ++1.0 ++ ++ ++This Linux-specific resource agent acts as a dummy ++resource agent for nfs-ganesha. ++ ++ ++Manages the user-space nfs-ganesha NFS server ++ ++ ++ ++NFS-Ganesha grace active attribute ++NFS-Ganesha grace active attribute ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++END ++ ++return ${OCF_SUCCESS} ++} ++ ++ganesha_grace_usage() { ++ echo "ganesha.nfsd USAGE" ++} ++ ++# Make sure meta-data and usage always succeed ++case $__OCF_ACTION in ++ meta-data) ganesha_meta_data ++ exit ${OCF_SUCCESS} ++ ;; ++ usage|help) ganesha_usage ++ exit ${OCF_SUCCESS} ++ ;; ++ *) ++ ;; ++esac ++ ++ganesha_grace_start() ++{ ++ local rc=${OCF_ERR_GENERIC} ++ local host=$(hostname -s) ++ ++ ocf_log debug "ganesha_grace_start()" ++ # give ganesha_mon RA a chance to set the crm_attr first ++ # I mislike the sleep, but it's not clear that looping ++ # with a small sleep is necessarily better ++ # start has a 40sec timeout, so a 5sec sleep here is okay ++ sleep 5 ++ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null) ++ if [ $? -ne 0 ]; then ++ host=$(hostname) ++ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null ) ++ if [ $? -ne 0 ]; then ++ ocf_log info "grace start: crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} failed" ++ fi ++ fi ++ ++ # Three possibilities: ++ # 1. There is no attribute at all and attr_updater returns ++ # a zero length string. This happens when ++ # ganesha_mon::monitor hasn't run at least once to set ++ # the attribute. The assumption here is that the system ++ # is coming up. We pretend, for now, that the node is ++ # healthy, to allow the system to continue coming up. ++ # It will cure itself in a few seconds ++ # 2. There is an attribute, and it has the value "1"; this ++ # node is healthy. ++ # 3. There is an attribute, but it has no value or the value ++ # "0"; this node is not healthy. ++ ++ # case 1 ++ if [[ -z "${attr}" ]]; then ++ return ${OCF_SUCCESS} ++ fi ++ ++ # case 2 ++ if [[ "${attr}" = *"value=1" ]]; then ++ return ${OCF_SUCCESS} ++ fi ++ ++ # case 3 ++ return ${OCF_NOT_RUNNING} ++} ++ ++ganesha_grace_stop() ++{ ++ ++ ocf_log debug "ganesha_grace_stop()" ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_grace_notify() ++{ ++ # since this is a clone RA we should only ever see pre-start ++ # or post-stop ++ mode="${OCF_RESKEY_CRM_meta_notify_type}-${OCF_RESKEY_CRM_meta_notify_operation}" ++ case "${mode}" in ++ pre-start | post-stop) ++ dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace string:${OCF_RESKEY_CRM_meta_notify_stop_uname} ++ if [ $? -ne 0 ]; then ++ ocf_log info "dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace string:${OCF_RESKEY_CRM_meta_notify_stop_uname} failed" ++ fi ++ ;; ++ esac ++ ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_grace_monitor() ++{ ++ local host=$(hostname -s) ++ ++ ocf_log debug "monitor" ++ ++ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null) ++ if [ $? -ne 0 ]; then ++ host=$(hostname) ++ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null) ++ if [ $? -ne 0 ]; then ++ ocf_log info "crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} failed" ++ fi ++ fi ++ ++ # if there is no attribute (yet), maybe it's because ++ # this RA started before ganesha_mon (nfs-mon) has had ++ # chance to create it. In which case we'll pretend ++ # everything is okay this time around ++ if [[ -z "${attr}" ]]; then ++ return ${OCF_SUCCESS} ++ fi ++ ++ if [[ "${attr}" = *"value=1" ]]; then ++ return ${OCF_SUCCESS} ++ fi ++ ++ return ${OCF_NOT_RUNNING} ++} ++ ++ganesha_grace_validate() ++{ ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_grace_validate ++ ++# Translate each action into the appropriate function call ++case $__OCF_ACTION in ++start) ganesha_grace_start ++ ;; ++stop) ganesha_grace_stop ++ ;; ++status|monitor) ganesha_grace_monitor ++ ;; ++notify) ganesha_grace_notify ++ ;; ++*) ganesha_grace_usage ++ exit ${OCF_ERR_UNIMPLEMENTED} ++ ;; ++esac ++ ++rc=$? ++ ++# The resource agent may optionally log a debug message ++ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned $rc" ++exit $rc ++ +diff --git a/extras/ganesha/ocf/ganesha_mon b/extras/ganesha/ocf/ganesha_mon +new file mode 100644 +index 0000000..7d2c268 +--- /dev/null ++++ b/extras/ganesha/ocf/ganesha_mon +@@ -0,0 +1,235 @@ ++#!/bin/bash ++# ++# Copyright (c) 2014 Anand Subramanian anands@redhat.com ++# Copyright (c) 2015 Red Hat Inc. ++# All Rights Reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it would be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++# ++# Further, this software is distributed without any warranty that it is ++# free of the rightful claim of any third person regarding infringement ++# or the like. Any license provided herein, whether implied or ++# otherwise, applies only to this software file. Patent licenses, if ++# any, provided herein do not apply to combinations of this program with ++# other software, or any other product whatsoever. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write the Free Software Foundation, ++# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++# ++# ++ ++# Initialization: ++: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++ ++if [ -n "${OCF_DEBUG_LIBRARY}" ]; then ++ . ${OCF_DEBUG_LIBRARY} ++else ++ : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++ . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++fi ++ ++# Defaults ++OCF_RESKEY_ganesha_active_default="ganesha-active" ++OCF_RESKEY_grace_active_default="grace-active" ++OCF_RESKEY_grace_delay_default="5" ++ ++: ${OCF_RESKEY_ganesha_active=${OCF_RESKEY_ganesha_active_default}} ++: ${OCF_RESKEY_grace_active=${OCF_RESKEY_grace_active_default}} ++: ${OCF_RESKEY_grace_delay=${OCF_RESKEY_grace_delay_default}} ++ ++ganesha_meta_data() { ++ cat < ++ ++ ++1.0 ++ ++ ++This Linux-specific resource agent acts as a dummy ++resource agent for nfs-ganesha. ++ ++ ++Manages the user-space nfs-ganesha NFS server ++ ++ ++ ++NFS-Ganesha daemon active attribute ++NFS-Ganesha daemon active attribute ++ ++ ++ ++NFS-Ganesha grace active attribute ++NFS-Ganesha grace active attribute ++ ++ ++ ++ ++NFS-Ganesha grace delay. ++When changing this, adjust the ganesha_grace RA's monitor interval to match. ++ ++NFS-Ganesha grace delay ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++END ++ ++return ${OCF_SUCCESS} ++} ++ ++ganesha_mon_usage() { ++ echo "ganesha.nfsd USAGE" ++} ++ ++# Make sure meta-data and usage always succeed ++case ${__OCF_ACTION} in ++ meta-data) ganesha_meta_data ++ exit ${OCF_SUCCESS} ++ ;; ++ usage|help) ganesha_usage ++ exit ${OCF_SUCCESS} ++ ;; ++ *) ++ ;; ++esac ++ ++ganesha_mon_start() ++{ ++ ocf_log debug "ganesha_mon_start" ++ ganesha_mon_monitor ++ return $OCF_SUCCESS ++} ++ ++ganesha_mon_stop() ++{ ++ ocf_log debug "ganesha_mon_stop" ++ return $OCF_SUCCESS ++} ++ ++ganesha_mon_monitor() ++{ ++ local host=$(hostname -s) ++ local pid_file="/var/run/ganesha.pid" ++ local rhel6_pid_file="/var/run/ganesha.nfsd.pid" ++ local proc_pid="/proc/" ++ ++ # RHEL6 /etc/init.d/nfs-ganesha adds -p /var/run/ganesha.nfsd.pid ++ # RHEL7 systemd does not. Would be nice if all distros used the ++ # same pid file. ++ if [ -e ${rhel6_pid_file} ]; then ++ pid_file=${rhel6_pid_file} ++ fi ++ if [ -e ${pid_file} ]; then ++ proc_pid="${proc_pid}$(cat ${pid_file})" ++ fi ++ ++ if [ "x${proc_pid}" != "x/proc/" -a -d ${proc_pid} ]; then ++ ++ attrd_updater -n ${OCF_RESKEY_ganesha_active} -v 1 ++ if [ $? -ne 0 ]; then ++ ocf_log info "warning: attrd_updater -n ${OCF_RESKEY_ganesha_active} -v 1 failed" ++ fi ++ ++ # ganesha_grace (nfs-grace) RA follows grace-active attr ++ # w/ constraint location ++ attrd_updater -n ${OCF_RESKEY_grace_active} -v 1 ++ if [ $? -ne 0 ]; then ++ ocf_log info "warning: attrd_updater -n ${OCF_RESKEY_grace_active} -v 1 failed" ++ fi ++ ++ # ganesha_mon (nfs-mon) and ganesha_grace (nfs-grace) ++ # track grace-active crm_attr (attr != crm_attr) ++ # we can't just use the attr as there's no way to query ++ # its value in RHEL6 pacemaker ++ ++ crm_attribute --node=${host} --lifetime=forever --name=${OCF_RESKEY_grace_active} --update=1 2> /dev/null ++ if [ $? -ne 0 ]; then ++ host=$(hostname) ++ crm_attribute --node=${host} --lifetime=forever --name=${OCF_RESKEY_grace_active} --update=1 2> /dev/null ++ if [ $? -ne 0 ]; then ++ ocf_log info "mon monitor warning: crm_attribute --node=${host} --lifetime=forever --name=${OCF_RESKEY_grace_active} --update=1 failed" ++ fi ++ fi ++ ++ return ${OCF_SUCCESS} ++ fi ++ ++ # VIP fail-over is triggered by clearing the ++ # ganesha-active node attribute on this node. ++ # ++ # Meanwhile the ganesha_grace notify() runs when its ++ # nfs-grace resource is disabled on a node; which ++ # is triggered by clearing the grace-active attribute ++ # on this node. ++ # ++ # We need to allow time for it to run and put ++ # the remaining ganesha.nfsds into grace before ++ # initiating the VIP fail-over. ++ ++ attrd_updater -D -n ${OCF_RESKEY_grace_active} ++ if [ $? -ne 0 ]; then ++ ocf_log info "warning: attrd_updater -D -n ${OCF_RESKEY_grace_active} failed" ++ fi ++ ++ host=$(hostname -s) ++ crm_attribute --node=${host} --name=${OCF_RESKEY_grace_active} --update=0 2> /dev/null ++ if [ $? -ne 0 ]; then ++ host=$(hostname) ++ crm_attribute --node=${host} --name=${OCF_RESKEY_grace_active} --update=0 2> /dev/null ++ if [ $? -ne 0 ]; then ++ ocf_log info "mon monitor warning: crm_attribute --node=${host} --name=${OCF_RESKEY_grace_active} --update=0 failed" ++ fi ++ fi ++ ++ sleep ${OCF_RESKEY_grace_delay} ++ ++ attrd_updater -D -n ${OCF_RESKEY_ganesha_active} ++ if [ $? -ne 0 ]; then ++ ocf_log info "warning: attrd_updater -D -n ${OCF_RESKEY_ganesha_active} failed" ++ fi ++ ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_mon_validate() ++{ ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_mon_validate ++ ++# Translate each action into the appropriate function call ++case ${__OCF_ACTION} in ++start) ganesha_mon_start ++ ;; ++stop) ganesha_mon_stop ++ ;; ++status|monitor) ganesha_mon_monitor ++ ;; ++*) ganesha_mon_usage ++ exit ${OCF_ERR_UNIMPLEMENTED} ++ ;; ++esac ++ ++rc=$? ++ ++# The resource agent may optionally log a debug message ++ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned $rc" ++exit $rc ++ +diff --git a/extras/ganesha/ocf/ganesha_nfsd b/extras/ganesha/ocf/ganesha_nfsd +new file mode 100644 +index 0000000..29e333c +--- /dev/null ++++ b/extras/ganesha/ocf/ganesha_nfsd +@@ -0,0 +1,168 @@ ++#!/bin/bash ++# ++# Copyright (c) 2014 Anand Subramanian anands@redhat.com ++# Copyright (c) 2015 Red Hat Inc. ++# All Rights Reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it would be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++# ++# Further, this software is distributed without any warranty that it is ++# free of the rightful claim of any third person regarding infringement ++# or the like. Any license provided herein, whether implied or ++# otherwise, applies only to this software file. Patent licenses, if ++# any, provided herein do not apply to combinations of this program with ++# other software, or any other product whatsoever. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write the Free Software Foundation, ++# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++# ++# ++ ++# Initialization: ++: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++ ++if [ -n "${OCF_DEBUG_LIBRARY}" ]; then ++ . ${OCF_DEBUG_LIBRARY} ++else ++ : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++ . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++fi ++ ++OCF_RESKEY_ha_vol_mnt_default="/var/run/gluster/shared_storage" ++: ${OCF_RESKEY_ha_vol_mnt=${OCF_RESKEY_ha_vol_mnt_default}} ++ ++ganesha_meta_data() { ++ cat < ++ ++ ++1.0 ++ ++ ++This Linux-specific resource agent acts as a dummy ++resource agent for nfs-ganesha. ++ ++ ++Manages the user-space nfs-ganesha NFS server ++ ++ ++ ++HA State Volume Mount Point ++HA_State Volume Mount Point ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++END ++ ++return ${OCF_SUCCESS} ++} ++ ++ganesha_nfsd_usage() { ++ echo "ganesha.nfsd USAGE" ++} ++ ++# Make sure meta-data and usage always succeed ++case $__OCF_ACTION in ++ meta-data) ganesha_meta_data ++ exit ${OCF_SUCCESS} ++ ;; ++ usage|help) ganesha_usage ++ exit ${OCF_SUCCESS} ++ ;; ++ *) ++ ;; ++esac ++ ++ganesha_nfsd_start() ++{ ++ local long_host=$(hostname) ++ ++ if [[ -d /var/lib/nfs ]]; then ++ mv /var/lib/nfs /var/lib/nfs.backup ++ if [ $? -ne 0 ]; then ++ ocf_log notice "mv /var/lib/nfs /var/lib/nfs.backup failed" ++ fi ++ ln -s ${OCF_RESKEY_ha_vol_mnt}/nfs-ganesha/${long_host}/nfs /var/lib/nfs ++ if [ $? -ne 0 ]; then ++ ocf_log notice "ln -s ${OCF_RESKEY_ha_vol_mnt}/nfs-ganesha/${long_host}/nfs /var/lib/nfs failed" ++ fi ++ fi ++ ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_nfsd_stop() ++{ ++ ++ if [ -L /var/lib/nfs -a -d /var/lib/nfs.backup ]; then ++ rm -f /var/lib/nfs ++ if [ $? -ne 0 ]; then ++ ocf_log notice "rm -f /var/lib/nfs failed" ++ fi ++ mv /var/lib/nfs.backup /var/lib/nfs ++ if [ $? -ne 0 ]; then ++ ocf_log notice "mv /var/lib/nfs.backup /var/lib/nfs failed" ++ fi ++ fi ++ ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_nfsd_monitor() ++{ ++ # pacemaker checks to see if RA is already running before starting it. ++ # if we return success, then it's presumed it's already running and ++ # doesn't need to be started, i.e. invoke the start action. ++ # return something other than success to make pacemaker invoke the ++ # start action ++ if [[ -L /var/lib/nfs ]]; then ++ return ${OCF_SUCCESS} ++ fi ++ return ${OCF_NOT_RUNNING} ++} ++ ++ganesha_nfsd_validate() ++{ ++ return ${OCF_SUCCESS} ++} ++ ++ganesha_nfsd_validate ++ ++# ocf_log notice "ganesha_nfsd ${OCF_RESOURCE_INSTANCE} $__OCF_ACTION" ++ ++# Translate each action into the appropriate function call ++case $__OCF_ACTION in ++start) ganesha_nfsd_start ++ ;; ++stop) ganesha_nfsd_stop ++ ;; ++status|monitor) ganesha_nfsd_monitor ++ ;; ++*) ganesha_nfsd_usage ++ exit ${OCF_ERR_UNIMPLEMENTED} ++ ;; ++esac ++ ++rc=$? ++ ++# The resource agent may optionally log a debug message ++ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned $rc" ++exit $rc ++ +diff --git a/extras/ganesha/scripts/Makefile.am b/extras/ganesha/scripts/Makefile.am +index 9ee8867..224ed26 100644 +--- a/extras/ganesha/scripts/Makefile.am ++++ b/extras/ganesha/scripts/Makefile.am +@@ -1,4 +1,6 @@ +-EXTRA_DIST= create-export-ganesha.sh generate-epoch.py dbus-send.sh ++EXTRA_DIST= ganesha-ha.sh dbus-send.sh create-export-ganesha.sh \ ++ generate-epoch.py + + scriptsdir = $(libexecdir)/ganesha +-scripts_SCRIPTS = create-export-ganesha.sh generate-epoch.py ++scripts_SCRIPTS = create-export-ganesha.sh dbus-send.sh ganesha-ha.sh \ ++ generate-epoch.py +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +new file mode 100644 +index 0000000..e4135ba +--- /dev/null ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -0,0 +1,1126 @@ ++#!/bin/bash ++ ++# Copyright 2015-2016 Red Hat Inc. All Rights Reserved ++# ++# Pacemaker+Corosync High Availability for NFS-Ganesha ++# ++# setup, teardown, add, delete, refresh-config, and status ++# ++# Each participating node in the cluster is assigned a virtual IP (VIP) ++# which fails over to another node when its associated ganesha.nfsd dies ++# for any reason. After the VIP is moved to another node all the ++# ganesha.nfsds are send a signal using DBUS to put them into NFS GRACE. ++# ++# There are six resource agent types used: ganesha_mon, ganesha_grace, ++# ganesha_nfsd, IPaddr, and Dummy. ganesha_mon is used to monitor the ++# ganesha.nfsd. ganesha_grace is used to send the DBUS signal to put ++# the remaining ganesha.nfsds into grace. ganesha_nfsd is used to start ++# and stop the ganesha.nfsd during setup and teardown. IPaddr manages ++# the VIP. A Dummy resource named $hostname-trigger_ip-1 is used to ++# ensure that the NFS GRACE DBUS signal is sent after the VIP moves to ++# the new host. ++ ++HA_NUM_SERVERS=0 ++HA_SERVERS="" ++HA_VOL_NAME="gluster_shared_storage" ++HA_VOL_MNT="/var/run/gluster/shared_storage" ++HA_CONFDIR=$HA_VOL_MNT"/nfs-ganesha" ++SERVICE_MAN="DISTRO_NOT_FOUND" ++ ++RHEL6_PCS_CNAME_OPTION="--name" ++SECRET_PEM="/var/lib/glusterd/nfs/secret.pem" ++ ++# UNBLOCK RA uses shared_storage which may become unavailable ++# during any of the nodes reboot. Hence increase timeout value. ++PORTBLOCK_UNBLOCK_TIMEOUT="60s" ++ ++# Try loading the config from any of the distro ++# specific configuration locations ++if [ -f /etc/sysconfig/ganesha ] ++ then ++ . /etc/sysconfig/ganesha ++fi ++if [ -f /etc/conf.d/ganesha ] ++ then ++ . /etc/conf.d/ganesha ++fi ++if [ -f /etc/default/ganesha ] ++ then ++ . /etc/default/ganesha ++fi ++ ++GANESHA_CONF= ++ ++function find_rhel7_conf ++{ ++ while [[ $# > 0 ]] ++ do ++ key="$1" ++ case $key in ++ -f) ++ CONFFILE="$2" ++ break; ++ ;; ++ *) ++ ;; ++ esac ++ shift ++ done ++} ++ ++if [ -z $CONFFILE ] ++ then ++ find_rhel7_conf $OPTIONS ++ ++fi ++ ++GANESHA_CONF=${CONFFILE:-/etc/ganesha/ganesha.conf} ++ ++usage() { ++ ++ echo "Usage : add|delete|refresh-config|status" ++ echo "Add-node : ganesha-ha.sh --add \ ++ " ++ echo "Delete-node: ganesha-ha.sh --delete \ ++" ++ echo "Refresh-config : ganesha-ha.sh --refresh-config \ ++" ++ echo "Status : ganesha-ha.sh --status " ++} ++ ++determine_service_manager () { ++ ++ if [ -e "/usr/bin/systemctl" ]; ++ then ++ SERVICE_MAN="/usr/bin/systemctl" ++ elif [ -e "/sbin/invoke-rc.d" ]; ++ then ++ SERVICE_MAN="/sbin/invoke-rc.d" ++ elif [ -e "/sbin/service" ]; ++ then ++ SERVICE_MAN="/sbin/service" ++ fi ++ if [ "$SERVICE_MAN" == "DISTRO_NOT_FOUND" ] ++ then ++ echo "Service manager not recognized, exiting" ++ exit 1 ++ fi ++} ++ ++manage_service () ++{ ++ local action=${1} ++ local new_node=${2} ++ local option= ++ ++ if [ "$action" == "start" ]; then ++ option="yes" ++ else ++ option="no" ++ fi ++ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ++${SECRET_PEM} root@${new_node} "/usr/libexec/ganesha/ganesha-ha.sh --setup-ganesha-conf-files $HA_CONFDIR $option" ++ ++ if [ "$SERVICE_MAN" == "/usr/bin/systemctl" ] ++ then ++ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ++${SECRET_PEM} root@${new_node} "$SERVICE_MAN ${action} nfs-ganesha" ++ else ++ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ++${SECRET_PEM} root@${new_node} "$SERVICE_MAN nfs-ganesha ${action}" ++ fi ++} ++ ++ ++check_cluster_exists() ++{ ++ local name=${1} ++ local cluster_name="" ++ ++ if [ -e /var/run/corosync.pid ]; then ++ cluster_name=$(pcs status | grep "Cluster name:" | cut -d ' ' -f 3) ++ if [ ${cluster_name} -a ${cluster_name} = ${name} ]; then ++ logger "$name already exists, exiting" ++ exit 0 ++ fi ++ fi ++} ++ ++ ++determine_servers() ++{ ++ local cmd=${1} ++ local num_servers=0 ++ local tmp_ifs=${IFS} ++ local ha_servers="" ++ ++ if [ "X${cmd}X" != "XsetupX" -a "X${cmd}X" != "XstatusX" ]; then ++ ha_servers=$(pcs status | grep "Online:" | grep -o '\[.*\]' | sed -e 's/\[//' | sed -e 's/\]//') ++ IFS=$' ' ++ for server in ${ha_servers} ; do ++ num_servers=$(expr ${num_servers} + 1) ++ done ++ IFS=${tmp_ifs} ++ HA_NUM_SERVERS=${num_servers} ++ HA_SERVERS="${ha_servers}" ++ else ++ IFS=$',' ++ for server in ${HA_CLUSTER_NODES} ; do ++ num_servers=$(expr ${num_servers} + 1) ++ done ++ IFS=${tmp_ifs} ++ HA_NUM_SERVERS=${num_servers} ++ HA_SERVERS="${HA_CLUSTER_NODES//,/ }" ++ fi ++} ++ ++ ++setup_cluster() ++{ ++ local name=${1} ++ local num_servers=${2} ++ local servers=${3} ++ local unclean="" ++ local quorum_policy="stop" ++ ++ logger "setting up cluster ${name} with the following ${servers}" ++ ++ pcs cluster auth ${servers} ++ # pcs cluster setup --name ${name} ${servers} ++ pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --transport udpu ${servers} ++ if [ $? -ne 0 ]; then ++ logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed" ++ exit 1; ++ fi ++ pcs cluster start --all ++ if [ $? -ne 0 ]; then ++ logger "pcs cluster start failed" ++ exit 1; ++ fi ++ ++ sleep 1 ++ # wait for the cluster to elect a DC before querying or writing ++ # to the CIB. BZ 1334092 ++ crmadmin --dc_lookup --timeout=5000 > /dev/null 2>&1 ++ while [ $? -ne 0 ]; do ++ crmadmin --dc_lookup --timeout=5000 > /dev/null 2>&1 ++ done ++ ++ unclean=$(pcs status | grep -u "UNCLEAN") ++ while [[ "${unclean}X" = "UNCLEANX" ]]; do ++ sleep 1 ++ unclean=$(pcs status | grep -u "UNCLEAN") ++ done ++ sleep 1 ++ ++ if [ ${num_servers} -lt 3 ]; then ++ quorum_policy="ignore" ++ fi ++ pcs property set no-quorum-policy=${quorum_policy} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs property set no-quorum-policy=${quorum_policy} failed" ++ fi ++ ++ pcs property set stonith-enabled=false ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs property set stonith-enabled=false failed" ++ fi ++} ++ ++ ++setup_finalize_ha() ++{ ++ local cibfile=${1} ++ local stopped="" ++ ++ stopped=$(pcs status | grep -u "Stopped") ++ while [[ "${stopped}X" = "StoppedX" ]]; do ++ sleep 1 ++ stopped=$(pcs status | grep -u "Stopped") ++ done ++} ++ ++ ++refresh_config () ++{ ++ local short_host=$(hostname -s) ++ local VOL=${1} ++ local HA_CONFDIR=${2} ++ local short_host=$(hostname -s) ++ ++ local export_id=$(grep ^[[:space:]]*Export_Id $HA_CONFDIR/exports/export.$VOL.conf |\ ++ awk -F"[=,;]" '{print $2}' | tr -d '[[:space:]]') ++ ++ ++ if [ -e ${SECRET_PEM} ]; then ++ while [[ ${3} ]]; do ++ current_host=`echo ${3} | cut -d "." -f 1` ++ if [ ${short_host} != ${current_host} ]; then ++ output=$(ssh -oPasswordAuthentication=no \ ++-oStrictHostKeyChecking=no -i ${SECRET_PEM} root@${current_host} \ ++"dbus-send --print-reply --system --dest=org.ganesha.nfsd \ ++/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.UpdateExport \ ++string:$HA_CONFDIR/exports/export.$VOL.conf \ ++string:\"EXPORT(Export_Id=$export_id)\" 2>&1") ++ ret=$? ++ logger <<< "${output}" ++ if [ ${ret} -ne 0 ]; then ++ echo "Error: refresh-config failed on ${current_host}." ++ exit 1 ++ else ++ echo "Refresh-config completed on ${current_host}." ++ fi ++ ++ fi ++ shift ++ done ++ else ++ echo "Error: refresh-config failed. Passwordless ssh is not enabled." ++ exit 1 ++ fi ++ ++ # Run the same command on the localhost, ++ output=$(dbus-send --print-reply --system --dest=org.ganesha.nfsd \ ++/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.UpdateExport \ ++string:$HA_CONFDIR/exports/export.$VOL.conf \ ++string:"EXPORT(Export_Id=$export_id)" 2>&1) ++ ret=$? ++ logger <<< "${output}" ++ if [ ${ret} -ne 0 ] ; then ++ echo "Error: refresh-config failed on localhost." ++ exit 1 ++ else ++ echo "Success: refresh-config completed." ++ fi ++} ++ ++ ++teardown_cluster() ++{ ++ local name=${1} ++ ++ for server in ${HA_SERVERS} ; do ++ if [[ ${HA_CLUSTER_NODES} != *${server}* ]]; then ++ logger "info: ${server} is not in config, removing" ++ ++ pcs cluster stop ${server} --force ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster stop ${server} failed" ++ fi ++ ++ pcs cluster node remove ${server} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster node remove ${server} failed" ++ fi ++ fi ++ done ++ ++ # BZ 1193433 - pcs doesn't reload cluster.conf after modification ++ # after teardown completes, a subsequent setup will appear to have ++ # 'remembered' the deleted node. You can work around this by ++ # issuing another `pcs cluster node remove $node`, ++ # `crm_node -f -R $server`, or ++ # `cibadmin --delete --xml-text '' ++ ++ pcs cluster stop --all ++ if [ $? -ne 0 ]; then ++ logger "warning pcs cluster stop --all failed" ++ fi ++ ++ pcs cluster destroy ++ if [ $? -ne 0 ]; then ++ logger "error pcs cluster destroy failed" ++ exit 1 ++ fi ++} ++ ++ ++cleanup_ganesha_config () ++{ ++ rm -f /etc/corosync/corosync.conf ++ rm -rf /etc/cluster/cluster.conf* ++ rm -rf /var/lib/pacemaker/cib/* ++} ++ ++do_create_virt_ip_constraints() ++{ ++ local cibfile=${1}; shift ++ local primary=${1}; shift ++ local weight="1000" ++ ++ # first a constraint location rule that says the VIP must be where ++ # there's a ganesha.nfsd running ++ pcs -f ${cibfile} constraint location ${primary}-group rule score=-INFINITY ganesha-active ne 1 ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs constraint location ${primary}-group rule score=-INFINITY ganesha-active ne 1 failed" ++ fi ++ ++ # then a set of constraint location prefers to set the prefered order ++ # for where a VIP should move ++ while [[ ${1} ]]; do ++ pcs -f ${cibfile} constraint location ${primary}-group prefers ${1}=${weight} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs constraint location ${primary}-group prefers ${1}=${weight} failed" ++ fi ++ weight=$(expr ${weight} + 1000) ++ shift ++ done ++ # and finally set the highest preference for the VIP to its home node ++ # default weight when created is/was 100. ++ # on Fedora setting appears to be additive, so to get the desired ++ # value we adjust the weight ++ # weight=$(expr ${weight} - 100) ++ pcs -f ${cibfile} constraint location ${primary}-group prefers ${primary}=${weight} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs constraint location ${primary}-group prefers ${primary}=${weight} failed" ++ fi ++} ++ ++ ++wrap_create_virt_ip_constraints() ++{ ++ local cibfile=${1}; shift ++ local primary=${1}; shift ++ local head="" ++ local tail="" ++ ++ # build a list of peers, e.g. for a four node cluster, for node1, ++ # the result is "node2 node3 node4"; for node2, "node3 node4 node1" ++ # and so on. ++ while [[ ${1} ]]; do ++ if [ "${1}" = "${primary}" ]; then ++ shift ++ while [[ ${1} ]]; do ++ tail=${tail}" "${1} ++ shift ++ done ++ else ++ head=${head}" "${1} ++ fi ++ shift ++ done ++ do_create_virt_ip_constraints ${cibfile} ${primary} ${tail} ${head} ++} ++ ++ ++create_virt_ip_constraints() ++{ ++ local cibfile=${1}; shift ++ ++ while [[ ${1} ]]; do ++ wrap_create_virt_ip_constraints ${cibfile} ${1} ${HA_SERVERS} ++ shift ++ done ++} ++ ++ ++setup_create_resources() ++{ ++ local cibfile=$(mktemp -u) ++ ++ # fixup /var/lib/nfs ++ logger "pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone" ++ pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone failed" ++ fi ++ ++ pcs resource create nfs-mon ocf:heartbeat:ganesha_mon --clone ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs resource create nfs-mon ocf:heartbeat:ganesha_mon --clone failed" ++ fi ++ ++ # see comment in (/usr/lib/ocf/resource.d/heartbeat/ganesha_grace ++ # start method. Allow time for ganesha_mon to start and set the ++ # ganesha-active crm_attribute ++ sleep 5 ++ ++ pcs resource create nfs-grace ocf:heartbeat:ganesha_grace --clone meta notify=true ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs resource create nfs-grace ocf:heartbeat:ganesha_grace --clone failed" ++ fi ++ ++ pcs constraint location nfs-grace-clone rule score=-INFINITY grace-active ne 1 ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs constraint location nfs-grace-clone rule score=-INFINITY grace-active ne 1" ++ fi ++ ++ pcs cluster cib ${cibfile} ++ ++ while [[ ${1} ]]; do ++ ++ # this is variable indirection ++ # from a nvs like 'VIP_host1=10.7.6.5' or 'VIP_host1="10.7.6.5"' ++ # (or VIP_host-1=..., or VIP_host-1.my.domain.name=...) ++ # a variable 'clean_name' is created (e.g. w/ value 'VIP_host_1') ++ # and a clean nvs (e.g. w/ value 'VIP_host_1="10_7_6_5"') ++ # after the `eval ${clean_nvs}` there is a variable VIP_host_1 ++ # with the value '10_7_6_5', and the following \$$ magic to ++ # reference it, i.e. `eval tmp_ipaddr=\$${clean_name}` gives us ++ # ${tmp_ipaddr} with 10_7_6_5 and then convert the _s back to .s ++ # to give us ipaddr="10.7.6.5". whew! ++ name="VIP_${1}" ++ clean_name=${name//[-.]/_} ++ nvs=$(grep "^${name}=" ${HA_CONFDIR}/ganesha-ha.conf) ++ clean_nvs=${nvs//[-.]/_} ++ eval ${clean_nvs} ++ eval tmp_ipaddr=\$${clean_name} ++ ipaddr=${tmp_ipaddr//_/.} ++ ++ pcs -f ${cibfile} resource create ${1}-nfs_block ocf:heartbeat:portblock protocol=tcp \ ++ portno=2049 action=block ip=${ipaddr} --group ${1}-group ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${1}-nfs_block failed" ++ fi ++ pcs -f ${cibfile} resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \ ++ cidr_netmask=32 op monitor interval=15s --group ${1}-group --after ${1}-nfs_block ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \ ++ cidr_netmask=32 op monitor interval=15s failed" ++ fi ++ ++ pcs -f ${cibfile} constraint order nfs-grace-clone then ${1}-cluster_ip-1 ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs constraint order nfs-grace-clone then ${1}-cluster_ip-1 failed" ++ fi ++ ++ pcs -f ${cibfile} resource create ${1}-nfs_unblock ocf:heartbeat:portblock protocol=tcp \ ++ portno=2049 action=unblock ip=${ipaddr} reset_local_on_unblock_stop=true \ ++ tickle_dir=${HA_VOL_MNT}/nfs-ganesha/tickle_dir/ --group ${1}-group --after ${1}-cluster_ip-1 \ ++ op stop timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op start timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} \ ++ op monitor interval=10s timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${1}-nfs_unblock failed" ++ fi ++ ++ ++ shift ++ done ++ ++ create_virt_ip_constraints ${cibfile} ${HA_SERVERS} ++ ++ pcs cluster cib-push ${cibfile} ++ if [ $? -ne 0 ]; then ++ logger "warning pcs cluster cib-push ${cibfile} failed" ++ fi ++ rm -f ${cibfile} ++} ++ ++ ++teardown_resources() ++{ ++ # local mntpt=$(grep ha-vol-mnt ${HA_CONFIG_FILE} | cut -d = -f 2) ++ ++ # restore /var/lib/nfs ++ logger "notice: pcs resource delete nfs_setup-clone" ++ pcs resource delete nfs_setup-clone ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs resource delete nfs_setup-clone failed" ++ fi ++ ++ # delete -clone resource agents ++ # in particular delete the ganesha monitor so we don't try to ++ # trigger anything when we shut down ganesha next. ++ pcs resource delete nfs-mon-clone ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs resource delete nfs-mon-clone failed" ++ fi ++ ++ pcs resource delete nfs-grace-clone ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs resource delete nfs-grace-clone failed" ++ fi ++ ++ while [[ ${1} ]]; do ++ pcs resource delete ${1}-group ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs resource delete ${1}-group failed" ++ fi ++ shift ++ done ++ ++} ++ ++ ++recreate_resources() ++{ ++ local cibfile=${1}; shift ++ ++ while [[ ${1} ]]; do ++ # this is variable indirection ++ # see the comment on the same a few lines up ++ name="VIP_${1}" ++ clean_name=${name//[-.]/_} ++ nvs=$(grep "^${name}=" ${HA_CONFDIR}/ganesha-ha.conf) ++ clean_nvs=${nvs//[-.]/_} ++ eval ${clean_nvs} ++ eval tmp_ipaddr=\$${clean_name} ++ ipaddr=${tmp_ipaddr//_/.} ++ ++ pcs -f ${cibfile} resource create ${1}-nfs_block ocf:heartbeat:portblock protocol=tcp \ ++ portno=2049 action=block ip=${ipaddr} --group ${1}-group ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${1}-nfs_block failed" ++ fi ++ pcs -f ${cibfile} resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \ ++ cidr_netmask=32 op monitor interval=15s --group ${1}-group --after ${1}-nfs_block ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \ ++ cidr_netmask=32 op monitor interval=15s failed" ++ fi ++ ++ pcs -f ${cibfile} constraint order nfs-grace-clone then ${1}-cluster_ip-1 ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs constraint order nfs-grace-clone then ${1}-cluster_ip-1 failed" ++ fi ++ ++ pcs -f ${cibfile} resource create ${1}-nfs_unblock ocf:heartbeat:portblock protocol=tcp \ ++ portno=2049 action=unblock ip=${ipaddr} reset_local_on_unblock_stop=true \ ++ tickle_dir=${HA_VOL_MNT}/nfs-ganesha/tickle_dir/ --group ${1}-group --after ${1}-cluster_ip-1 \ ++ op stop timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op start timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} \ ++ op monitor interval=10s timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${1}-nfs_unblock failed" ++ fi ++ ++ shift ++ done ++} ++ ++ ++addnode_recreate_resources() ++{ ++ local cibfile=${1}; shift ++ local add_node=${1}; shift ++ local add_vip=${1}; shift ++ ++ recreate_resources ${cibfile} ${HA_SERVERS} ++ ++ pcs -f ${cibfile} resource create ${add_node}-nfs_block ocf:heartbeat:portblock \ ++ protocol=tcp portno=2049 action=block ip=${add_vip} --group ${add_node}-group ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${add_node}-nfs_block failed" ++ fi ++ pcs -f ${cibfile} resource create ${add_node}-cluster_ip-1 ocf:heartbeat:IPaddr \ ++ ip=${add_vip} cidr_netmask=32 op monitor interval=15s --group ${add_node}-group \ ++ --after ${add_node}-nfs_block ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${add_node}-cluster_ip-1 ocf:heartbeat:IPaddr \ ++ ip=${add_vip} cidr_netmask=32 op monitor interval=15s failed" ++ fi ++ ++ pcs -f ${cibfile} constraint order nfs-grace-clone then ${add_node}-cluster_ip-1 ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs constraint order nfs-grace-clone then ${add_node}-cluster_ip-1 failed" ++ fi ++ pcs -f ${cibfile} resource create ${add_node}-nfs_unblock ocf:heartbeat:portblock \ ++ protocol=tcp portno=2049 action=unblock ip=${add_vip} reset_local_on_unblock_stop=true \ ++ tickle_dir=${HA_VOL_MNT}/nfs-ganesha/tickle_dir/ --group ${add_node}-group --after \ ++ ${add_node}-cluster_ip-1 op stop timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op start \ ++ timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op monitor interval=10s \ ++ timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} ++ if [ $? -ne 0 ]; then ++ logger "warning pcs resource create ${add_node}-nfs_unblock failed" ++ fi ++} ++ ++ ++clear_resources() ++{ ++ local cibfile=${1}; shift ++ ++ while [[ ${1} ]]; do ++ pcs -f ${cibfile} resource delete ${1}-group ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs -f ${cibfile} resource delete ${1}-group" ++ fi ++ ++ shift ++ done ++} ++ ++ ++addnode_create_resources() ++{ ++ local add_node=${1}; shift ++ local add_vip=${1}; shift ++ local cibfile=$(mktemp -u) ++ ++ # start HA on the new node ++ pcs cluster start ${add_node} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster start ${add_node} failed" ++ fi ++ ++ pcs cluster cib ${cibfile} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster cib ${cibfile} failed" ++ fi ++ ++ # delete all the -cluster_ip-1 resources, clearing ++ # their constraints, then create them again so we can ++ # recompute their constraints ++ clear_resources ${cibfile} ${HA_SERVERS} ++ addnode_recreate_resources ${cibfile} ${add_node} ${add_vip} ++ ++ HA_SERVERS="${HA_SERVERS} ${add_node}" ++ create_virt_ip_constraints ${cibfile} ${HA_SERVERS} ++ ++ pcs cluster cib-push ${cibfile} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster cib-push ${cibfile} failed" ++ fi ++ rm -f ${cibfile} ++} ++ ++ ++deletenode_delete_resources() ++{ ++ local node=${1}; shift ++ local ha_servers=$(echo "${HA_SERVERS}" | sed s/${node}//) ++ local cibfile=$(mktemp -u) ++ ++ pcs cluster cib ${cibfile} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster cib ${cibfile} failed" ++ fi ++ ++ # delete all the -cluster_ip-1 and -trigger_ip-1 resources, ++ # clearing their constraints, then create them again so we can ++ # recompute their constraints ++ clear_resources ${cibfile} ${HA_SERVERS} ++ recreate_resources ${cibfile} ${ha_servers} ++ HA_SERVERS=$(echo "${ha_servers}" | sed -e "s/ / /") ++ ++ create_virt_ip_constraints ${cibfile} ${HA_SERVERS} ++ ++ pcs cluster cib-push ${cibfile} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster cib-push ${cibfile} failed" ++ fi ++ rm -f ${cibfile} ++ ++} ++ ++ ++deletenode_update_haconfig() ++{ ++ local name="VIP_${1}" ++ local clean_name=${name//[-.]/_} ++ ++ ha_servers=$(echo ${HA_SERVERS} | sed -e "s/ /,/") ++ sed -i -e "s/^HA_CLUSTER_NODES=.*$/HA_CLUSTER_NODES=\"${ha_servers// /,}\"/" -e "s/^${name}=.*$//" -e "/^$/d" ${HA_CONFDIR}/ganesha-ha.conf ++} ++ ++ ++setup_state_volume() ++{ ++ local mnt=${HA_VOL_MNT} ++ local longname="" ++ local shortname="" ++ local dname="" ++ local dirname="" ++ ++ longname=$(hostname) ++ dname=${longname#$(hostname -s)} ++ ++ while [[ ${1} ]]; do ++ ++ if [[ ${1} == *${dname} ]]; then ++ dirname=${1} ++ else ++ dirname=${1}${dname} ++ fi ++ ++ if [ ! -d ${mnt}/nfs-ganesha/tickle_dir ]; then ++ mkdir ${mnt}/nfs-ganesha/tickle_dir ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname} ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname} ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd ++ fi ++ if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/state ]; then ++ touch ${mnt}/nfs-ganesha/${dirname}/nfs/state ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4old ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4old ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak ++ fi ++ if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state ]; then ++ touch ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state ++ fi ++ for server in ${HA_SERVERS} ; do ++ if [ ${server} != ${dirname} ]; then ++ ln -s ${mnt}/nfs-ganesha/${server}/nfs/ganesha ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/${server} ++ ln -s ${mnt}/nfs-ganesha/${server}/nfs/statd ${mnt}/nfs-ganesha/${dirname}/nfs/statd/${server} ++ fi ++ done ++ shift ++ done ++ ++} ++ ++ ++addnode_state_volume() ++{ ++ local newnode=${1}; shift ++ local mnt=${HA_VOL_MNT} ++ local longname="" ++ local dname="" ++ local dirname="" ++ ++ longname=$(hostname) ++ dname=${longname#$(hostname -s)} ++ ++ if [[ ${newnode} == *${dname} ]]; then ++ dirname=${newnode} ++ else ++ dirname=${newnode}${dname} ++ fi ++ ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname} ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname} ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd ++ fi ++ if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/state ]; then ++ touch ${mnt}/nfs-ganesha/${dirname}/nfs/state ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4old ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4old ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm ++ fi ++ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak ]; then ++ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak ++ fi ++ if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state ]; then ++ touch ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state ++ fi ++ ++ for server in ${HA_SERVERS} ; do ++ ++ if [[ ${server} != ${dirname} ]]; then ++ ln -s ${mnt}/nfs-ganesha/${server}/nfs/ganesha ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/${server} ++ ln -s ${mnt}/nfs-ganesha/${server}/nfs/statd ${mnt}/nfs-ganesha/${dirname}/nfs/statd/${server} ++ ++ ln -s ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha ${mnt}/nfs-ganesha/${server}/nfs/ganesha/${dirname} ++ ln -s ${mnt}/nfs-ganesha/${dirname}/nfs/statd ${mnt}/nfs-ganesha/${server}/nfs/statd/${dirname} ++ fi ++ done ++ ++} ++ ++ ++delnode_state_volume() ++{ ++ local delnode=${1}; shift ++ local mnt=${HA_VOL_MNT} ++ local longname="" ++ local dname="" ++ local dirname="" ++ ++ longname=$(hostname) ++ dname=${longname#$(hostname -s)} ++ ++ if [[ ${delnode} == *${dname} ]]; then ++ dirname=${delnode} ++ else ++ dirname=${delnode}${dname} ++ fi ++ ++ rm -rf ${mnt}/nfs-ganesha/${dirname} ++ ++ for server in ${HA_SERVERS} ; do ++ if [[ "${server}" != "${dirname}" ]]; then ++ rm -f ${mnt}/nfs-ganesha/${server}/nfs/ganesha/${dirname} ++ rm -f ${mnt}/nfs-ganesha/${server}/nfs/statd/${dirname} ++ fi ++ done ++} ++ ++ ++status() ++{ ++ local scratch=$(mktemp) ++ local regex_str="^${1}-cluster_ip-1" ++ local healthy=0 ++ local index=1 ++ local nodes ++ ++ # change tabs to spaces, strip leading spaces ++ pcs status | sed -e "s/\t/ /g" -e "s/^[ ]*//" > ${scratch} ++ ++ nodes[0]=${1}; shift ++ ++ # make a regex of the configured nodes ++ # and initalize the nodes array for later ++ while [[ ${1} ]]; do ++ ++ regex_str="${regex_str}|^${1}-cluster_ip-1" ++ nodes[${index}]=${1} ++ ((index++)) ++ shift ++ done ++ ++ # print the nodes that are expected to be online ++ grep -E "^Online:" ${scratch} ++ ++ echo ++ ++ # print the VIPs and which node they are on ++ grep -E "${regex_str}" < ${scratch} | cut -d ' ' -f 1,4 ++ ++ echo ++ ++ # check if the VIP and port block/unblock RAs are on the expected nodes ++ for n in ${nodes[*]}; do ++ ++ grep -E -x "${n}-nfs_block \(ocf::heartbeat:portblock\): Started ${n}" > /dev/null 2>&1 ${scratch} ++ result=$? ++ ((healthy+=${result})) ++ grep -E -x "${n}-cluster_ip-1 \(ocf::heartbeat:IPaddr\): Started ${n}" > /dev/null 2>&1 ${scratch} ++ result=$? ++ ((healthy+=${result})) ++ grep -E -x "${n}-nfs_unblock \(ocf::heartbeat:portblock\): Started ${n}" > /dev/null 2>&1 ${scratch} ++ result=$? ++ ((healthy+=${result})) ++ done ++ ++ grep -E "\):\ Stopped|FAILED" > /dev/null 2>&1 ${scratch} ++ result=$? ++ ++ if [ ${result} -eq 0 ]; then ++ echo "Cluster HA Status: BAD" ++ elif [ ${healthy} -eq 0 ]; then ++ echo "Cluster HA Status: HEALTHY" ++ else ++ echo "Cluster HA Status: FAILOVER" ++ fi ++ ++ rm -f ${scratch} ++} ++ ++create_ganesha_conf_file() ++{ ++ if [ $1 == "yes" ]; ++ then ++ if [ -e $GANESHA_CONF ]; ++ then ++ rm -rf $GANESHA_CONF ++ fi ++ # The symlink /etc/ganesha/ganesha.conf need to be ++ # created using ganesha conf file mentioned in the ++ # shared storage. Every node will only have this ++ # link and actual file will stored in shared storage, ++ # so that ganesha conf editing of ganesha conf will ++ # be easy as well as it become more consistent. ++ ++ ln -s $HA_CONFDIR/ganesha.conf $GANESHA_CONF ++ else ++ # Restoring previous file ++ rm -rf $GANESHA_CONF ++ cp $HA_CONFDIR/ganesha.conf $GANESHA_CONF ++ sed -r -i -e '/^%include[[:space:]]+".+\.conf"$/d' $GANESHA_CONF ++ fi ++} ++ ++set_quorum_policy() ++{ ++ local quorum_policy="stop" ++ local num_servers=${1} ++ ++ if [ ${num_servers} -lt 3 ]; then ++ quorum_policy="ignore" ++ fi ++ pcs property set no-quorum-policy=${quorum_policy} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs property set no-quorum-policy=${quorum_policy} failed" ++ fi ++} ++ ++main() ++{ ++ ++ local cmd=${1}; shift ++ if [[ ${cmd} == *help ]]; then ++ usage ++ exit 0 ++ fi ++ HA_CONFDIR=${1%/}; shift ++ local ha_conf=${HA_CONFDIR}/ganesha-ha.conf ++ local node="" ++ local vip="" ++ ++ # ignore any comment lines ++ cfgline=$(grep ^HA_NAME= ${ha_conf}) ++ eval $(echo ${cfgline} | grep -F HA_NAME=) ++ cfgline=$(grep ^HA_CLUSTER_NODES= ${ha_conf}) ++ eval $(echo ${cfgline} | grep -F HA_CLUSTER_NODES=) ++ ++ case "${cmd}" in ++ ++ setup | --setup) ++ logger "setting up ${HA_NAME}" ++ ++ check_cluster_exists ${HA_NAME} ++ ++ determine_servers "setup" ++ ++ if [ "X${HA_NUM_SERVERS}X" != "X1X" ]; then ++ ++ setup_cluster ${HA_NAME} ${HA_NUM_SERVERS} "${HA_SERVERS}" ++ ++ setup_create_resources ${HA_SERVERS} ++ ++ setup_finalize_ha ++ ++ setup_state_volume ${HA_SERVERS} ++ ++ else ++ ++ logger "insufficient servers for HA, aborting" ++ fi ++ ;; ++ ++ teardown | --teardown) ++ logger "tearing down ${HA_NAME}" ++ ++ determine_servers "teardown" ++ ++ teardown_resources ${HA_SERVERS} ++ ++ teardown_cluster ${HA_NAME} ++ ++ cleanup_ganesha_config ${HA_CONFDIR} ++ ;; ++ ++ cleanup | --cleanup) ++ cleanup_ganesha_config ${HA_CONFDIR} ++ ;; ++ ++ add | --add) ++ node=${1}; shift ++ vip=${1}; shift ++ ++ logger "adding ${node} with ${vip} to ${HA_NAME}" ++ ++ determine_service_manager ++ ++ manage_service "start" ${node} ++ ++ determine_servers "add" ++ ++ pcs cluster node add ${node} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster node add ${node} failed" ++ fi ++ ++ addnode_create_resources ${node} ${vip} ++ # Subsequent add-node recreates resources for all the nodes ++ # that already exist in the cluster. The nodes are picked up ++ # from the entries in the ganesha-ha.conf file. Adding the ++ # newly added node to the file so that the resources specfic ++ # to this node is correctly recreated in the future. ++ clean_node=${node//[-.]/_} ++ echo "VIP_${node}=\"${vip}\"" >> ${HA_CONFDIR}/ganesha-ha.conf ++ ++ NEW_NODES="$HA_CLUSTER_NODES,${node}" ++ ++ sed -i s/HA_CLUSTER_NODES.*/"HA_CLUSTER_NODES=\"$NEW_NODES\""/ \ ++$HA_CONFDIR/ganesha-ha.conf ++ ++ addnode_state_volume ${node} ++ ++ # addnode_create_resources() already appended ${node} to ++ # HA_SERVERS, so only need to increment HA_NUM_SERVERS ++ # and set quorum policy ++ HA_NUM_SERVERS=$(expr ${HA_NUM_SERVERS} + 1) ++ set_quorum_policy ${HA_NUM_SERVERS} ++ ;; ++ ++ delete | --delete) ++ node=${1}; shift ++ ++ logger "deleting ${node} from ${HA_NAME}" ++ ++ determine_servers "delete" ++ ++ deletenode_delete_resources ${node} ++ ++ pcs cluster node remove ${node} ++ if [ $? -ne 0 ]; then ++ logger "warning: pcs cluster node remove ${node} failed" ++ fi ++ ++ deletenode_update_haconfig ${node} ++ ++ delnode_state_volume ${node} ++ ++ determine_service_manager ++ ++ manage_service "stop" ${node} ++ ++ HA_NUM_SERVERS=$(expr ${HA_NUM_SERVERS} - 1) ++ set_quorum_policy ${HA_NUM_SERVERS} ++ ;; ++ ++ status | --status) ++ determine_servers "status" ++ ++ status ${HA_SERVERS} ++ ;; ++ ++ refresh-config | --refresh-config) ++ VOL=${1} ++ ++ determine_servers "refresh-config" ++ ++ refresh_config ${VOL} ${HA_CONFDIR} ${HA_SERVERS} ++ ;; ++ ++ setup-ganesha-conf-files | --setup-ganesha-conf-files) ++ ++ create_ganesha_conf_file ${1} ++ ;; ++ ++ *) ++ # setup and teardown are not intended to be used by a ++ # casual user ++ usage ++ logger "Usage: ganesha-ha.sh add|delete|status" ++ ;; ++ ++ esac ++} ++ ++main $* ++ +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 6e710e5..0bad6cf 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -405,7 +405,8 @@ Summary: NFS-Ganesha configuration + Group: Applications/File + + Requires: %{name}-server%{?_isa} = %{version}-%{release} +-Requires: nfs-ganesha-gluster, pcs, dbus ++Requires: nfs-ganesha-gluster >= 2.4.1 ++Requires: pcs, dbus + %if ( 0%{?rhel} && 0%{?rhel} == 6 ) + Requires: cman, pacemaker, corosync + %endif +@@ -1276,6 +1277,7 @@ exit 0 + %files ganesha + %{_sysconfdir}/ganesha/* + %{_libexecdir}/ganesha/* ++%{_prefix}/lib/ocf/resource.d/heartbeat/* + %{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh + %endif + +-- +1.8.3.1 + diff --git a/SOURCES/0051-quota-add-quota-events.patch b/SOURCES/0051-quota-add-quota-events.patch deleted file mode 100644 index 1984a40..0000000 --- a/SOURCES/0051-quota-add-quota-events.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 22b65c30c5eca015bb5aabf0a0d1d2c4aba21daa Mon Sep 17 00:00:00 2001 -From: Muthu-vigneshwaran -Date: Mon, 22 Aug 2016 16:53:59 +0530 -Subject: [PATCH 51/86] quota: add quota events - -The patch targets to capture quota related events which are -important to be notified. - ->Reviewed-on: http://review.gluster.org/15235 ->Smoke: Gluster Build System ->Tested-by: Manikandan Selvaganesh ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Manikandan Selvaganesh ->Reviewed-by: Raghavendra G - -Change-Id: Iba440d675b11c346faab4c23260899d05296d8a7 -BUG: 1361078 -Signed-off-by: Muthu-vigneshwaran -Reviewed-on: https://code.engineering.redhat.com/gerrit/84798 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - events/eventskeygen.py | 2 +- - xlators/features/quota/src/quota.c | 10 ++++++++++ - 2 files changed, 11 insertions(+), 1 deletions(-) - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 144c554..a118a4c 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -90,7 +90,7 @@ keys = ( - "EVENT_QUOTA_SOFT_TIMEOUT", - "EVENT_QUOTA_HARD_TIMEOUT", - "EVENT_QUOTA_DEFAULT_SOFT_LIMIT", -- -+ "EVENT_QUOTA_CROSSED_SOFT_LIMIT", - ) - - LAST_EVENT = "EVENT_LAST" -diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c -index dd7bf80..50eaa1f 100644 ---- a/xlators/features/quota/src/quota.c -+++ b/xlators/features/quota/src/quota.c -@@ -15,6 +15,7 @@ - #include "statedump.h" - #include "quota-common-utils.h" - #include "quota-messages.h" -+#include "events.h" - - struct volume_options options[]; - -@@ -5008,7 +5009,12 @@ quota_log_usage (xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode, - gf_msg (this->name, GF_LOG_ALERT, 0, - Q_MSG_CROSSED_SOFT_LIMIT, "Usage crossed soft limit: " - "%s used by %s", usage_str, path); -+ -+ gf_event (EVENT_QUOTA_CROSSED_SOFT_LIMIT, "Usage=%s;volume=%s;" -+ "path=%s", usage_str, priv->volume_uuid, path); -+ - ctx->prev_log = cur_time; -+ - } - /* Usage is above soft limit */ - else if (cur_size > ctx->soft_lim && -@@ -5020,6 +5026,10 @@ quota_log_usage (xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode, - gf_msg (this->name, GF_LOG_ALERT, 0, Q_MSG_CROSSED_SOFT_LIMIT, - "Usage is above soft limit: %s used by %s", - usage_str, path); -+ -+ gf_event (EVENT_QUOTA_CROSSED_SOFT_LIMIT, "Usage=%s;volume=%s;" -+ "path=%s", usage_str, priv->volume_uuid, path); -+ - ctx->prev_log = cur_time; - } - --- -1.7.1 - diff --git a/SOURCES/0052-common-ha-fixes-for-Debian-based-systems.patch b/SOURCES/0052-common-ha-fixes-for-Debian-based-systems.patch new file mode 100644 index 0000000..914204d --- /dev/null +++ b/SOURCES/0052-common-ha-fixes-for-Debian-based-systems.patch @@ -0,0 +1,235 @@ +From a4d7f6c1999f2c7837aaa674177edca9298d1c00 Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Fri, 7 Apr 2017 09:09:29 -0400 +Subject: [PATCH 52/74] common-ha: fixes for Debian-based systems + +1) Debian-based systems don't have /usr/libexec/... and there is +a hard-coded invocation of /usr/libexec/ganesha/ganesha-ha.sh within +ganesha-ha.sh itself. +Fix: save $0 and use it instead for further invocations of self. + +2) default shell is /bin/dash (not /bin/bash). Various runner_run() +invocations for ganesha used what amounts to + exec("sh /usr/$libexec/ganesha/ganesha-ha.sh ...); +which executes the script using the default shell, but there are +some bash-specific idioms that don't work if the shell is dash. +Fix: change to exec("/usr/$libexec/ganesha/ganesha-ha.sh ...); so that +the shebang forces the use of /bin/bash + +3) Fedora and RHEL7 have merged /bin/ and /usr/bin, /bin is a symlink +to /usr/bin. Debian-based systems are not merged, and systemd systems +have /bin/systemctl. The logic to find .../bin/systemctl is backwards. +If the logic looks for /usr/bin/systemctl it will not find it on +Debian-based systems; if it looks for /bin/systemctl it will find it +on Fedora and RHEL by virtue of the symlink. (RHEL6 and others will +find their respective init regardless.) +Fix: change the logic to look for /bin/systemctl instead. + +4) The logic for deciding to run systemctl (or not) is a bit silly. +Fix: simply invoke the found method via the function pointer in the +table. + +Change-Id: I33681b296a73aebb078bda6ac0d3a1d3b9770a21 +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://review.gluster.org/17013 +Smoke: Gluster Build System +Reviewed-by: Niels de Vos +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: jiffin tony Thottan +--- + extras/ganesha/scripts/ganesha-ha.sh | 21 ++++++------- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 44 +++++++++++++--------------- + 2 files changed, 32 insertions(+), 33 deletions(-) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index e4135ba..d4844e4 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -20,6 +20,7 @@ + # ensure that the NFS GRACE DBUS signal is sent after the VIP moves to + # the new host. + ++GANESHA_HA_SH=$(realpath $0) + HA_NUM_SERVERS=0 + HA_SERVERS="" + HA_VOL_NAME="gluster_shared_storage" +@@ -68,9 +69,9 @@ function find_rhel7_conf + done + } + +-if [ -z $CONFFILE ] ++if [ -z ${CONFFILE} ] + then +- find_rhel7_conf $OPTIONS ++ find_rhel7_conf ${OPTIONS} + + fi + +@@ -90,9 +91,9 @@ usage() { + + determine_service_manager () { + +- if [ -e "/usr/bin/systemctl" ]; ++ if [ -e "/bin/systemctl" ]; + then +- SERVICE_MAN="/usr/bin/systemctl" ++ SERVICE_MAN="/bin/systemctl" + elif [ -e "/sbin/invoke-rc.d" ]; + then + SERVICE_MAN="/sbin/invoke-rc.d" +@@ -100,7 +101,7 @@ determine_service_manager () { + then + SERVICE_MAN="/sbin/service" + fi +- if [ "$SERVICE_MAN" == "DISTRO_NOT_FOUND" ] ++ if [ "${SERVICE_MAN}" == "DISTRO_NOT_FOUND" ] + then + echo "Service manager not recognized, exiting" + exit 1 +@@ -113,21 +114,21 @@ manage_service () + local new_node=${2} + local option= + +- if [ "$action" == "start" ]; then ++ if [ "${action}" == "start" ]; then + option="yes" + else + option="no" + fi + ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ +-${SECRET_PEM} root@${new_node} "/usr/libexec/ganesha/ganesha-ha.sh --setup-ganesha-conf-files $HA_CONFDIR $option" ++${SECRET_PEM} root@${new_node} "${GANESHA_HA_SH} --setup-ganesha-conf-files $HA_CONFDIR $option" + +- if [ "$SERVICE_MAN" == "/usr/bin/systemctl" ] ++ if [ "${SERVICE_MAN}" == "/bin/systemctl" ] + then + ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ +-${SECRET_PEM} root@${new_node} "$SERVICE_MAN ${action} nfs-ganesha" ++${SECRET_PEM} root@${new_node} "${SERVICE_MAN} ${action} nfs-ganesha" + else + ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ +-${SECRET_PEM} root@${new_node} "$SERVICE_MAN nfs-ganesha ${action}" ++${SECRET_PEM} root@${new_node} "${SERVICE_MAN} nfs-ganesha ${action}" + fi + } + +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index 4346bad..c16dd72 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -119,11 +119,10 @@ sc_service_action (struct service_command *sc, char *command) + static int + manage_service (char *action) + { +- struct stat stbuf = {0,}; + int i = 0; + int ret = 0; + struct service_command sc_list[] = { +- { .binary = "/usr/bin/systemctl", ++ { .binary = "/bin/systemctl", + .service = "nfs-ganesha", + .action = sc_systemctl_action + }, +@@ -140,16 +139,11 @@ manage_service (char *action) + }; + + while (sc_list[i].binary != NULL) { +- ret = sys_stat (sc_list[i].binary, &stbuf); ++ ret = sys_access (sc_list[i].binary, X_OK); + if (ret == 0) { + gf_msg_debug (THIS->name, 0, +- "%s found.", sc_list[i].binary); +- if (strcmp (sc_list[i].binary, "/usr/bin/systemctl") == 0) +- ret = sc_systemctl_action (&sc_list[i], action); +- else +- ret = sc_service_action (&sc_list[i], action); +- +- return ret; ++ "%s found.", sc_list[i].binary); ++ return sc_list[i].action (&sc_list[i], action); + } + i++; + } +@@ -465,9 +459,9 @@ manage_export_config (char *volname, char *value, char **op_errstr) + + GF_ASSERT(volname); + runinit (&runner); +- runner_add_args (&runner, "sh", +- GANESHA_PREFIX"/create-export-ganesha.sh", +- CONFDIR, value, volname, NULL); ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/create-export-ganesha.sh", ++ CONFDIR, value, volname, NULL); + ret = runner_run(&runner); + + if (ret) +@@ -570,8 +564,9 @@ ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) + } + + if (check_host_list()) { +- runner_add_args (&runner, "sh", GANESHA_PREFIX"/dbus-send.sh", +- CONFDIR, value, volname, NULL); ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/dbus-send.sh", ++ CONFDIR, value, volname, NULL); + ret = runner_run (&runner); + if (ret) { + gf_asprintf(op_errstr, "Dynamic export" +@@ -610,9 +605,9 @@ tear_down_cluster(gf_boolean_t run_teardown) + + if (run_teardown) { + runinit (&runner); +- runner_add_args (&runner, "sh", +- GANESHA_PREFIX"/ganesha-ha.sh", "teardown", +- CONFDIR, NULL); ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/ganesha-ha.sh", "teardown", ++ CONFDIR, NULL); + ret = runner_run(&runner); + /* * + * Remove all the entries in CONFDIR expect ganesha.conf and +@@ -675,7 +670,8 @@ setup_cluster(gf_boolean_t run_setup) + + if (run_setup) { + runinit (&runner); +- runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/ganesha-ha.sh", + "setup", CONFDIR, NULL); + ret = runner_run (&runner); + } +@@ -702,8 +698,9 @@ teardown (gf_boolean_t run_teardown, char **op_errstr) + } + + runinit (&runner); +- runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", +- "cleanup", CONFDIR, NULL); ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/ganesha-ha.sh", ++ "cleanup", CONFDIR, NULL); + ret = runner_run (&runner); + if (ret) + gf_msg_debug (THIS->name, 0, "Could not clean up" +@@ -747,7 +744,8 @@ stop_ganesha (char **op_errstr) { + runner_t runner = {0,}; + + runinit (&runner); +- runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/ganesha-ha.sh", + "--setup-ganesha-conf-files", CONFDIR, "no", NULL); + ret = runner_run (&runner); + if (ret) { +@@ -810,7 +808,7 @@ start_ganesha (char **op_errstr) + + if (check_host_list()) { + runinit (&runner); +- runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", ++ runner_add_args (&runner, GANESHA_PREFIX"/ganesha-ha.sh", + "--setup-ganesha-conf-files", CONFDIR, "yes", + NULL); + ret = runner_run (&runner); +-- +1.8.3.1 + diff --git a/SOURCES/0052-eventsapi-declare-all-the-identified-events-at-one-g.patch b/SOURCES/0052-eventsapi-declare-all-the-identified-events-at-one-g.patch deleted file mode 100644 index 515271c..0000000 --- a/SOURCES/0052-eventsapi-declare-all-the-identified-events-at-one-g.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 53a8ae976e7886dcfeea151b8a3a045863b7f018 Mon Sep 17 00:00:00 2001 -From: Atin Mukherjee -Date: Tue, 30 Aug 2016 18:05:11 +0530 -Subject: [PATCH 52/86] eventsapi: declare all the identified events at one go - -This patch ensures we don't get into merge conflicts -everytime a single eventing patch is merged which -changes eventskeygen.py. I've collected all the identified -events from the patches posted in gerrit for reviews and -consolidated at one place. - ->Reviewed-on: http://review.gluster.org/15351 ->Tested-by: Prasanna Kumar Kalever ->Reviewed-by: Avra Sengupta ->Smoke: Gluster Build System ->Reviewed-by: Aravinda VK ->Reviewed-by: Saravanakumar Arumugam ->CentOS-regression: Gluster Build System ->NetBSD-regression: NetBSD Build System - -Change-Id: I5a5983d5c8db7c4a223fa02b4f99ec41c6fa9c35 -BUG: 1351589 -Signed-off-by: Atin Mukherjee -Reviewed-on: https://code.engineering.redhat.com/gerrit/84800 ---- - events/eventskeygen.py | 94 ++++++++++++++++++++++++++++++++++++++--------- - 1 files changed, 76 insertions(+), 18 deletions(-) - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index a118a4c..2869e45 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -21,16 +21,20 @@ gen_header_type = sys.argv[1] - - # When adding new keys add it to the END - keys = ( -+ # user driven events -+ #peer and volume managment events - "EVENT_PEER_ATTACH", - "EVENT_PEER_DETACH", -- - "EVENT_VOLUME_CREATE", - "EVENT_VOLUME_START", - "EVENT_VOLUME_STOP", - "EVENT_VOLUME_DELETE", - "EVENT_VOLUME_SET", - "EVENT_VOLUME_RESET", -+ "EVENT_BRICK_RESET", -+ "EVENT_BRICK_REPLACE", - -+ #geo-rep events - "EVENT_GEOREP_CREATE", - "EVENT_GEOREP_START", - "EVENT_GEOREP_STOP", -@@ -40,19 +44,61 @@ keys = ( - "EVENT_GEOREP_CONFIG_SET", - "EVENT_GEOREP_CONFIG_RESET", - -+ #bitrot events - "EVENT_BITROT_ENABLE", - "EVENT_BITROT_DISABLE", - "EVENT_BITROT_SCRUB_THROTTLE", - "EVENT_BITROT_SCRUB_FREQ", - "EVENT_BITROT_SCRUB_OPTION", -- "EVENT_BITROT_BAD_FILE", - -+ #quota events -+ "EVENT_QUOTA_ENABLE", -+ "EVENT_QUOTA_DISABLE", -+ "EVENT_QUOTA_SET_USAGE_LIMIT", -+ "EVENT_QUOTA_SET_OBJECTS_LIMIT", -+ "EVENT_QUOTA_REMOVE_USAGE_LIMIT", -+ "EVENT_QUOTA_REMOVE_OBJECTS_LIMIT", -+ "EVENT_QUOTA_ALERT_TIME", -+ "EVENT_QUOTA_SOFT_TIMEOUT", -+ "EVENT_QUOTA_HARD_TIMEOUT", -+ "EVENT_QUOTA_DEFAULT_SOFT_LIMIT", -+ -+ #snapshot events -+ "EVENT_SNAPSHOT_CREATED", -+ "EVENT_SNAPSHOT_CREATE_FAILED", -+ "EVENT_SNAPSHOT_ACTIVATED", -+ "EVENT_SNAPSHOT_ACTIVATE_FAILED", -+ "EVENT_SNAPSHOT_DEACTIVATED", -+ "EVENT_SNAPSHOT_DEACTIVATE_FAILED", -+ "EVENT_SNAPSHOT_SOFT_LIMIT_REACHED", -+ "EVENT_SNAPSHOT_HARD_LIMIT_REACHED", -+ "EVENT_SNAPSHOT_RESTORED", -+ "EVENT_SNAPSHOT_RESTORE_FAILED", -+ "EVENT_SNAPSHOT_DELETED", -+ "EVENT_SNAPSHOT_DELETE_FAILED", -+ "EVENT_SNAPSHOT_CLONED", -+ "EVENT_SNAPSHOT_CLONE_FAILED", -+ "EVENT_SNAPSHOT_CONFIG_UPDATED", -+ "EVENT_SNAPSHOT_CONFIG_UPDATE_FAILED", -+ "EVENT_SNAPSHOT_SCHEDULER_INITIALISED", -+ "EVENT_SNAPSHOT_SCHEDULER_INIT_FAILED", -+ "EVENT_SNAPSHOT_SCHEDULER_ENABLED", -+ "EVENT_SNAPSHOT_SCHEDULER_ENABLE_FAILED", -+ "EVENT_SNAPSHOT_SCHEDULER_DISABLED", -+ "EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED", -+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADDED", -+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED", -+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDITED", -+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED", -+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETED", -+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED", -+ -+ #async events -+ #glusterd events - "EVENT_SVC_MANAGER_FAILED", - "EVENT_SVC_RECONFIGURE_FAILED", - "EVENT_SVC_CONNECTED", - "EVENT_SVC_DISCONNECTED", -- -- - "EVENT_PEER_STORE_FAILURE", - "EVENT_PEER_RPC_CREATE_FAILED", - "EVENT_PEER_REJECT", -@@ -60,16 +106,13 @@ keys = ( - "EVENT_PEER_DISCONNECT", - "EVENT_PEER_NOT_FOUND", - "EVENT_UNKNOWN_PEER", -- - "EVENT_BRICK_START_FAILED", - "EVENT_BRICK_STOP_FAILED", - "EVENT_BRICK_DISCONNECTED", - "EVENT_BRICK_CONNECTED", - "EVENT_BRICKS_START_FAILED", - "EVENT_BRICKPATH_RESOLVE_FAILED", -- - "EVENT_NOTIFY_UNKNOWN_OP", -- - "EVENT_QUORUM_LOST", - "EVENT_QUORUM_REGAINED", - "EVENT_REBALANCE_START_FAILED", -@@ -79,18 +122,33 @@ keys = ( - "EVENT_IMPORT_BRICK_FAILED", - "EVENT_COMPARE_FRIEND_VOLUME_FAILED", - "EVENT_NFS_GANESHA_EXPORT_FAILED", -- -- "EVENT_QUOTA_ENABLE", -- "EVENT_QUOTA_DISABLE", -- "EVENT_QUOTA_SET_USAGE_LIMIT", -- "EVENT_QUOTA_SET_OBJECTS_LIMIT", -- "EVENT_QUOTA_REMOVE_USAGE_LIMIT", -- "EVENT_QUOTA_REMOVE_OBJECTS_LIMIT", -- "EVENT_QUOTA_ALERT_TIME", -- "EVENT_QUOTA_SOFT_TIMEOUT", -- "EVENT_QUOTA_HARD_TIMEOUT", -- "EVENT_QUOTA_DEFAULT_SOFT_LIMIT", -+ #ec events -+ "EVENT_EC_DATA_BRICKS_NOT_UP", -+ "EVENT_EC_DATA_BRICKS_UP", -+ #georep async events -+ "EVENT_GEOREP_FAULTY", -+ #quota async events - "EVENT_QUOTA_CROSSED_SOFT_LIMIT", -+ -+ #bitrot async events -+ "EVENT_BITROT_BAD_FILE", -+ #protocol-server events -+ "EVENT_CLIENT_CONNECT", -+ "EVENT_CLIENT_AUTH_REJECT", -+ "EVENT_CLIENT_DISCONNECT", -+ #posix events -+ "EVENT_POSIX_SAME_GFID", -+ "EVENT_POSIX_ALREADY_PART_OF_VOLUME", -+ "EVENT_POSIX_INVALID_BRICK", -+ "EVENT_POSIX_BRICK_VERIFICATION_FAILED", -+ "EVENT_POSIX_ACL_NOTSUP", -+ "EVENT_POSIX_HEALTH_CHECK_FAILED", -+ #afr events -+ "EVENT_AFR_QUORUM_MET", -+ "EVENT_AFR_QUORUM_FAIL", -+ "EVENT_AFR_SUBVOL_UP", -+ "EVENT_AFR_SUBVOLS_DOWN", -+ "EVENT_AFR_SPLIT_BRAIN", - ) - - LAST_EVENT = "EVENT_LAST" --- -1.7.1 - diff --git a/SOURCES/0053-ganesha-scripts-Remove-export-entries-from-ganesha.c.patch b/SOURCES/0053-ganesha-scripts-Remove-export-entries-from-ganesha.c.patch new file mode 100644 index 0000000..3c0ad6d --- /dev/null +++ b/SOURCES/0053-ganesha-scripts-Remove-export-entries-from-ganesha.c.patch @@ -0,0 +1,33 @@ +From bfad2cafc9cbb58161386ee71dd086f01176558e Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Wed, 22 Feb 2017 14:37:04 +0530 +Subject: [PATCH 53/74] ganesha/scripts : Remove export entries from + ganesha.conf during cleanup + +Change-Id: I288f7c9ced23d258a7ce1242d8efe03a4bf6f746 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/16708 +Smoke: Gluster Build System +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: soumya k +Reviewed-by: Kaleb KEITHLEY +--- + extras/ganesha/scripts/ganesha-ha.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index d4844e4..2d6b06f 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -342,6 +342,7 @@ cleanup_ganesha_config () + rm -f /etc/corosync/corosync.conf + rm -rf /etc/cluster/cluster.conf* + rm -rf /var/lib/pacemaker/cib/* ++ sed -r -i -e '/^%include[[:space:]]+".+\.conf"$/d' $HA_CONFDIR/ganesha.conf + } + + do_create_virt_ip_constraints() +-- +1.8.3.1 + diff --git a/SOURCES/0053-protocol-server-generate-events.patch b/SOURCES/0053-protocol-server-generate-events.patch deleted file mode 100644 index a84a102..0000000 --- a/SOURCES/0053-protocol-server-generate-events.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 60c4a19f15d806e36e8e67352349cc1c6daa0199 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 16 Sep 2016 13:19:48 +0530 -Subject: [PATCH 53/86] protocol-server: generate events - -This patch add/generate the events seen from/in the protocol server -side, which will be consumed by the new eventing framework. - -------------------------------------------------------------------------- -| event | description | -|-------------------------------|---------------------------------------| -| EVENT_CLIENT_CONNECT | new client connected | -|-------------------------------|---------------------------------------| -| EVENT_CLIENT_AUTH_REJECT | client cannot be authenticated | -|-------------------------------|---------------------------------------| -| EVENT_CLIENT_DISCONNECT | client had disconnected | -------------------------------------------------------------------------- - -Thanks to "Raghavendra Talur" for all the help - -Backport of: -> Change-Id: I4fda83fae7747507f64d81a7645cc3a8a2fbaeae -> BUG: 1369403 -> Signed-off-by: Prasanna Kumar Kalever -> Reviewed-on: http://review.gluster.org/15294 -> Tested-by: Prasanna Kumar Kalever -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Raghavendra G - -Change-Id: I4fda83fae7747507f64d81a7645cc3a8a2fbaeae -BUG: 1367382 -Signed-off-by: Prasanna Kumar Kalever -Reviewed-on: https://code.engineering.redhat.com/gerrit/84770 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - xlators/protocol/server/src/server-handshake.c | 17 +++++++ - xlators/protocol/server/src/server.c | 55 +++++++++++++++++++++++- - 2 files changed, 70 insertions(+), 2 deletions(-) - -diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c -index 7715952..1230cdf 100644 ---- a/xlators/protocol/server/src/server-handshake.c -+++ b/xlators/protocol/server/src/server-handshake.c -@@ -18,6 +18,7 @@ - #include "authenticate.h" - #include "server-messages.h" - #include "syscall.h" -+#include "events.h" - - struct __get_xl_struct { - const char *name; -@@ -690,6 +691,15 @@ server_setvolume (rpcsvc_request_t *req) - "accepted client from %s (version: %s)", - client->client_uid, - (clnt_version) ? clnt_version : "old"); -+ -+ gf_event (EVENT_CLIENT_CONNECT, "client_uid=%s;" -+ "client_identifier=%s;server_identifier=%s;" -+ "brick_path=%s", -+ client->client_uid, -+ req->trans->peerinfo.identifier, -+ req->trans->myinfo.identifier, -+ name); -+ - op_ret = 0; - client->bound_xl = xl; - ret = dict_set_str (reply, "ERROR", "Success"); -@@ -697,6 +707,13 @@ server_setvolume (rpcsvc_request_t *req) - gf_msg_debug (this->name, 0, "failed to set error " - "msg"); - } else { -+ gf_event (EVENT_CLIENT_AUTH_REJECT, "client_uid=%s;" -+ "client_identifier=%s;server_identifier=%s;" -+ "brick_path=%s", -+ client->client_uid, -+ req->trans->peerinfo.identifier, -+ req->trans->myinfo.identifier, -+ name); - gf_msg (this->name, GF_LOG_ERROR, EACCES, - PS_MSG_AUTHENTICATE_ERROR, "Cannot authenticate client" - " from %s %s", client->client_uid, -diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c -index 10009e2..457f3d6 100644 ---- a/xlators/protocol/server/src/server.c -+++ b/xlators/protocol/server/src/server.c -@@ -21,6 +21,7 @@ - #include "defaults.h" - #include "authenticate.h" - #include "event.h" -+#include "events.h" - #include "server-messages.h" - - rpcsvc_cbk_program_t server_cbk_prog = { -@@ -76,7 +77,8 @@ grace_time_handler (void *data) - */ - gf_client_ref (client); - gf_client_put (client, &detached); -- if (detached)//reconnection did not happen :-( -+ -+ if (detached) /* reconnection did not happen :-( */ - server_connection_cleanup (this, client, - INTERNAL_LOCKS | POSIX_LOCKS); - gf_client_unref (client); -@@ -488,6 +490,8 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, - client_t *client = NULL; - server_ctx_t *serv_ctx = NULL; - struct timespec grace_ts = {0, }; -+ char *auth_path = NULL; -+ int ret = -1; - - if (!xl || !data) { - gf_msg_callingfn ("server", GF_LOG_WARNING, 0, -@@ -547,19 +551,45 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event, - PS_MSG_CLIENT_DISCONNECTING, "disconnecting connection" - " from %s", client->client_uid); - -+ ret = dict_get_str (this->options, "auth-path", &auth_path); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_WARNING, 0, -+ PS_MSG_DICT_GET_FAILED, -+ "failed to get auth-path"); -+ auth_path = NULL; -+ } -+ - /* If lock self heal is off, then destroy the - conn object, else register a grace timer event */ - if (!conf->lk_heal) { - gf_client_ref (client); - gf_client_put (client, &detached); -- if (detached) -+ if (detached) { - server_connection_cleanup (this, client, - INTERNAL_LOCKS | POSIX_LOCKS); -+ -+ gf_event (EVENT_CLIENT_DISCONNECT, -+ "client_uid=%s;" -+ "client_identifier=%s;" -+ "server_identifier=%s;" -+ "brick_path=%s", -+ client->client_uid, -+ trans->peerinfo.identifier, -+ trans->myinfo.identifier, -+ auth_path); -+ } - gf_client_unref (client); - break; - } - trans->xl_private = NULL; - server_connection_cleanup (this, client, INTERNAL_LOCKS); -+ gf_event (EVENT_CLIENT_DISCONNECT, "client_uid=%s;" -+ "client_identifier=%s;server_identifier=%s;" -+ "brick_path=%s", -+ client->client_uid, -+ trans->peerinfo.identifier, -+ trans->myinfo.identifier, -+ auth_path); - - serv_ctx = server_ctx_get (client, this); - -@@ -718,6 +748,7 @@ reconfigure (xlator_t *this, dict_t *options) - char *statedump_path = NULL; - xlator_t *xl = NULL; - int32_t new_nthread = 0; -+ char *auth_path = NULL; - - conf = this->private; - -@@ -842,6 +873,26 @@ reconfigure (xlator_t *this, dict_t *options) - "authorized client, hence we " - "continue with this connection"); - } else { -+ ret = dict_get_str (this->options, -+ "auth-path", -+ &auth_path); -+ if (ret) { -+ gf_msg (this->name, -+ GF_LOG_WARNING, 0, -+ PS_MSG_DICT_GET_FAILED, -+ "failed to get " -+ "auth-path"); -+ auth_path = NULL; -+ } -+ gf_event (EVENT_CLIENT_AUTH_REJECT, -+ "client_uid=%s;" -+ "client_identifier=%s;" -+ "server_identifier=%s;" -+ "brick_path=%s", -+ xprt->xl_private->client_uid, -+ xprt->peerinfo.identifier, -+ xprt->myinfo.identifier, -+ auth_path); - gf_msg (this->name, GF_LOG_INFO, - EACCES, - PS_MSG_AUTHENTICATE_ERROR, --- -1.7.1 - diff --git a/SOURCES/0054-extras-cliutils-Utils-for-creating-CLI-tools-for-Glu.patch b/SOURCES/0054-extras-cliutils-Utils-for-creating-CLI-tools-for-Glu.patch deleted file mode 100644 index 276f12a..0000000 --- a/SOURCES/0054-extras-cliutils-Utils-for-creating-CLI-tools-for-Glu.patch +++ /dev/null @@ -1,591 +0,0 @@ -From 322ca565ff22481a1406a205d8f6f44359b68009 Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Tue, 31 May 2016 13:39:05 +0530 -Subject: [PATCH 54/86] extras/cliutils: Utils for creating CLI tools for Gluster - -Refer README.md for documentation. - -This patch also includes changes from #14923 since without that -build will fail. - -> Reviewed-on: http://review.gluster.org/14627 -> Reviewed-on: http://review.gluster.org/14923 -> Reviewed-by: Prashanth Pai -> Reviewed-by: Niels de Vos -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Jeff Darcy - -BUG: 1351589 -Change-Id: Ic88504177137136bbb4b8b2c304ecc4af9bcfe30 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84799 -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - configure.ac | 1 + - extras/Makefile.am | 2 +- - extras/cliutils/Makefile.am | 4 + - extras/cliutils/README.md | 233 +++++++++++++++++++++++++++++++++++++++++++ - extras/cliutils/__init__.py | 29 ++++++ - extras/cliutils/cliutils.py | 212 +++++++++++++++++++++++++++++++++++++++ - glusterfs.spec.in | 4 + - 7 files changed, 484 insertions(+), 1 deletions(-) - create mode 100644 extras/cliutils/Makefile.am - create mode 100644 extras/cliutils/README.md - create mode 100644 extras/cliutils/__init__.py - create mode 100644 extras/cliutils/cliutils.py - -diff --git a/configure.ac b/configure.ac -index d84398d..75ebcd4 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -194,6 +194,7 @@ AC_CONFIG_FILES([Makefile - doc/Makefile - extras/Makefile - extras/glusterd.vol -+ extras/cliutils/Makefile - extras/init.d/Makefile - extras/init.d/glusterd.plist - extras/init.d/glusterd-Debian -diff --git a/extras/Makefile.am b/extras/Makefile.am -index 609d497..37b297f 100644 ---- a/extras/Makefile.am -+++ b/extras/Makefile.am -@@ -5,7 +5,7 @@ EditorModedir = $(docdir) - EditorMode_DATA = glusterfs-mode.el glusterfs.vim - - SUBDIRS = init.d systemd benchmarking hook-scripts $(OCF_SUBDIR) LinuxRPM \ -- $(GEOREP_EXTRAS_SUBDIR) ganesha snap_scheduler firewalld -+ $(GEOREP_EXTRAS_SUBDIR) ganesha snap_scheduler firewalld cliutils - - confdir = $(sysconfdir)/glusterfs - conf_DATA = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \ -diff --git a/extras/cliutils/Makefile.am b/extras/cliutils/Makefile.am -new file mode 100644 -index 0000000..7039703 ---- /dev/null -+++ b/extras/cliutils/Makefile.am -@@ -0,0 +1,4 @@ -+EXTRA_DIST= cliutils.py __init__.py -+ -+cliutilsdir = @BUILD_PYTHON_SITE_PACKAGES@/gluster/cliutils -+cliutils_PYTHON = cliutils.py __init__.py -diff --git a/extras/cliutils/README.md b/extras/cliutils/README.md -new file mode 100644 -index 0000000..ccb6080 ---- /dev/null -+++ b/extras/cliutils/README.md -@@ -0,0 +1,233 @@ -+# CLI utility for creating Cluster aware CLI tools for Gluster -+cliutils is a Python library which provides wrapper around `gluster system:: -+execute` command to extend the functionalities of Gluster. -+ -+Example use cases: -+- Start a service in all peer nodes of Cluster -+- Collect the status of a service from all peer nodes -+- Collect the config values from each peer nodes and display latest -+ config based on version. -+- Copy a file present in GLUSTERD_WORKDIR from one peer node to all -+ other peer nodes.(Geo-replication create push-pem is using this to -+ distribute the SSH public keys from all master nodes to all slave -+ nodes) -+- Generate pem keys in all peer nodes and collect all the public keys -+ to one place(Geo-replication gsec_create is doing this) -+- Provide Config sync CLIs for new features like `gluster-eventsapi`, -+ `gluster-restapi`, `gluster-mountbroker` etc. -+ -+## Introduction -+ -+If a executable file present in `$GLUSTER_LIBEXEC` directory in all -+peer nodes(Filename startswith `peer_`) then it can be executed by -+running `gluster system:: execute` command from any one peer node. -+ -+- This command will not copy any executables to peer nodes, Script -+ should exist in all peer nodes to use this infrastructure. Raises -+ error in case script not exists in any one of the peer node. -+- Filename should start with `peer_` and should exist in -+ `$GLUSTER_LIBEXEC` directory. -+- This command can not be called from outside the cluster. -+ -+To understand the functionality, create a executable file `peer_hello` -+under $GLUSTER_LIBEXEC directory and copy to all peer nodes. -+ -+ #!/usr/bin/env bash -+ echo "Hello from $(gluster system:: uuid get)" -+ -+Now run the following command from any one gluster node, -+ -+ gluster system:: execute hello -+ -+**Note:** Gluster will not copy the executable script to all nodes, -+ copy `peer_hello` script to all peer nodes to use `gluster system:: -+ execute` infrastructure. -+ -+It will run `peer_hello` executable in all peer nodes and shows the -+output from each node(Below example shows output from my two nodes -+cluster) -+ -+ Hello from UUID: e7a3c5c8-e7ad-47ad-aa9c-c13907c4da84 -+ Hello from UUID: c680fc0a-01f9-4c93-a062-df91cc02e40f -+ -+## cliutils -+A Python wrapper around `gluster system:: execute` command is created -+to address the following issues -+ -+- If a node is down in the cluster, `system:: execute` just skips it -+ and runs only in up nodes. -+- `system:: execute` commands are not user friendly -+- It captures only stdout, so handling errors is tricky. -+ -+**Advantages of cliutils:** -+ -+- Single executable file will act as node component as well as User CLI. -+- `execute_in_peers` utility function will merge the `gluster system:: -+ execute` output with `gluster peer status` to identify offline nodes. -+- Easy CLI Arguments handling. -+- If node component returns non zero return value then, `gluster -+ system:: execute` will fail to aggregate the output from other -+ nodes. `node_output_ok` or `node_output_notok` utility functions -+ returns zero both in case of success or error, but returns json -+ with ok: true or ok:false respectively. -+- Easy to iterate on the node outputs. -+- Better error handling - Geo-rep CLIs `gluster system:: execute -+ mountbroker`, `gluster system:: execute gsec_create` and `gluster -+ system:: add_secret_pub` are suffering from error handling. These -+ tools are not notifying user if any failures during execute or if a node -+ is down during execute. -+ -+### Hello World -+Create a file in `$LIBEXEC/glusterfs/peer_message.py` with following -+content. -+ -+ #!/usr/bin/env python -+ from gluster.cliutils import Cmd, runcli, execute_in_peers, node_output_ok -+ -+ class NodeHello(Cmd): -+ name = "node-hello" -+ -+ def run(self, args): -+ node_output_ok("Hello") -+ -+ class Hello(Cmd): -+ name = "hello" -+ -+ def run(self, args): -+ out = execute_in_peers("node-hello") -+ for row in out: -+ print ("{0} from {1}".format(row.output, row.hostname)) -+ -+ if __name__ == "__main__": -+ runcli() -+ -+When we run `python peer_message.py`, it will have two subcommands, -+"node-hello" and "hello". This file should be copied to -+`$LIBEXEC/glusterfs` directory in all peer nodes. User will call -+subcommand "hello" from any one peer node, which internally call -+`gluster system:: execute message.py node-hello`(This runs in all peer -+nodes and collect the outputs) -+ -+For node component do not print the output directly, use -+`node_output_ok` or `node_output_notok` functions. `node_output_ok` -+additionally collects the node UUID and prints in JSON -+format. `execute_in_peers` function will collect this output and -+merges with `peers list` so that we don't miss the node information if -+that node is offline. -+ -+If you observed already, function `args` is optional, if you don't -+have arguments then no need to create a function. When we run the -+file, we will have two subcommands. For example, -+ -+ python peer_message.py hello -+ python peer_message.py node-hello -+ -+First subcommand calls second subcommand in all peer nodes. Basically -+`execute_in_peers(NAME, ARGS)` will be converted into -+ -+ CMD_NAME = FILENAME without "peers_" -+ gluster system:: execute -+ -+In our example, -+ -+ filename = "peer_message.py" -+ cmd_name = "message.py" -+ gluster system:: execute ${cmd_name} node-hello -+ -+Now create symlink in `/usr/bin` or `/usr/sbin` directory depending on -+the usecase.(Optional step for usability) -+ -+ ln -s /usr/libexec/glusterfs/peer_message.py /usr/bin/gluster-message -+ -+Now users can use `gluster-message` instead of calling -+`/usr/libexec/glusterfs/peer_message.py` -+ -+ gluster-message hello -+ -+### Showing CLI output as Table -+ -+Following example uses prettytable library, which can be installed -+using `pip install prettytable` or `dnf install python-prettytable` -+ -+ #!/usr/bin/env python -+ from prettytable import PrettyTable -+ from gluster.cliutils import Cmd, runcli, execute_in_peers, node_output_ok -+ -+ class NodeHello(Cmd): -+ name = "node-hello" -+ -+ def run(self, args): -+ node_output_ok("Hello") -+ -+ class Hello(Cmd): -+ name = "hello" -+ -+ def run(self, args): -+ out = execute_in_peers("node-hello") -+ # Initialize the CLI table -+ table = PrettyTable(["ID", "NODE", "NODE STATUS", "MESSAGE"]) -+ table.align["NODE STATUS"] = "r" -+ for row in out: -+ table.add_row([row.nodeid, -+ row.hostname, -+ "UP" if row.node_up else "DOWN", -+ row.output if row.ok else row.error]) -+ -+ print table -+ -+ if __name__ == "__main__": -+ runcli() -+ -+ -+Example output, -+ -+ +--------------------------------------+-----------+-------------+---------+ -+ | ID | NODE | NODE STATUS | MESSAGE | -+ +--------------------------------------+-----------+-------------+---------+ -+ | e7a3c5c8-e7ad-47ad-aa9c-c13907c4da84 | localhost | UP | Hello | -+ | bb57a4c4-86eb-4af5-865d-932148c2759b | vm2 | UP | Hello | -+ | f69b918f-1ffa-4fe5-b554-ee10f051294e | vm3 | DOWN | N/A | -+ +--------------------------------------+-----------+-------------+---------+ -+ -+## How to package in Gluster -+If the project is created in `$GLUSTER_SRC/tools/message` -+ -+Add "message" to SUBDIRS list in `$GLUSTER_SRC/tools/Makefile.am` -+ -+and then create a `Makefile.am` in `$GLUSTER_SRC/tools/message` -+directory with following content. -+ -+ EXTRA_DIST = peer_message.py -+ -+ peertoolsdir = $(libexecdir)/glusterfs/ -+ peertools_SCRIPTS = peer_message.py -+ -+ install-exec-hook: -+ $(mkdir_p) $(DESTDIR)$(bindir) -+ rm -f $(DESTDIR)$(bindir)/gluster-message -+ ln -s $(libexecdir)/glusterfs/peer_message.py \ -+ $(DESTDIR)$(bindir)/gluster-message -+ -+ uninstall-hook: -+ rm -f $(DESTDIR)$(bindir)/gluster-message -+ -+Thats all. Add following files in `glusterfs.spec.in` if packaging is -+required.(Under `%files` section) -+ -+ %{_libexecdir}/glusterfs/peer_message.py* -+ %{_bindir}/gluster-message -+ -+## Who is using cliutils -+- gluster-mountbroker http://review.gluster.org/14544 -+- gluster-eventsapi http://review.gluster.org/14248 -+- gluster-georep-sshkey http://review.gluster.org/14732 -+- gluster-restapi https://github.com/aravindavk/glusterfs-restapi -+ -+## Limitations/TODOs -+- Not yet possible to create CLI without any subcommand, For example -+ `gluster-message` without any arguments -+- Hiding node subcommands in `--help`(`gluster-message --help` will -+ show all subcommands including node subcommands) -+- Only positional arguments supported for node arguments, Optional -+ arguments can be used for other commands. -+- API documentation -diff --git a/extras/cliutils/__init__.py b/extras/cliutils/__init__.py -new file mode 100644 -index 0000000..4bb8395 ---- /dev/null -+++ b/extras/cliutils/__init__.py -@@ -0,0 +1,29 @@ -+# -*- coding: utf-8 -*- -+# Reexporting the utility funcs and classes -+from cliutils import (runcli, -+ sync_file_to_peers, -+ execute_in_peers, -+ execute, -+ node_output_ok, -+ node_output_notok, -+ output_error, -+ oknotok, -+ yesno, -+ get_node_uuid, -+ Cmd, -+ GlusterCmdException) -+ -+ -+# This will be useful when `from cliutils import *` -+__all__ = ["runcli", -+ "sync_file_to_peers", -+ "execute_in_peers", -+ "execute", -+ "node_output_ok", -+ "node_output_notok", -+ "output_error", -+ "oknotok", -+ "yesno", -+ "get_node_uuid", -+ "Cmd", -+ "GlusterCmdException"] -diff --git a/extras/cliutils/cliutils.py b/extras/cliutils/cliutils.py -new file mode 100644 -index 0000000..4e035d7 ---- /dev/null -+++ b/extras/cliutils/cliutils.py -@@ -0,0 +1,212 @@ -+# -*- coding: utf-8 -*- -+from __future__ import print_function -+from argparse import ArgumentParser, RawDescriptionHelpFormatter -+import inspect -+import subprocess -+import os -+import xml.etree.cElementTree as etree -+import json -+import sys -+ -+MY_UUID = None -+parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter, -+ description=__doc__) -+subparsers = parser.add_subparsers(dest="mode") -+ -+subcommands = {} -+cache_data = {} -+ParseError = etree.ParseError if hasattr(etree, 'ParseError') else SyntaxError -+ -+ -+class GlusterCmdException(Exception): -+ pass -+ -+ -+def get_node_uuid(): -+ # Caches the Node UUID in global variable, -+ # Executes gluster system:: uuid get command only if -+ # calling this function for first time -+ global MY_UUID -+ if MY_UUID is not None: -+ return MY_UUID -+ -+ cmd = ["gluster", "system::", "uuid", "get", "--xml"] -+ rc, out, err = execute(cmd) -+ -+ if rc != 0: -+ return None -+ -+ tree = etree.fromstring(out) -+ uuid_el = tree.find("uuidGenerate/uuid") -+ MY_UUID = uuid_el.text -+ return MY_UUID -+ -+ -+def yesno(flag): -+ return "Yes" if flag else "No" -+ -+ -+def oknotok(flag): -+ return "OK" if flag else "NOT OK" -+ -+ -+def output_error(message): -+ print (message, file=sys.stderr) -+ sys.exit(1) -+ -+ -+def node_output_ok(message=""): -+ # Prints Success JSON output and exits with returncode zero -+ out = {"ok": True, "nodeid": get_node_uuid(), "output": message} -+ print (json.dumps(out)) -+ sys.exit(0) -+ -+ -+def node_output_notok(message): -+ # Prints Error JSON output and exits with returncode zero -+ out = {"ok": False, "nodeid": get_node_uuid(), "error": message} -+ print (json.dumps(out)) -+ sys.exit(0) -+ -+ -+def execute(cmd): -+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ out, err = p.communicate() -+ return p.returncode, out, err -+ -+ -+def get_pool_list(): -+ cmd = ["gluster", "--mode=script", "pool", "list", "--xml"] -+ rc, out, err = execute(cmd) -+ if rc != 0: -+ output_error("Failed to get Pool Info: {0}".format(err)) -+ -+ tree = etree.fromstring(out) -+ -+ pool = [] -+ try: -+ for p in tree.findall('peerStatus/peer'): -+ pool.append({"nodeid": p.find("uuid").text, -+ "hostname": p.find("hostname").text, -+ "connected": (True if p.find("connected").text == "1" -+ else False)}) -+ except (ParseError, AttributeError, ValueError) as e: -+ output_error("Failed to parse Pool Info: {0}".format(e)) -+ -+ return pool -+ -+ -+class NodeOutput(object): -+ def __init__(self, **kwargs): -+ self.nodeid = kwargs.get("nodeid", "") -+ self.hostname = kwargs.get("hostname", "") -+ self.node_up = kwargs.get("node_up", False) -+ self.ok = kwargs.get("ok", False) -+ self.output = kwargs.get("output", "N/A") -+ self.error = kwargs.get("error", "N/A") -+ -+ -+def execute_in_peers(name, args=[]): -+ # Get the file name of Caller function, If the file name is peer_example.py -+ # then Gluster peer command will be gluster system:: execute example.py -+ # Command name is without peer_ -+ frame = inspect.stack()[1] -+ module = inspect.getmodule(frame[0]) -+ actual_file = module.__file__ -+ # If file is symlink then find actual file -+ if os.path.islink(actual_file): -+ actual_file = os.readlink(actual_file) -+ -+ # Get the name of file without peer_ -+ cmd_name = os.path.basename(actual_file).replace("peer_", "") -+ cmd = ["gluster", "system::", "execute", cmd_name, name] + args -+ rc, out, err = execute(cmd) -+ if rc != 0: -+ raise GlusterCmdException((rc, out, err, " ".join(cmd))) -+ -+ out = out.strip().splitlines() -+ -+ # JSON decode each line and construct one object with node id as key -+ all_nodes_data = {} -+ for node_data in out: -+ data = json.loads(node_data) -+ all_nodes_data[data["nodeid"]] = { -+ "nodeid": data.get("nodeid"), -+ "ok": data.get("ok"), -+ "output": data.get("output", ""), -+ "error": data.get("error", "")} -+ -+ # gluster pool list -+ pool_list = get_pool_list() -+ -+ data_out = [] -+ # Iterate pool_list and merge all_nodes_data collected above -+ # If a peer node is down then set node_up = False -+ for p in pool_list: -+ p_data = all_nodes_data.get(p.get("nodeid"), None) -+ row_data = NodeOutput(node_up=False, -+ hostname=p.get("hostname"), -+ nodeid=p.get("nodeid"), -+ ok=False) -+ -+ if p_data is not None: -+ # Node is UP -+ row_data.node_up = True -+ row_data.ok = p_data.get("ok") -+ row_data.output = p_data.get("output") -+ row_data.error = p_data.get("error") -+ -+ data_out.append(row_data) -+ -+ return data_out -+ -+ -+def sync_file_to_peers(fname): -+ # Copy file from current node to all peer nodes, fname -+ # is path after GLUSTERD_WORKDIR -+ cmd = ["gluster", "system::", "copy", "file", fname] -+ rc, out, err = execute(cmd) -+ if rc != 0: -+ raise GlusterCmdException((rc, out, err)) -+ -+ -+class Cmd(object): -+ name = "" -+ -+ def run(self, args): -+ # Must required method. Raise NotImplementedError if derived class -+ # not implemented this method -+ raise NotImplementedError("\"run(self, args)\" method is " -+ "not implemented by \"{0}\"".format( -+ self.__class__.__name__)) -+ -+ -+def runcli(): -+ # Get list of Classes derived from class "Cmd" and create -+ # a subcommand as specified in the Class name. Call the args -+ # method by passing subcommand parser, Derived class can add -+ # arguments to the subcommand parser. -+ for c in Cmd.__subclasses__(): -+ cls = c() -+ if getattr(cls, "name", "") == "": -+ raise NotImplementedError("\"name\" is not added " -+ "to \"{0}\"".format( -+ cls.__class__.__name__)) -+ -+ p = subparsers.add_parser(cls.name) -+ args_func = getattr(cls, "args", None) -+ if args_func is not None: -+ args_func(p) -+ -+ # A dict to save subcommands, key is name of the subcommand -+ subcommands[cls.name] = cls -+ -+ # Get all parsed arguments -+ args = parser.parse_args() -+ -+ # Get the subcommand to execute -+ cls = subcommands.get(args.mode, None) -+ -+ # Run -+ if cls is not None: -+ cls.run(args) -diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 06f1de1..a60f216 100644 ---- a/glusterfs.spec.in -+++ b/glusterfs.spec.in -@@ -1249,6 +1249,7 @@ exit 0 - # introducing glusterfs module in site packages. - # so that all other gluster submodules can reside in the same namespace. - %{python_sitelib}/gluster/__init__.* -+%{python_sitelib}/gluster/cliutils - - %if ( 0%{!?_without_rdma:1} ) - %files rdma -@@ -2008,6 +2009,9 @@ end - - %changelog - * Fri Sep 16 2016 Aravinda VK -+- Added Python subpackage "cliutils" under gluster (#1342356) -+ -+* Fri Sep 16 2016 Aravinda VK - - Changed attribute of eventsconfig.json file as same as other configs (#1375532) - - * Fri Sep 16 2016 Aravinda VK --- -1.7.1 - diff --git a/SOURCES/0054-glusterd-ganesha-During-volume-delete-remove-the-gan.patch b/SOURCES/0054-glusterd-ganesha-During-volume-delete-remove-the-gan.patch new file mode 100644 index 0000000..8b6c8e2 --- /dev/null +++ b/SOURCES/0054-glusterd-ganesha-During-volume-delete-remove-the-gan.patch @@ -0,0 +1,55 @@ +From 1a9717eb9fb0c6ebd4fce5aa85e3ed53bdd69d59 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Wed, 22 Feb 2017 14:20:41 +0530 +Subject: [PATCH 54/74] glusterd/ganesha : During volume delete remove the + ganesha export configuration file + +Change-Id: I0363e7f4d7cefd3f1b3c4f91e495767ec52e230e +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/16707 +Smoke: Gluster Build System +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: soumya k +Reviewed-by: Kaleb KEITHLEY +Signed-off-by: Jiffin Tony Thottan +--- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 2 +- + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 8 ++++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index c16dd72..e176df9 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -464,7 +464,7 @@ manage_export_config (char *volname, char *value, char **op_errstr) + CONFDIR, value, volname, NULL); + ret = runner_run(&runner); + +- if (ret) ++ if (ret && !(*op_errstr)) + gf_asprintf (op_errstr, "Failed to create" + " NFS-Ganesha export config file."); + +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +index 0914fb1..92db458 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +@@ -2853,6 +2853,14 @@ glusterd_op_delete_volume (dict_t *dict) + volname); + goto out; + } ++ if (glusterd_check_ganesha_export (volinfo)) { ++ ret = manage_export_config (volname, "off", NULL); ++ if (ret) ++ gf_msg (this->name, GF_LOG_WARNING, 0, 0, ++ "Could not delete ganesha export conf file " ++ "for %s", volname); ++ } ++ + + ret = glusterd_delete_volume (volinfo); + out: +-- +1.8.3.1 + diff --git a/SOURCES/0055-glusterd-ganesha-Move-ganesha-ha.conf-and-ganesha.co.patch b/SOURCES/0055-glusterd-ganesha-Move-ganesha-ha.conf-and-ganesha.co.patch deleted file mode 100644 index 73ec16c..0000000 --- a/SOURCES/0055-glusterd-ganesha-Move-ganesha-ha.conf-and-ganesha.co.patch +++ /dev/null @@ -1,361 +0,0 @@ -From 9cab3d31da4bfd5784215fe394b46bcfc6214bfd Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Tue, 12 Jul 2016 15:44:23 +0530 -Subject: [PATCH 55/86] glusterd/ganesha : Move ganesha-ha.conf and ganesha.conf to shared storage - -Currently all the ganesha related configuration files(ganesha.conf, -ganesha-ha.conf, export files, etc) is stored locally at /etc/ganesha -on a every node in ganesha cluster. Usually we end up in two issues by -doing so : -* difficult in modifiying ganesha related conf file -* diffciult to maintain consistency of conf file across ganesha cluster -To tackle this, we plan to move all the ganesha configuration to shared -storage. As a first step in this patch ganesha.conf and ganesha-ha.conf -move to shared storage. Here actual ganesha.conf will resides in shared -stoarge and symlinks will be created in /etc/ganesha when the option -"gluster nfs-ganesha enable" is executed and remove those during the -"disable" part. - -Modified prerequisites to done before running globaloption: - * enable shared storage - * create nfs-ganesha folder in shared storage - * create ganesha.conf and ganesha-ha.conf in it - -More details can be found at http://review.gluster.org/#/c/15105/ - -Upstream reference : ->Change-Id: Ifabb6c5db50061f077a03932940190af74e2ca7f ->BUG: 1355956 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/14906 ->Reviewed-by: soumya k ->NetBSD-regression: NetBSD Build System ->Smoke: Gluster Build System ->Reviewed-by: Kaleb KEITHLEY ->CentOS-regression: Gluster Build System ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: Ifabb6c5db50061f077a03932940190af74e2ca7f -BUG: 1348949 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84776 -Reviewed-by: Soumya Koduri -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - extras/ganesha/scripts/ganesha-ha.sh | 34 ++++++++-- - xlators/mgmt/glusterd/src/Makefile.am | 2 +- - xlators/mgmt/glusterd/src/glusterd-ganesha.c | 101 +++++++++++++++++++++----- - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 19 ++++-- - 4 files changed, 125 insertions(+), 31 deletions(-) - -diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh -index 8b55abb..31c0c39 100644 ---- a/extras/ganesha/scripts/ganesha-ha.sh -+++ b/extras/ganesha/scripts/ganesha-ha.sh -@@ -22,9 +22,9 @@ - - HA_NUM_SERVERS=0 - HA_SERVERS="" --HA_CONFDIR="/etc/ganesha" - HA_VOL_NAME="gluster_shared_storage" - HA_VOL_MNT="/var/run/gluster/shared_storage" -+HA_CONFDIR=$HA_VOL_MNT"/nfs-ganesha" - SERVICE_MAN="DISTRO_NOT_FOUND" - - RHEL6_PCS_CNAME_OPTION="--name" -@@ -416,12 +416,8 @@ teardown_cluster() - - cleanup_ganesha_config () - { -- rm -rf ${HA_CONFDIR}/exports/*.conf -- rm -rf ${HA_CONFDIR}/.export_added - rm -rf /etc/cluster/cluster.conf* - rm -rf /var/lib/pacemaker/cib/* -- sed -r -i -e '/^%include[[:space:]]+".+\.conf"$/d' ${GANESHA_CONF} -- rm -rf ${HA_VOL_MNT}/nfs-ganesha - } - - do_create_virt_ip_constraints() -@@ -830,6 +826,29 @@ status() - rm -f ${status_file} - } - -+create_ganesha_conf_file() -+{ -+ if [ $1 == "yes" ]; -+ then -+ if [ -e $GANESHA_CONF ]; -+ then -+ rm -rf $GANESHA_CONF -+ fi -+ # The symlink /etc/ganesha/ganesha.conf need to be -+ # created using ganesha conf file mentioned in the -+ # shared storage. Every node will only have this -+ # link and actual file will stored in shared storage, -+ # so that ganesha conf editing of ganesha conf will -+ # be easy as well as it become more consistent. -+ -+ ln -s $HA_CONFDIR/ganesha.conf $GANESHA_CONF -+ else -+ # Restoring previous file -+ rm -rf $GANESHA_CONF -+ sed -r -i -e '/^%include[[:space:]]+".+\.conf"$/d' $HA_CONFDIR/ganesha.conf -+ cp $HA_CONFDIR/ganesha.conf $GANESHA_CONF -+ fi -+} - - main() - { -@@ -971,6 +990,11 @@ $HA_CONFDIR/ganesha-ha.conf - refresh_config ${VOL} ${HA_CONFDIR} ${HA_SERVERS} - ;; - -+ setup-ganesha-conf-files | --setup-ganesha-conf-files) -+ -+ create_ganesha_conf_file ${1} -+ ;; -+ - *) - # setup and teardown are not intended to be used by a - # casual user -diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am -index f3381e3..23840cd 100644 ---- a/xlators/mgmt/glusterd/src/Makefile.am -+++ b/xlators/mgmt/glusterd/src/Makefile.am -@@ -47,7 +47,7 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ - -I$(CONTRIBDIR)/userspace-rcu \ - -DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\" \ -- -DCONFDIR=\"$(sysconfdir)/ganesha\" \ -+ -DCONFDIR=\"/$(runstatedir)/gluster/shared_storage/nfs-ganesha\" \ - -DGANESHA_PREFIX=\"$(libexecdir)/ganesha\" \ - -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(XML_CPPFLAGS) - -diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -index d34ec05..3d9a10e 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c -+++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -@@ -22,8 +22,6 @@ - - #include - --#define SHARED_STORAGE_MNT "/var/run/gluster/shared_storage/nfs-ganesha" -- - int start_ganesha (char **op_errstr); - - -@@ -267,6 +265,11 @@ glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr) - "Could not start NFS-Ganesha"); - - } -+ } else { -+ ret = stop_ganesha (op_errstr); -+ if (ret) -+ gf_msg_debug (THIS->name, 0, "Could not stop " -+ "NFS-Ganesha."); - } - - out: -@@ -638,8 +641,12 @@ out: - int - tear_down_cluster(void) - { -- int ret = 0; -- runner_t runner = {0,}; -+ int ret = 0; -+ runner_t runner = {0,}; -+ struct stat st = {0,}; -+ DIR *dir = NULL; -+ struct dirent *entry = NULL; -+ char path[PATH_MAX] = {0,}; - - if (is_ganesha_host()) { - runinit (&runner); -@@ -647,7 +654,55 @@ tear_down_cluster(void) - GANESHA_PREFIX"/ganesha-ha.sh", "teardown", - CONFDIR, NULL); - ret = runner_run(&runner); -+ /* * -+ * Remove all the entries in CONFDIR expect ganesha.conf and -+ * ganesha-ha.conf -+ */ -+ dir = sys_opendir (CONFDIR); -+ if (!dir) { -+ gf_msg_debug (THIS->name, 0, "Failed to open directory %s. " -+ "Reason : %s", CONFDIR, strerror (errno)); -+ ret = 0; -+ goto out; -+ } -+ -+ GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); -+ while (entry) { -+ snprintf (path, PATH_MAX, "%s/%s", CONFDIR, entry->d_name); -+ ret = sys_lstat (path, &st); -+ if (ret == -1) { -+ gf_msg_debug (THIS->name, 0, "Failed to stat entry %s :" -+ " %s", path, strerror (errno)); -+ goto out; -+ } -+ -+ if (strcmp(entry->d_name, "ganesha.conf") == 0 || -+ strcmp(entry->d_name, "ganesha-ha.conf") == 0) -+ gf_msg_debug (THIS->name, 0, " %s is not required" -+ " to remove", path); -+ else if (S_ISDIR (st.st_mode)) -+ ret = recursive_rmdir (path); -+ else -+ ret = sys_unlink (path); -+ -+ if (ret) { -+ gf_msg_debug (THIS->name, 0, " Failed to remove %s. " -+ "Reason : %s", path, strerror (errno)); -+ } -+ -+ gf_msg_debug (THIS->name, 0, "%s %s", ret ? -+ "Failed to remove" : "Removed", entry->d_name); -+ GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); -+ } -+ -+ ret = sys_closedir (dir); -+ if (ret) { -+ gf_msg_debug (THIS->name, 0, "Failed to close dir %s. Reason :" -+ " %s", CONFDIR, strerror (errno)); -+ } - } -+ -+out: - return ret; - } - -@@ -685,11 +740,6 @@ teardown (char **op_errstr) - " HA config failed."); - goto out; - } -- ret = stop_ganesha (op_errstr); -- if (ret) { -- gf_asprintf (op_errstr, "Could not stop NFS-Ganesha."); -- goto out; -- } - - runinit (&runner); - runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", -@@ -733,7 +783,17 @@ out: - int - stop_ganesha (char **op_errstr) { - -- int ret = 0; -+ int ret = 0; -+ runner_t runner = {0,}; -+ -+ runinit (&runner); -+ runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", -+ "--setup-ganesha-conf-files", CONFDIR, "no", NULL); -+ ret = runner_run (&runner); -+ if (ret) { -+ gf_asprintf (op_errstr, "removal of symlink ganesha.conf " -+ "in /etc/ganesha failed"); -+ } - - if (check_host_list ()) { - ret = manage_service ("stop"); -@@ -755,6 +815,7 @@ start_ganesha (char **op_errstr) - int count = 0; - char *volname = NULL; - glusterd_conf_t *priv = NULL; -+ runner_t runner = {0,}; - - priv = THIS->private; - GF_ASSERT (priv); -@@ -789,6 +850,16 @@ start_ganesha (char **op_errstr) - goto out; - } - } -+ -+ runinit (&runner); -+ runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", -+ "--setup-ganesha-conf-files", CONFDIR, "yes", NULL); -+ ret = runner_run (&runner); -+ if (ret) { -+ gf_asprintf (op_errstr, "creation of symlink ganesha.conf " -+ "in /etc/ganesha failed"); -+ goto out; -+ } - if (check_host_list()) { - ret = manage_service ("start"); - if (ret) -@@ -805,15 +876,6 @@ pre_setup (char **op_errstr) - { - int ret = 0; - -- ret = sys_mkdir (SHARED_STORAGE_MNT, 0775); -- -- if ((-1 == ret) && (EEXIST != errno)) { -- gf_msg ("THIS->name", GF_LOG_ERROR, errno, -- GD_MSG_CREATE_DIR_FAILED, "mkdir() failed on path %s,", -- SHARED_STORAGE_MNT); -- goto out; -- } -- - ret = check_host_list(); - - if (ret) { -@@ -824,7 +886,6 @@ pre_setup (char **op_errstr) - "Please check the log file for details"); - } - --out: - return ret; - } - -diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index d138e81..4b88570 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c -+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -1422,10 +1422,14 @@ glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr) - char *key_fixed = NULL; - glusterd_volinfo_t *volinfo = NULL; - xlator_t *this = NULL; -+ glusterd_conf_t *priv = NULL; - - this = THIS; - GF_ASSERT (this); - -+ priv = this->private; -+ GF_ASSERT (priv); -+ - ret = dict_get_str (dict, "volname", &volname); - - if (ret) { -@@ -1452,6 +1456,16 @@ glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr) - ret = glusterd_validate_volume_id (dict, volinfo); - if (ret) - goto out; -+ ret = dict_get_str_boolean (priv->opts, -+ GLUSTERD_STORE_KEY_GANESHA_GLOBAL, _gf_false); -+ if (ret) { -+ ret = stop_ganesha (op_errstr); -+ if (ret) -+ gf_msg (THIS->name, GF_LOG_WARNING, 0, -+ GD_MSG_NFS_GNS_STOP_FAIL, -+ "Could not stop NFS-Ganesha service"); -+ } -+ - } - - ret = dict_get_str (dict, "key", &key); -@@ -2038,11 +2052,6 @@ glusterd_op_reset_all_volume_options (xlator_t *this, dict_t *dict) - gf_msg (THIS->name, GF_LOG_WARNING, errno, - GD_MSG_DICT_GET_FAILED, - "Could not tear down NFS-Ganesha cluster"); -- ret = stop_ganesha (&op_errstr); -- if (ret) -- gf_msg (THIS->name, GF_LOG_WARNING, 0, -- GD_MSG_NFS_GNS_STOP_FAIL, -- "Could not stop NFS-Ganesha service"); - } - - ret = -1; --- -1.7.1 - diff --git a/SOURCES/0055-glusterd-ganesha-throw-proper-error-for-gluster-nfs-.patch b/SOURCES/0055-glusterd-ganesha-throw-proper-error-for-gluster-nfs-.patch new file mode 100644 index 0000000..d98316c --- /dev/null +++ b/SOURCES/0055-glusterd-ganesha-throw-proper-error-for-gluster-nfs-.patch @@ -0,0 +1,125 @@ +From 6683f3c2702f635a95623c427f343385a1ad8c63 Mon Sep 17 00:00:00 2001 +From: jiffin tony thottan +Date: Mon, 7 Dec 2015 14:38:54 +0530 +Subject: [PATCH 55/74] glusterd/ganesha : throw proper error for "gluster + nfs-ganesha disable" + +For first time or if "gluster nfs-ganesha enable" fails the global option +"nfs-ganesha" won't be stored in glusterd's dictionary. In both cases the +"gluster nfs-ganesha disable" throws following error : +"nfs-ganesha: failed: nfs-ganesha is already (null)d." + +Also this patch provides the missing prompt for nfs-ganesha disable in 3.10 + +Change-Id: I7c9fd6dabedc0cfb14c5190b3554bc63a6bc0340 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/16791 +Smoke: Gluster Build System +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: soumya k +Reviewed-by: Kaleb KEITHLEY +--- + cli/src/cli-cmd-parser.c | 30 ++++++++++++++++++---------- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 28 +++++++++----------------- + 2 files changed, 28 insertions(+), 30 deletions(-) + +diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c +index a4c601b..a35fc74 100644 +--- a/cli/src/cli-cmd-parser.c ++++ b/cli/src/cli-cmd-parser.c +@@ -897,18 +897,26 @@ cli_cmd_ganesha_parse (struct cli_state *state, + goto out; + } + +- question = "Enabling NFS-Ganesha requires Gluster-NFS to be" +- " disabled across the trusted pool. Do you " +- "still want to continue?\n"; +- + if (strcmp (value, "enable") == 0) { +- answer = cli_cmd_get_confirmation (state, question); +- if (GF_ANSWER_NO == answer) { +- gf_log ("cli", GF_LOG_ERROR, "Global operation " +- "cancelled, exiting"); +- ret = -1; +- goto out; +- } ++ question = "Enabling NFS-Ganesha requires Gluster-NFS to be " ++ "disabled across the trusted pool. Do you " ++ "still want to continue?\n"; ++ ++ } else if (strcmp (value, "disable") == 0) { ++ question = "Disabling NFS-Ganesha will tear down the entire " ++ "ganesha cluster across the trusted pool. Do you " ++ "still want to continue?\n"; ++ } else { ++ ret = -1; ++ goto out; ++ } ++ ++ answer = cli_cmd_get_confirmation (state, question); ++ if (GF_ANSWER_NO == answer) { ++ gf_log ("cli", GF_LOG_ERROR, "Global operation " ++ "cancelled, exiting"); ++ ret = -1; ++ goto out; + } + cli_out ("This will take a few minutes to complete. Please wait .."); + +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index e176df9..5c582cd 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -258,8 +258,7 @@ int + glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr) + { + int ret = -1; +- int value = -1; +- gf_boolean_t option = _gf_false; ++ char *value = NULL; + char *str = NULL; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; +@@ -270,8 +269,8 @@ glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr) + priv = this->private; + GF_ASSERT (priv); + +- value = dict_get_str_boolean (dict, "value", _gf_false); +- if (value == -1) { ++ ret = dict_get_str (dict, "value", &value); ++ if (value == NULL) { + gf_msg (this->name, GF_LOG_ERROR, errno, + GD_MSG_DICT_GET_FAILED, + "value not present."); +@@ -280,22 +279,13 @@ glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr) + /* This dict_get will fail if the user had never set the key before */ + /*Ignoring the ret value and proceeding */ + ret = dict_get_str (priv->opts, GLUSTERD_STORE_KEY_GANESHA_GLOBAL, &str); +- if (ret == -1) { +- gf_msg (this->name, GF_LOG_WARNING, errno, +- GD_MSG_DICT_GET_FAILED, "Global dict not present."); +- ret = 0; +- goto out; ++ /* Check if the feature is already enabled/disable, fail in that case */ ++ if (str ? strcmp (value, str) == 0 : strcmp (value, "disable") == 0) { ++ gf_asprintf (op_errstr, "nfs-ganesha is already %sd.", value); ++ ret = -1; ++ goto out; + } +- /* Validity of the value is already checked */ +- ret = gf_string2boolean (str, &option); +- /* Check if the feature is already enabled, fail in that case */ +- if (value == option) { +- gf_asprintf (op_errstr, "nfs-ganesha is already %sd.", str); +- ret = -1; +- goto out; +- } +- +- if (value) { ++ if (strcmp (value, "enable") == 0) { + ret = start_ganesha (op_errstr); + if (ret) { + gf_msg (THIS->name, GF_LOG_ERROR, 0, +-- +1.8.3.1 + diff --git a/SOURCES/0056-ganesha-scripts-Stop-ganesha-process-on-all-nodes-if.patch b/SOURCES/0056-ganesha-scripts-Stop-ganesha-process-on-all-nodes-if.patch new file mode 100644 index 0000000..675b65b --- /dev/null +++ b/SOURCES/0056-ganesha-scripts-Stop-ganesha-process-on-all-nodes-if.patch @@ -0,0 +1,54 @@ +From 72869da97db070bc00cc0934aebdb8f247b05b55 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Thu, 2 Mar 2017 12:22:30 +0530 +Subject: [PATCH 56/74] ganesha/scripts : Stop ganesha process on all nodes if + cluster setup fails + +During staging phase of volume option "nfs-ganesha", symlink "ganesha.conf" +will be created plus ganesha process will be started. The cluster setup +happens during commit phase of that option. So if cluster set up fails, the +ganesha process will be running on all cluster nodes. + +Change-Id: Ib2cb85364b7ef5b702acb4826ffdf8e6f31a2acd +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/16823 +Smoke: Gluster Build System +Tested-by: Kaleb KEITHLEY +Reviewed-by: soumya k +Reviewed-by: Kaleb KEITHLEY +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +--- + extras/ganesha/scripts/ganesha-ha.sh | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index 2d6b06f..df4f0b8 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -175,6 +175,13 @@ determine_servers() + fi + } + ++stop_ganesha_all() ++{ ++ local serverlist=${1} ++ for node in ${serverlist} ; do ++ manage_service "stop" ${node} ++ done ++} + + setup_cluster() + { +@@ -191,6 +198,8 @@ setup_cluster() + pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --transport udpu ${servers} + if [ $? -ne 0 ]; then + logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed" ++ #set up failed stop all ganesha process and clean up symlinks in cluster ++ stop_ganesha_all ${servers} + exit 1; + fi + pcs cluster start --all +-- +1.8.3.1 + diff --git a/SOURCES/0056-ganesha-scripts-remove-HA_VOL_SERVER-from-the-code.patch b/SOURCES/0056-ganesha-scripts-remove-HA_VOL_SERVER-from-the-code.patch deleted file mode 100644 index d004829..0000000 --- a/SOURCES/0056-ganesha-scripts-remove-HA_VOL_SERVER-from-the-code.patch +++ /dev/null @@ -1,288 +0,0 @@ -From 45aa6c07554a20903ad12ee00b0ed9b6b403d8f0 Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Mon, 27 Jun 2016 15:08:25 +0530 -Subject: [PATCH 56/86] ganesha/scripts : remove 'HA_VOL_SERVER' from the code - -The parameter HA_VOL_SERVER introduced intially ganesha-ha.conf to -specify gluster server from which to mount the shared data volume. -But after introducing new cli for the same purpose, it become -unnecessary. The existence of that parameter can lead confussion -to the users. This patch will remove/replace all the instance of -HA_VOL_SERVER from the code - -Upstream reference: ->Change-Id: I638c61dcd2c21ebdb279bbb141d35bb806bd3ef0 ->BUG: 1350371 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/14812 ->Tested-by: Kaleb KEITHLEY ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: soumya k ->Smoke: Gluster Build System ->Reviewed-by: Kaleb KEITHLEY ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: I638c61dcd2c21ebdb279bbb141d35bb806bd3ef0 -BUG: 1348954 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84777 -Reviewed-by: Soumya Koduri -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - extras/ganesha/config/ganesha-ha.conf.sample | 3 - - extras/ganesha/scripts/ganesha-ha.sh | 34 +++------------ - xlators/mgmt/glusterd/src/glusterd-ganesha.c | 62 +++++++------------------ - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 2 +- - xlators/mgmt/glusterd/src/glusterd.h | 2 +- - 5 files changed, 26 insertions(+), 77 deletions(-) - -diff --git a/extras/ganesha/config/ganesha-ha.conf.sample b/extras/ganesha/config/ganesha-ha.conf.sample -index 2077800..c22892b 100644 ---- a/extras/ganesha/config/ganesha-ha.conf.sample -+++ b/extras/ganesha/config/ganesha-ha.conf.sample -@@ -2,9 +2,6 @@ - # must be unique within the subnet - HA_NAME="ganesha-ha-360" - # --# The gluster server from which to mount the shared data volume. --HA_VOL_SERVER="server1" --# - # N.B. you may use short names or long names; you may not use IP addrs. - # Once you select one, stay with it as it will be mildly unpleasant to - # clean up if you switch later on. Ensure that all names - short and/or -diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh -index 31c0c39..ada21cb 100644 ---- a/extras/ganesha/scripts/ganesha-ha.sh -+++ b/extras/ganesha/scripts/ganesha-ha.sh -@@ -341,35 +341,15 @@ string:"EXPORT(Path=/$VOL)" 2>&1) - copy_export_config () - { - local new_node=${1} -- local tganesha_conf=$(mktemp) -- local tganesha_exports=$(mktemp -d) -- local short_host=$(hostname -s) -- # avoid prompting for password, even with password-less scp -- # scp $host1:$file $host2:$file prompts for the password -- # Ideally all the existing nodes in the cluster should have same -- # copy of the configuration files. Maybe for sanity check, copy -- # the state from HA_VOL_SERVER? -- if [ "${HA_VOL_SERVER}" == $(hostname) ] -- then -- cp ${GANESHA_CONF} ${tganesha_conf} -- else -- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${HA_VOL_SERVER}:${GANESHA_CONF} $short_host:${tganesha_conf} -- fi -+ -+ # The add node should be executed from one of the nodes in ganesha -+ # cluster. So all the configuration file will be available in that -+ # node itself. So just copy that to new node - scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${tganesha_conf} ${new_node}:${GANESHA_CONF} -- rm -f ${tganesha_conf} -+${SECRET_PEM} ${GANESHA_CONF} ${new_node}:${GANESHA_CONF} - -- if [ "${HA_VOL_SERVER}" == $(hostname) ] -- then -- cp -r ${HA_CONFDIR}/exports ${tganesha_exports} -- else -- scp -r -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${HA_VOL_SERVER}:${HA_CONFDIR}/exports/ $short_host:${tganesha_exports} -- fi - scp -r -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${tganesha_exports}/exports ${new_node}:${HA_CONFDIR}/ -- rm -rf ${tganesha_exports} -+${SECRET_PEM} ${HA_CONFDIR}/exports/ ${new_node}:${HA_CONFDIR}/ - } - - -@@ -867,8 +847,6 @@ main() - # ignore any comment lines - cfgline=$(grep ^HA_NAME= ${ha_conf}) - eval $(echo ${cfgline} | grep -F HA_NAME=) -- cfgline=$(grep ^HA_VOL_SERVER= ${ha_conf}) -- eval $(echo ${cfgline} | grep -F HA_VOL_SERVER=) - cfgline=$(grep ^HA_CLUSTER_NODES= ${ha_conf}) - eval $(echo ${cfgline} | grep -F HA_CLUSTER_NODES=) - fi -diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -index 3d9a10e..2406519 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c -+++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -@@ -364,46 +364,14 @@ out: - return ret; - } - --/* Following 2 functions parse GANESHA_HA_CONF -+/* Following function parse GANESHA_HA_CONF - * The sample file looks like below, - * HA_NAME="ganesha-ha-360" - * HA_VOL_NAME="ha-state" -- * HA_VOL_MNT="/mount-point" -- * HA_VOL_SERVER="server1" - * HA_CLUSTER_NODES="server1,server2" - * VIP_rhs_1="10.x.x.x" - * VIP_rhs_2="10.x.x.x." */ - --gf_boolean_t --is_ganesha_host (void) --{ -- char *host_from_file = NULL; -- gf_boolean_t ret = _gf_false; -- xlator_t *this = NULL; -- -- this = THIS; -- -- host_from_file = parsing_ganesha_ha_conf ("HA_VOL_SERVER"); -- if (host_from_file == NULL) { -- gf_msg (this->name, GF_LOG_INFO, errno, -- GD_MSG_GET_CONFIG_INFO_FAILED, -- "couldn't get HA_VOL_SERVER from file %s", -- GANESHA_HA_CONF); -- return _gf_false; -- } -- -- ret = gf_is_local_addr (host_from_file); -- if (ret) { -- gf_msg (this->name, GF_LOG_INFO, 0, -- GD_MSG_NFS_GNS_HOST_FOUND, -- "ganesha host found " -- "Hostname is %s", host_from_file); -- } -- -- GF_FREE (host_from_file); -- return ret; --} -- - /* Check if the localhost is listed as one of nfs-ganesha nodes */ - gf_boolean_t - check_host_list (void) -@@ -411,7 +379,7 @@ check_host_list (void) - - glusterd_conf_t *priv = NULL; - char *hostname, *hostlist; -- int ret = _gf_false; -+ gf_boolean_t ret = _gf_false; - xlator_t *this = NULL; - - this = THIS; -@@ -639,7 +607,7 @@ out: - } - - int --tear_down_cluster(void) -+tear_down_cluster(gf_boolean_t run_teardown) - { - int ret = 0; - runner_t runner = {0,}; -@@ -648,7 +616,7 @@ tear_down_cluster(void) - struct dirent *entry = NULL; - char path[PATH_MAX] = {0,}; - -- if (is_ganesha_host()) { -+ if (run_teardown) { - runinit (&runner); - runner_add_args (&runner, "sh", - GANESHA_PREFIX"/ganesha-ha.sh", "teardown", -@@ -708,12 +676,12 @@ out: - - - int --setup_cluster(void) -+setup_cluster(gf_boolean_t run_setup) - { - int ret = 0; - runner_t runner = {0,}; - -- if (is_ganesha_host()) { -+ if (run_setup) { - runinit (&runner); - runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", - "setup", CONFDIR, NULL); -@@ -724,7 +692,7 @@ setup_cluster(void) - - - static int --teardown (char **op_errstr) -+teardown (gf_boolean_t run_teardown, char **op_errstr) - { - runner_t runner = {0,}; - int ret = 1; -@@ -734,7 +702,7 @@ teardown (char **op_errstr) - - priv = THIS->private; - -- ret = tear_down_cluster(); -+ ret = tear_down_cluster (run_teardown); - if (ret == -1) { - gf_asprintf (op_errstr, "Cleanup of NFS-Ganesha" - " HA config failed."); -@@ -872,14 +840,14 @@ out: - } - - static int --pre_setup (char **op_errstr) -+pre_setup (gf_boolean_t run_setup, char **op_errstr) - { - int ret = 0; - - ret = check_host_list(); - - if (ret) { -- ret = setup_cluster(); -+ ret = setup_cluster(run_setup); - if (ret == -1) - gf_asprintf (op_errstr, "Failed to set up HA " - "config for NFS-Ganesha. " -@@ -926,12 +894,18 @@ glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, - } - - if (strcmp (key, GLUSTERD_STORE_KEY_GANESHA_GLOBAL) == 0) { -+ /* * -+ * The set up/teardown of pcs cluster should be performed only -+ * once. This will done on the node in which the cli command -+ * 'gluster nfs-ganesha ' got executed. So that -+ * node should part of ganesha HA cluster -+ */ - if (option) { -- ret = pre_setup (op_errstr); -+ ret = pre_setup (is_origin_glusterd (dict), op_errstr); - if (ret < 0) - goto out; - } else { -- ret = teardown (op_errstr); -+ ret = teardown (is_origin_glusterd (dict), op_errstr); - if (ret < 0) - goto out; - } -diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index 4b88570..313e3de 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c -+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -2047,7 +2047,7 @@ glusterd_op_reset_all_volume_options (xlator_t *this, dict_t *dict) - option = dict_get_str_boolean (conf->opts, GLUSTERD_STORE_KEY_GANESHA_GLOBAL, - _gf_false); - if (option) { -- ret = tear_down_cluster(); -+ ret = tear_down_cluster (is_origin_glusterd (dict)); - if (ret == -1) - gf_msg (THIS->name, GF_LOG_WARNING, errno, - GD_MSG_DICT_GET_FAILED, -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index f5e090d..7ca589c 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -1072,7 +1072,7 @@ int ganesha_manage_export (char *volname, char *value, char **op_errstr, - gf_boolean_t reboot); - gf_boolean_t glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo); - int stop_ganesha (char **op_errstr); --int tear_down_cluster (void); -+int tear_down_cluster (gf_boolean_t run_teardown); - int glusterd_op_add_brick (dict_t *dict, char **op_errstr); - int glusterd_op_remove_brick (dict_t *dict, char **op_errstr); - int glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, --- -1.7.1 - diff --git a/SOURCES/0057-afr-add-replication-events.patch b/SOURCES/0057-afr-add-replication-events.patch deleted file mode 100644 index b9d80ea..0000000 --- a/SOURCES/0057-afr-add-replication-events.patch +++ /dev/null @@ -1,277 +0,0 @@ -From 07af401ec6a375203d9c842b6436c3b248230900 Mon Sep 17 00:00:00 2001 -From: Ravishankar N -Date: Fri, 16 Sep 2016 17:02:08 +0530 -Subject: [PATCH 57/86] afr: add replication events - -Patch in master: http://review.gluster.org/#/c/15349/ -Patch in release-3.9:http://review.gluster.org/#/c/15417/ - -Added the following events for the eventing framework: - - "EVENT_AFR_QUORUM_MET", --> Sent when quorum is met. - "EVENT_AFR_QUORUM_FAIL" -->Sent when quorum is lost. - "EVENT_AFR_SUBVOL_UP" -->Sent when afr witnesses the first up subvolume. - "EVENT_AFR_SUBVOLS_DOWN"-->Sent when all children of an afr subvol are down. - "EVENT_AFR_SPLIT_BRAIN" -->Sent when self-heal detects split-brain in heal - path (not read/write path). - -Change-Id: I94828c57dc343062392e65ade0e1a6f93e3d152f -BUG: 1361082 -Signed-off-by: Ravishankar N -Reviewed-on: https://code.engineering.redhat.com/gerrit/84802 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - xlators/cluster/afr/src/afr-common.c | 16 +++++++- - xlators/cluster/afr/src/afr-self-heal-common.c | 8 ++++ - xlators/cluster/afr/src/afr-self-heal-entry.c | 27 ++++++++++++-- - xlators/cluster/afr/src/afr-self-heal-name.c | 47 +++++++++++++++++++----- - 4 files changed, 82 insertions(+), 16 deletions(-) - -diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c -index 9b2c0d7..8f0de59 100644 ---- a/xlators/cluster/afr/src/afr-common.c -+++ b/xlators/cluster/afr/src/afr-common.c -@@ -31,6 +31,7 @@ - #include "byte-order.h" - #include "statedump.h" - #include "inode.h" -+#include "events.h" - - #include "fd.h" - -@@ -4292,6 +4293,9 @@ afr_notify (xlator_t *this, int32_t event, - AFR_MSG_SUBVOL_UP, - "Subvolume '%s' came back up; " - "going online.", ((xlator_t *)data)->name); -+ gf_event (EVENT_AFR_SUBVOL_UP, -+ "subvol=%s", this->name); -+ - } else { - event = GF_EVENT_CHILD_MODIFIED; - } -@@ -4314,6 +4318,8 @@ afr_notify (xlator_t *this, int32_t event, - AFR_MSG_ALL_SUBVOLS_DOWN, - "All subvolumes are down. Going offline " - "until atleast one of them comes back up."); -+ gf_event (EVENT_AFR_SUBVOLS_DOWN, -+ "subvol=%s", this->name); - } else { - event = GF_EVENT_SOME_CHILD_DOWN; - } -@@ -4365,13 +4371,19 @@ afr_notify (xlator_t *this, int32_t event, - - if (priv->quorum_count) { - has_quorum = afr_has_quorum (priv->child_up, this); -- if (!had_quorum && has_quorum) -+ if (!had_quorum && has_quorum) { - gf_msg (this->name, GF_LOG_INFO, 0, AFR_MSG_QUORUM_MET, - "Client-quorum is met"); -- if (had_quorum && !has_quorum) -+ gf_event (EVENT_AFR_QUORUM_MET, -+ "subvol=%s", this->name); -+ } -+ if (had_quorum && !has_quorum) { - gf_msg (this->name, GF_LOG_WARNING, 0, - AFR_MSG_QUORUM_FAIL, - "Client-quorum is not met"); -+ gf_event (EVENT_AFR_QUORUM_FAIL, "subvol=%s", -+ this->name); -+ } - } - - /* if all subvols have reported status, no need to hide anything -diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c -index 58db6d1..d7ffb35 100644 ---- a/xlators/cluster/afr/src/afr-self-heal-common.c -+++ b/xlators/cluster/afr/src/afr-self-heal-common.c -@@ -14,6 +14,7 @@ - #include "byte-order.h" - #include "protocol-common.h" - #include "afr-messages.h" -+#include "events.h" - - void - afr_heal_synctask (xlator_t *this, afr_local_t *local); -@@ -1653,6 +1654,13 @@ afr_selfheal_unlocked_inspect (call_frame_t *frame, xlator_t *this, - (int) replies[i].poststat.ia_type, - priv->children[i]->name, - uuid_utoa (replies[i].poststat.ia_gfid)); -+ gf_event (EVENT_AFR_SPLIT_BRAIN, "subvol=%s;" -+ "msg=file type mismatch;gfid=%s;" -+ "ia_type-%d=%s;ia_type-%d=%s", -+ this->name, -+ uuid_utoa (replies[i].poststat.ia_gfid), first, -+ gf_inode_type_to_str (first.ia_type), i, -+ gf_inode_type_to_str (replies[i].poststat.ia_type)); - ret = -EIO; - goto out; - } -diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c -index 985cebe..bf55ede 100644 ---- a/xlators/cluster/afr/src/afr-self-heal-entry.c -+++ b/xlators/cluster/afr/src/afr-self-heal-entry.c -@@ -15,6 +15,7 @@ - #include "afr-transaction.h" - #include "afr-messages.h" - #include "syncop-utils.h" -+#include "events.h" - - /* Max file name length is 255 this filename is of length 256. No file with - * this name can ever come, entry-lock with this name is going to prevent -@@ -240,13 +241,22 @@ afr_selfheal_detect_gfid_and_type_mismatch (xlator_t *this, - replies[i].poststat.ia_gfid)) { - gf_msg (this->name, GF_LOG_ERROR, 0, - AFR_MSG_SPLIT_BRAIN, "Gfid mismatch " -- "detected for <%s/%s>, %s on %s and %s on %s. " -+ "detected for /%s>, %s on %s and %s on %s. " - "Skipping conservative merge on the file.", - uuid_utoa (pargfid), bname, - uuid_utoa_r (replies[i].poststat.ia_gfid, g1), - priv->children[i]->name, - uuid_utoa_r (replies[src_idx].poststat.ia_gfid, - g2), priv->children[src_idx]->name); -+ gf_event (EVENT_AFR_SPLIT_BRAIN, -+ "subvol=%s;msg=gfid mismatch. Skipping " -+ "conservative merge.;file=/%s>;count=2;" -+ "child-%d=%s;gfid-%d=%s;child-%d=%s;gfid-%d=%s", -+ this->name, uuid_utoa (pargfid), bname, i, -+ priv->children[i]->name, i, -+ uuid_utoa_r (replies[i].poststat.ia_gfid, g1), -+ src_idx, priv->children[src_idx]->name, src_idx, -+ uuid_utoa_r (replies[src_idx].poststat.ia_gfid, g2)); - return -1; - } - -@@ -254,13 +264,22 @@ afr_selfheal_detect_gfid_and_type_mismatch (xlator_t *this, - (replies[i].poststat.ia_type)) { - gf_msg (this->name, GF_LOG_ERROR, 0, - AFR_MSG_SPLIT_BRAIN, "Type mismatch " -- "detected for <%s/%s>, %d on %s and %d on %s. " -+ "detected for /%s>, %s on %s and %s on %s. " - "Skipping conservative merge on the file.", - uuid_utoa (pargfid), bname, -- replies[i].poststat.ia_type, -+ gf_inode_type_to_str (replies[i].poststat.ia_type), - priv->children[i]->name, -- replies[src_idx].poststat.ia_type, -+ gf_inode_type_to_str (replies[src_idx].poststat.ia_type), - priv->children[src_idx]->name); -+ gf_event (EVENT_AFR_SPLIT_BRAIN, -+ "subvol=%s;msg=file type mismatch. Skipping " -+ "conservative merge;file=/%s>;count=2;" -+ "child-%d=%s;type-%d=%s;child-%d=%s;type-%d=%s", -+ this->name, uuid_utoa (pargfid), bname, i, -+ priv->children[i]->name, i, -+ gf_inode_type_to_str(replies[i].poststat.ia_type), -+ src_idx, priv->children[src_idx]->name, src_idx, -+ gf_inode_type_to_str(replies[src_idx].poststat.ia_type)); - return -1; - } - } -diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c -index 3445ecc..acacea8 100644 ---- a/xlators/cluster/afr/src/afr-self-heal-name.c -+++ b/xlators/cluster/afr/src/afr-self-heal-name.c -@@ -9,6 +9,7 @@ - */ - - -+#include "events.h" - #include "afr.h" - #include "afr-self-heal.h" - #include "afr-messages.h" -@@ -274,6 +275,7 @@ afr_selfheal_name_type_mismatch_check (xlator_t *this, struct afr_reply *replies - int i = 0; - int type_idx = -1; - ia_type_t inode_type = IA_INVAL; -+ ia_type_t inode_type1 = IA_INVAL; - afr_private_t *priv = NULL; - - priv = this->private; -@@ -290,21 +292,32 @@ afr_selfheal_name_type_mismatch_check (xlator_t *this, struct afr_reply *replies - type_idx = i; - continue; - } -- -+ inode_type1 = replies[i].poststat.ia_type; - if (sources[i] || source == -1) { - if ((sources[type_idx] || source == -1) && -- (inode_type != replies[i].poststat.ia_type)) { -+ (inode_type != inode_type1)) { - gf_msg (this->name, GF_LOG_WARNING, 0, - AFR_MSG_SPLIT_BRAIN, - "Type mismatch for /%s: " -- "%d on %s and %d on %s", -+ "%s on %s and %s on %s", - uuid_utoa(pargfid), bname, -- replies[i].poststat.ia_type, -+ gf_inode_type_to_str (inode_type1), - priv->children[i]->name, -- replies[type_idx].poststat.ia_type, -+ gf_inode_type_to_str (inode_type), - priv->children[type_idx]->name); -- -- return -EIO; -+ gf_event (EVENT_AFR_SPLIT_BRAIN, -+ "subvol=%s;msg=file type mismatch;" -+ "file=/%s;count=2;" -+ "child-%d=%s;type-%d=%s;child-%d=%s;" -+ "type-%d=%s", this->name, -+ uuid_utoa (pargfid), bname, i, -+ priv->children[i]->name, i, -+ gf_inode_type_to_str (inode_type1), -+ type_idx, -+ priv->children[type_idx]->name, -+ type_idx, -+ gf_inode_type_to_str (inode_type)); -+ return -EIO; - } - inode_type = replies[i].poststat.ia_type; - type_idx = i; -@@ -322,6 +335,7 @@ afr_selfheal_name_gfid_mismatch_check (xlator_t *this, struct afr_reply *replies - int i = 0; - int gfid_idx_iter = -1; - void *gfid = NULL; -+ void *gfid1 = NULL; - afr_private_t *priv = NULL; - char g1[64], g2[64]; - -@@ -340,18 +354,31 @@ afr_selfheal_name_gfid_mismatch_check (xlator_t *this, struct afr_reply *replies - continue; - } - -+ gfid1 = &replies[i].poststat.ia_gfid; - if (sources[i] || source == -1) { - if ((sources[gfid_idx_iter] || source == -1) && -- gf_uuid_compare (gfid, replies[i].poststat.ia_gfid)) { -+ gf_uuid_compare (gfid, gfid1)) { - gf_msg (this->name, GF_LOG_WARNING, 0, - AFR_MSG_SPLIT_BRAIN, - "GFID mismatch for /%s " - "%s on %s and %s on %s", - uuid_utoa (pargfid), bname, -- uuid_utoa_r (replies[i].poststat.ia_gfid, g1), -+ uuid_utoa_r (gfid1, g1), - priv->children[i]->name, -- uuid_utoa_r (replies[gfid_idx_iter].poststat.ia_gfid, g2), -+ uuid_utoa_r (gfid, g2), - priv->children[gfid_idx_iter]->name); -+ gf_event (EVENT_AFR_SPLIT_BRAIN, -+ "subvol=%s;msg=gfid mismatch;" -+ "file=/%s;count=2;" -+ "child-%d=%s;gfid-%d=%s;child-%d=%s;" -+ "gfid-%d=%s", this->name, -+ uuid_utoa (pargfid), bname, i, -+ priv->children[i]->name, i, -+ uuid_utoa_r (gfid1, g1), -+ gfid_idx_iter, -+ priv->children[gfid_idx_iter]->name, -+ gfid_idx_iter, -+ uuid_utoa_r (gfid, g2)); - - return -EIO; - } --- -1.7.1 - diff --git a/SOURCES/0057-ganesha-allow-refresh-config-and-volume-export-unexp.patch b/SOURCES/0057-ganesha-allow-refresh-config-and-volume-export-unexp.patch new file mode 100644 index 0000000..81e892c --- /dev/null +++ b/SOURCES/0057-ganesha-allow-refresh-config-and-volume-export-unexp.patch @@ -0,0 +1,117 @@ +From 17b75c3bf216c53b4303a9c59adaf89d3da328ea Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Wed, 19 Apr 2017 16:12:10 +0530 +Subject: [PATCH 57/74] ganesha : allow refresh-config and volume + export/unexport in failover state + +If ganesha is not running on one of nodes in HA cluster, then alli dbus +commands send to that ganesha server will fail. This results in both +refresh-config and volume export/unepxort failure. This change will +gracefully handle those scenarios. + +Change-Id: I3f1b7b7ca98e54c273c266e56357d8e24dd1b14b +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/17081 +Smoke: Gluster Build System +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: soumya k +Reviewed-by: Kaleb KEITHLEY +Signed-off-by: Jiffin Tony Thottan +--- + extras/ganesha/scripts/ganesha-ha.sh | 6 ++---- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 25 ++++++++++++++++--------- + xlators/mgmt/glusterd/src/glusterd-messages.h | 10 +++++++++- + 3 files changed, 27 insertions(+), 14 deletions(-) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index df4f0b8..db2fa54 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -275,8 +275,7 @@ string:\"EXPORT(Export_Id=$export_id)\" 2>&1") + ret=$? + logger <<< "${output}" + if [ ${ret} -ne 0 ]; then +- echo "Error: refresh-config failed on ${current_host}." +- exit 1 ++ echo "Refresh-config failed on ${current_host}" + else + echo "Refresh-config completed on ${current_host}." + fi +@@ -297,8 +296,7 @@ string:"EXPORT(Export_Id=$export_id)" 2>&1) + ret=$? + logger <<< "${output}" + if [ ${ret} -ne 0 ] ; then +- echo "Error: refresh-config failed on localhost." +- exit 1 ++ echo "Refresh-config failed on localhost." + else + echo "Success: refresh-config completed." + fi +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index 5c582cd..38fa378 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -554,15 +554,22 @@ ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) + } + + if (check_host_list()) { +- runner_add_args (&runner, +- GANESHA_PREFIX"/dbus-send.sh", +- CONFDIR, value, volname, NULL); +- ret = runner_run (&runner); +- if (ret) { +- gf_asprintf(op_errstr, "Dynamic export" +- " addition/deletion failed." +- " Please see log file for details"); +- goto out; ++ /* Check whether ganesha is running on this node */ ++ if (manage_service ("status")) { ++ gf_msg (this->name, GF_LOG_WARNING, 0, ++ GD_MSG_GANESHA_NOT_RUNNING, ++ "Export failed, NFS-Ganesha is not running"); ++ } else { ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/dbus-send.sh", ++ CONFDIR, value, volname, NULL); ++ ret = runner_run (&runner); ++ if (ret) { ++ gf_asprintf(op_errstr, "Dynamic export" ++ " addition/deletion failed." ++ " Please see log file for details"); ++ goto out; ++ } + } + } + +diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h +index cc7f371..fb2079f 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-messages.h ++++ b/xlators/mgmt/glusterd/src/glusterd-messages.h +@@ -41,7 +41,7 @@ + + #define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD + +-#define GLFS_NUM_MESSAGES 612 ++#define GLFS_NUM_MESSAGES 613 + + #define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1) + /* Messaged with message IDs */ +@@ -4961,6 +4961,14 @@ + */ + #define GD_MSG_PORTS_EXHAUSTED (GLUSTERD_COMP_BASE + 612) + ++#define GD_MSG_GANESHA_NOT_RUNNING (GLUSTERD_COMP_BASE + 613) ++/*! ++ * @messageid ++ * @diagnosis ++ * @recommendedaction ++ * ++ */ ++ + /*------------*/ + + #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" +-- +1.8.3.1 + diff --git a/SOURCES/0058-glusterd-Introduce-reset-brick.patch b/SOURCES/0058-glusterd-Introduce-reset-brick.patch deleted file mode 100644 index c945e25..0000000 --- a/SOURCES/0058-glusterd-Introduce-reset-brick.patch +++ /dev/null @@ -1,2439 +0,0 @@ -From a07ff2945c3d7e80ff8a399439e27c7cfef41cda Mon Sep 17 00:00:00 2001 -From: Anuradha Talur -Date: Mon, 22 Aug 2016 13:22:03 -0400 -Subject: [PATCH 58/86] glusterd : Introduce reset brick - -The command basically allows replace brick with src and -dst bricks as same. - -Usage: -gluster v reset-brick start -This command kills the brick to be reset. Once this command is run, -admin can do other manual operations that they need to do, -like configuring some options for the brick. Once this is done, -resetting the brick can be continued with the following options. - -gluster v reset-brick commit {force} - -Does the job of resetting the brick. 'force' option should be used -when the brick already contains volinfo id. - -Problem: On doing a disk-replacement of a brick in a replicate volume -the following 2 scenarios may occur : - -a) there is a chance that reads are served from this replaced-disk brick, -which leads to empty reads. b) potential data loss if next writes succeed -only on replaced brick, and heal is done to other bricks from this one. - -Solution: After disk-replacement, make sure that reset-brick command is -run for that brick so that pending markers are set for the brick and it -is not chosen as source for reads and heal. But, as of now replace-brick -for the same brick-path is not allowed. In order to fix the above -mentioned problem, same brick-path replace-brick is needed. -With this patch reset-brick commit {force} will be allowed even when -source and destination are identical as long as -1) destination brick is not alive -2) source and destination brick have the same brick uuid and path. -Also, the destination brick after replace-brick will use the same port -as the source brick. - ->Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de ->BUG: 1266876 ->Signed-off-by: Anuradha Talur ->Reviewed-on: http://review.gluster.org/12250 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Ashish Pandey ->Reviewed-by: Pranith Kumar Karampuri - -Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de -BUG: 1256524 -Signed-off-by: Ashish Pandey -Reviewed-on: https://code.engineering.redhat.com/gerrit/84804 -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-cmd-parser.c | 164 ++++++-- - cli/src/cli-cmd-volume.c | 61 +++ - cli/src/cli-rpc-ops.c | 224 ++++++++++- - cli/src/cli-xml-output.c | 2 +- - cli/src/cli.h | 7 +- - heal/src/glfs-heal.c | 2 +- - rpc/rpc-lib/src/protocol-common.h | 1 + - .../bug-1266876-allow-reset-brick-for-same-path.t | 54 +++ - xlators/cluster/afr/src/afr-inode-write.c | 4 +- - xlators/mgmt/glusterd/src/Makefile.am | 3 +- - xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 2 +- - xlators/mgmt/glusterd/src/glusterd-handler.c | 1 + - xlators/mgmt/glusterd/src/glusterd-hooks.c | 1 + - xlators/mgmt/glusterd/src/glusterd-messages.h | 29 ++- - xlators/mgmt/glusterd/src/glusterd-mgmt.c | 33 ++ - xlators/mgmt/glusterd/src/glusterd-mgmt.h | 6 + - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 1 + - xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 350 ++++------------ - xlators/mgmt/glusterd/src/glusterd-reset-brick.c | 430 ++++++++++++++++++++ - xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 1 + - xlators/mgmt/glusterd/src/glusterd-syncop.c | 1 + - xlators/mgmt/glusterd/src/glusterd-utils.c | 327 +++++++++++++++- - xlators/mgmt/glusterd/src/glusterd-utils.h | 34 ++- - xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 +- - xlators/mgmt/glusterd/src/glusterd.c | 1 + - xlators/mgmt/glusterd/src/glusterd.h | 6 + - 26 files changed, 1429 insertions(+), 318 deletions(-) - create mode 100644 tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t - create mode 100644 xlators/mgmt/glusterd/src/glusterd-reset-brick.c - -diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c -index 836a464..04c8a22 100644 ---- a/cli/src/cli-cmd-parser.c -+++ b/cli/src/cli-cmd-parser.c -@@ -2147,6 +2147,137 @@ out: - return ret; - } - -+int32_t -+cli_cmd_brick_op_validate_bricks (const char **words, dict_t *dict, -+ int src, int dst) -+{ -+ int ret = -1; -+ char *delimiter = NULL; -+ -+ if (validate_brick_name ((char *)words[src])) { -+ cli_err ("wrong brick type: %s, use " -+ ":", words[3]); -+ ret = -1; -+ goto out; -+ } else { -+ delimiter = strrchr ((char *)words[src], '/'); -+ ret = gf_canonicalize_path (delimiter); -+ if (ret) -+ goto out; -+ } -+ -+ ret = dict_set_str (dict, "src-brick", (char *)words[src]); -+ if (ret) -+ goto out; -+ -+ if (dst == -1) { -+ ret = 0; -+ goto out; -+ } -+ -+ if (validate_brick_name ((char *)words[dst])) { -+ cli_err ("wrong brick type: %s, use " -+ ":", words[dst]); -+ ret = -1; -+ goto out; -+ } else { -+ delimiter = strrchr ((char *)words[dst], '/'); -+ ret = gf_canonicalize_path (delimiter); -+ if (ret) -+ goto out; -+ } -+ -+ ret = dict_set_str (dict, "dst-brick", (char *)words[dst]); -+ if (ret) -+ goto out; -+ ret = 0; -+out: -+ return ret; -+} -+ -+int32_t -+cli_cmd_volume_reset_brick_parse (const char **words, int wordcount, -+ dict_t **options) -+{ -+ int ret = -1; -+ char *volname = NULL; -+ dict_t *dict = NULL; -+ -+ if (wordcount < 5 || wordcount > 7) -+ goto out; -+ -+ dict = dict_new (); -+ -+ if (!dict) -+ goto out; -+ -+ volname = (char *)words[2]; -+ -+ ret = dict_set_str (dict, "volname", volname); -+ if (ret) -+ goto out; -+ -+ if (wordcount == 5) { -+ if (strcmp (words[4], "start")) { -+ cli_err ("Invalid option '%s' for reset-brick. Please " -+ "enter valid reset-brick command", words[4]); -+ ret = -1; -+ goto out; -+ } -+ -+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, -1); -+ if (ret) -+ goto out; -+ -+ ret = dict_set_str (dict, "operation", "GF_RESET_OP_START"); -+ if (ret) -+ goto out; -+ } else if (wordcount == 6) { -+ if (strcmp (words[5], "commit")) { -+ cli_err ("Invalid option '%s' for reset-brick. Please " -+ "enter valid reset-brick command", words[5]); -+ ret = -1; -+ goto out; -+ } -+ -+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4); -+ if (ret) -+ goto out; -+ -+ ret = dict_set_str (dict, "operation", "GF_RESET_OP_COMMIT"); -+ if (ret) -+ goto out; -+ } else if (wordcount == 7) { -+ if (strcmp (words[5], "commit") || strcmp (words[6], "force")) { -+ cli_err ("Invalid option '%s %s' for reset-brick. Please " -+ "enter valid reset-brick command", -+ words[5], words[6]); -+ ret = -1; -+ goto out; -+ } -+ -+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4); -+ if (ret) -+ goto out; -+ -+ ret = dict_set_str (dict, "operation", -+ "GF_RESET_OP_COMMIT_FORCE"); -+ if (ret) -+ goto out; -+ } -+ -+ *options = dict; -+ -+out: -+ if (ret) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Unable to parse reset-brick CLI"); -+ if (dict) -+ dict_unref (dict); -+ } -+ -+ return ret; -+} - - int32_t - cli_cmd_volume_replace_brick_parse (const char **words, int wordcount, -@@ -2154,7 +2285,6 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount, - { - int ret = -1; - char *volname = NULL; -- char *delimiter = NULL; - dict_t *dict = NULL; - - GF_ASSERT (words); -@@ -2180,35 +2310,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount, - if (ret) - goto out; - -- if (validate_brick_name ((char *)words[3])) { -- cli_err ("wrong brick type: %s, use " -- ":", words[3]); -- ret = -1; -- goto out; -- } else { -- delimiter = strrchr ((char *)words[3], ':'); -- ret = gf_canonicalize_path (delimiter + 1); -- if (ret) -- goto out; -- } -- -- ret = dict_set_str (dict, "src-brick", (char *)words[3]); -- if (ret) -- goto out; -- -- if (validate_brick_name ((char *)words[4])) { -- cli_err ("wrong brick type: %s, use " -- ":", words[4]); -- ret = -1; -- goto out; -- } else { -- delimiter = strrchr ((char *)words[4], ':'); -- ret = gf_canonicalize_path (delimiter + 1); -- if (ret) -- goto out; -- } -- -- ret = dict_set_str (dict, "dst-brick", (char *)words[4]); -+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4); - if (ret) - goto out; - -@@ -2229,7 +2331,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount, - - out: - if (ret) { -- gf_log ("cli", GF_LOG_ERROR, "Unable to parse replace-brick CLI"); -+ gf_log ("cli", GF_LOG_ERROR, "Unable to parse reset-brick CLI"); - if (dict) - dict_destroy (dict); - } -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 27cb9dd..4b2653b 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -1836,6 +1836,59 @@ out: - } - - int -+cli_cmd_volume_reset_brick_cbk (struct cli_state *state, -+ struct cli_cmd_word *word, -+ const char **words, -+ int wordcount) -+{ -+ int ret = -1; -+ rpc_clnt_procedure_t *proc = NULL; -+ call_frame_t *frame = NULL; -+ dict_t *options = NULL; -+ int sent = 0; -+ int parse_error = 0; -+ cli_local_t *local = NULL; -+ -+#ifdef GF_SOLARIS_HOST_OS -+ cli_out ("Command not supported on Solaris"); -+ goto out; -+#endif -+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_BRICK]; -+ -+ frame = create_frame (THIS, THIS->ctx->pool); -+ if (!frame) -+ goto out; -+ -+ ret = cli_cmd_volume_reset_brick_parse (words, wordcount, &options); -+ -+ if (ret) { -+ cli_usage_out (word->pattern); -+ parse_error = 1; -+ goto out; -+ } -+ -+ CLI_LOCAL_INIT (local, words, frame, options); -+ -+ if (proc->fn) { -+ ret = proc->fn (frame, THIS, options); -+ } -+ -+out: -+ if (ret) { -+ gf_event (EVENT_BRICK_RESET, "Volume reset-brick failed."); -+ cli_cmd_sent_status_get (&sent); -+ if ((sent == 0) && (parse_error == 0)) -+ cli_out ("Volume reset-brick failed"); -+ } else { -+ gf_event (EVENT_BRICK_RESET, "Volume reset-brick succeeded."); -+ } -+ -+ CLI_STACK_DESTROY (frame); -+ -+ return ret; -+} -+ -+int - cli_cmd_volume_replace_brick_cbk (struct cli_state *state, - struct cli_cmd_word *word, - const char **words, -@@ -1875,9 +1928,12 @@ cli_cmd_volume_replace_brick_cbk (struct cli_state *state, - - out: - if (ret) { -+ gf_event (EVENT_BRICK_REPLACE, "Volume replace-brick failed."); - cli_cmd_sent_status_get (&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out ("Volume replace-brick failed"); -+ } else { -+ gf_event (EVENT_BRICK_RESET, "Volume replace-brick succeeded."); - } - - CLI_STACK_DESTROY (frame); -@@ -3023,6 +3079,11 @@ struct cli_cmd volume_cmds[] = { - "Bitrot translator specific operation. For more information about " - "bitrot command type 'man gluster'" - }, -+ { "volume reset-brick {{start} |" -+ " { commit}}", -+ cli_cmd_volume_reset_brick_cbk, -+ "reset-brick operations"}, -+ - { NULL, NULL, NULL } - }; - -diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c -index 77a2e24..dcf2a12 100644 ---- a/cli/src/cli-rpc-ops.c -+++ b/cli/src/cli-rpc-ops.c -@@ -2967,6 +2967,149 @@ out: - } - - int -+gf_cli_reset_brick_cbk (struct rpc_req *req, struct iovec *iov, -+ int count, void *myframe) -+{ -+ gf_cli_rsp rsp = {0,}; -+ int ret = -1; -+ cli_local_t *local = NULL; -+ call_frame_t *frame = NULL; -+ char *src_brick = NULL; -+ char *dst_brick = NULL; -+ char *status_reply = NULL; -+ char *rb_operation_str = NULL; -+ dict_t *rsp_dict = NULL; -+ char msg[1024] = {0,}; -+ char *task_id_str = NULL; -+ char *reset_op = NULL; -+ -+ GF_ASSERT (myframe); -+ -+ if (-1 == req->rpc_status) { -+ goto out; -+ } -+ -+ frame = myframe; -+ -+ GF_ASSERT (frame->local); -+ -+ local = frame->local; -+ -+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp); -+ if (ret < 0) { -+ gf_log (frame->this->name, GF_LOG_ERROR, -+ "Failed to decode xdr response"); -+ goto out; -+ } -+ -+ ret = dict_get_str (local->dict, "operation", &reset_op); -+ if (ret) { -+ gf_log (frame->this->name, GF_LOG_ERROR, -+ "dict_get on operation failed"); -+ goto out; -+ } -+ -+ if (rsp.dict.dict_len) { -+ /* Unserialize the dictionary */ -+ rsp_dict = dict_new (); -+ -+ ret = dict_unserialize (rsp.dict.dict_val, -+ rsp.dict.dict_len, -+ &rsp_dict); -+ if (ret < 0) { -+ gf_log (frame->this->name, GF_LOG_ERROR, "failed to " -+ "unserialize rsp buffer to dictionary"); -+ goto out; -+ } -+ } -+ -+ if (strcmp (reset_op, "GF_RESET_OP_START") && -+ strcmp (reset_op, "GF_RESET_OP_COMMIT") && -+ strcmp (reset_op, "GF_RESET_OP_COMMIT_FORCE")) { -+ rb_operation_str = gf_strdup ("Unknown operation"); -+ ret = -1; -+ goto out; -+ } -+ -+ if (rsp.op_ret && (strcmp (rsp.op_errstr, ""))) { -+ rb_operation_str = gf_strdup (rsp.op_errstr); -+ } else { -+ if (!strcmp (reset_op, "GF_RESET_OP_START")) { -+ if (rsp.op_ret) -+ rb_operation_str = gf_strdup ("reset-brick " -+ "start " -+ "operation " -+ "failed"); -+ else -+ rb_operation_str = gf_strdup ("reset-brick " -+ "start " -+ "operation " -+ "successful"); -+ } else if (!strcmp (reset_op, "GF_RESET_OP_COMMIT")) { -+ -+ if (rsp.op_ret) -+ rb_operation_str = gf_strdup ("reset-brick " -+ "commit " -+ "operation " -+ "failed"); -+ else -+ rb_operation_str = gf_strdup ("reset-brick " -+ "commit " -+ "operation " -+ "successful"); -+ } else if (!strcmp (reset_op, "GF_RESET_OP_COMMIT_FORCE")) { -+ -+ if (rsp.op_ret) -+ rb_operation_str = gf_strdup ("reset-brick " -+ "commit " -+ "force operation " -+ "failed"); -+ else -+ rb_operation_str = gf_strdup ("reset-brick " -+ "commit " -+ "force operation " -+ "successful"); -+ } -+ } -+ -+ gf_log ("cli", GF_LOG_INFO, "Received resp to reset brick"); -+ snprintf (msg, sizeof (msg), "%s", -+ rb_operation_str ? rb_operation_str : "Unknown operation"); -+ -+ if (global_state->mode & GLUSTER_MODE_XML) { -+ ret = cli_xml_output_vol_replace_brick (rsp_dict, -+ rsp.op_ret, -+ rsp.op_errno, msg); -+ if (ret) -+ gf_log ("cli", GF_LOG_ERROR, -+ "Error outputting to xml"); -+ goto out; -+ } -+ -+ if (rsp.op_ret) -+ cli_err ("volume reset-brick: failed: %s", msg); -+ else -+ cli_out ("volume reset-brick: success: %s", msg); -+ ret = rsp.op_ret; -+ -+out: -+ if (frame) -+ frame->local = NULL; -+ -+ if (local) -+ cli_local_wipe (local); -+ -+ if (rb_operation_str) -+ GF_FREE (rb_operation_str); -+ -+ cli_cmd_broadcast_response (ret); -+ free (rsp.dict.dict_val); -+ if (rsp_dict) -+ dict_unref (rsp_dict); -+ -+ return ret; -+} -+int - gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov, - int count, void *myframe) - { -@@ -2980,8 +3123,7 @@ gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov, - char *rb_operation_str = NULL; - dict_t *rsp_dict = NULL; - char msg[1024] = {0,}; -- char *task_id_str = NULL; -- char *replace_op = 0; -+ char *replace_op = NULL; - - GF_ASSERT (myframe); - -@@ -3023,7 +3165,7 @@ gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov, - } - } - -- if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) { -+ if (!strcmp (replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) { - - if (rsp.op_ret || ret) - rb_operation_str = gf_strdup ("replace-brick commit " -@@ -3045,7 +3187,7 @@ gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov, - rb_operation_str ? rb_operation_str : "Unknown operation"); - - if (global_state->mode & GLUSTER_MODE_XML) { -- ret = cli_xml_output_vol_replace_brick (replace_op, rsp_dict, -+ ret = cli_xml_output_vol_replace_brick (rsp_dict, - rsp.op_ret, - rsp.op_errno, msg); - if (ret) -@@ -3064,10 +3206,8 @@ out: - if (frame) - frame->local = NULL; - -- if (local) { -- dict_unref (local->dict); -+ if (local) - cli_local_wipe (local); -- } - - if (rb_operation_str) - GF_FREE (rb_operation_str); -@@ -4903,8 +5043,73 @@ out: - } - - int32_t -+gf_cli_reset_brick (call_frame_t *frame, xlator_t *this, void *data) -+{ -+ gf_cli_req req = { {0,} }; -+ int ret = 0; -+ dict_t *dict = NULL; -+ char *dst_brick = NULL; -+ char *src_brick = NULL; -+ char *volname = NULL; -+ char *op = NULL; -+ -+ if (!frame || !this || !data) { -+ ret = -1; -+ goto out; -+ } -+ -+ dict = data; -+ -+ ret = dict_get_str (dict, "operation", &op); -+ if (ret) { -+ gf_log (this->name, GF_LOG_DEBUG, -+ "dict_get on operation failed"); -+ goto out; -+ } -+ -+ ret = dict_get_str (dict, "volname", &volname); -+ if (ret) { -+ gf_log (this->name, GF_LOG_DEBUG, -+ "dict_get on volname failed"); -+ goto out; -+ } -+ -+ ret = dict_get_str (dict, "src-brick", &src_brick); -+ if (ret) { -+ gf_log (this->name, GF_LOG_DEBUG, -+ "dict_get on src-brick failed"); -+ goto out; -+ } -+ -+ if (!strcmp (op, "GF_RESET_OP_COMMIT") || -+ !strcmp (op, "GF_RESET_OP_COMMIT_FORCE")) { -+ ret = dict_get_str (dict, "dst-brick", &dst_brick); -+ if (ret) { -+ gf_log (this->name, GF_LOG_DEBUG, -+ "dict_get on dst-brick failed"); -+ goto out; -+ } -+ } -+ -+ gf_log (this->name, GF_LOG_DEBUG, -+ "Received command reset-brick %s on %s.", op, src_brick); -+ -+ ret = cli_to_glusterd (&req, frame, gf_cli_reset_brick_cbk, -+ (xdrproc_t) xdr_gf_cli_req, dict, -+ GLUSTER_CLI_RESET_BRICK, this, cli_rpc_prog, -+ NULL); -+ -+out: -+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); -+ -+ GF_FREE (req.dict.dict_val); -+ -+ return ret; -+} -+ -+int32_t - gf_cli_replace_brick (call_frame_t *frame, xlator_t *this, -- void *data) -+ void *data) - { - gf_cli_req req = {{0,}}; - int ret = 0; -@@ -11374,7 +11579,8 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = { - [GLUSTER_CLI_ATTACH_TIER] = {"ATTACH_TIER", gf_cli_attach_tier}, - [GLUSTER_CLI_DETACH_TIER] = {"DETACH_TIER", gf_cli_detach_tier}, - [GLUSTER_CLI_TIER] = {"TIER", gf_cli_tier}, -- [GLUSTER_CLI_GET_STATE] = {"GET_STATE", gf_cli_get_state} -+ [GLUSTER_CLI_GET_STATE] = {"GET_STATE", gf_cli_get_state}, -+ [GLUSTER_CLI_RESET_BRICK] = {"RESET_BRICK", gf_cli_reset_brick} - }; - - struct rpc_clnt_program cli_prog = { -diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c -index 34f85f2..6d1e617 100644 ---- a/cli/src/cli-xml-output.c -+++ b/cli/src/cli-xml-output.c -@@ -3865,7 +3865,7 @@ out: - } - - int --cli_xml_output_vol_replace_brick (char *op, dict_t *dict, -+cli_xml_output_vol_replace_brick (dict_t *dict, - int op_ret, int op_errno, char *op_errstr) - { - #if (HAVE_LIB_XML) -diff --git a/cli/src/cli.h b/cli/src/cli.h -index f9c642e..ba0d845 100644 ---- a/cli/src/cli.h -+++ b/cli/src/cli.h -@@ -284,6 +284,10 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount, - dict_t **options); - - int32_t -+cli_cmd_volume_reset_brick_parse (const char **words, int wordcount, -+ dict_t **options); -+ -+int32_t - cli_cmd_log_rotate_parse (const char **words, int wordcount, dict_t **options); - int32_t - cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options); -@@ -424,7 +428,7 @@ cli_xml_output_vol_remove_brick_detach_tier (gf_boolean_t status_op, - const char *op); - - int --cli_xml_output_vol_replace_brick (char *op, dict_t *dict, int op_ret, -+cli_xml_output_vol_replace_brick (dict_t *dict, int op_ret, - int op_errno, char *op_errstr); - - int -@@ -489,5 +493,4 @@ print_quota_list_empty (char *path, int type); - - int - gf_gsync_status_t_comparator (const void *p, const void *q); -- - #endif /* __CLI_H__ */ -diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c -index 0a880cb..e885dd9 100644 ---- a/heal/src/glfs-heal.c -+++ b/heal/src/glfs-heal.c -@@ -517,7 +517,7 @@ out: - - (*num_entries)++; - glfsh_output->print_heal_status (path ? path : -- uuid_utoa_r (gfid, gfid_str), -+ uuid_utoa_r (gfid, gfid_str), - gfid, - status ? status : ""); - -diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h -index c1a488e..c7c3327 100644 ---- a/rpc/rpc-lib/src/protocol-common.h -+++ b/rpc/rpc-lib/src/protocol-common.h -@@ -193,6 +193,7 @@ enum gluster_cli_procnum { - GLUSTER_CLI_DETACH_TIER, - GLUSTER_CLI_TIER, - GLUSTER_CLI_GET_STATE, -+ GLUSTER_CLI_RESET_BRICK, - GLUSTER_CLI_MAXVALUE, - }; - -diff --git a/tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t b/tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t -new file mode 100644 -index 0000000..884b789 ---- /dev/null -+++ b/tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t -@@ -0,0 +1,54 @@ -+#!/bin/bash -+. $(dirname $0)/../../include.rc -+. $(dirname $0)/../../volume.rc -+cleanup; -+ -+TEST glusterd -+TEST pidof glusterd -+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1} -+TEST $CLI volume start $V0 -+ -+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0; -+# Create files -+for i in {1..5} -+do -+ echo $i > $M0/file$i.txt -+done -+ -+# Negative case with brick not killed && volume-id xattrs present -+TEST ! $CLI volume reset-brick $V0 $H0:$B0/${V0}1 $H0:$B0/${V0}1 commit force -+TEST kill_brick $V0 $H0 $B0/${V0}1 -+ -+# Negative case with brick killed but volume-id xattr present -+TEST ! $CLI volume reset-brick $V0 $H0:$B0/${V0}1 $H0:$B0/${V0}1 commit -+ -+TEST $CLI volume reset-brick $V0 $H0:$B0/${V0}1 start -+# Simulated reset disk -+for i in {1..5} -+do -+ rm -rf $B0/${V0}{1}/file$i.txt -+done -+for i in {6..10} -+do -+ echo $i > $M0/file$i.txt -+done -+ -+# Now reset the brick -+TEST $CLI volume reset-brick $V0 $H0:$B0/${V0}1 $H0:$B0/${V0}1 commit force -+ -+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 "Y" glustershd_up_status -+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 -+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 -+ -+TEST $CLI volume heal $V0 -+ -+EXPECT_WITHIN $HEAL_TIMEOUT "0" get_pending_heal_count $V0 -+ -+# Check if entry-heal has happened -+TEST diff <(ls $B0/${V0}0 | sort) <(ls $B0/${V0}1 | sort) -+EXPECT "10" echo $(ls $B0/${V0}1 | wc -l) -+ -+cleanup; -diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c -index ddc257d..24ab52f 100644 ---- a/xlators/cluster/afr/src/afr-inode-write.c -+++ b/xlators/cluster/afr/src/afr-inode-write.c -@@ -1235,8 +1235,8 @@ _afr_handle_empty_brick (void *opaque) - - loc_copy (&local->loc, &data->loc); - -- gf_msg_debug (this->name, 0, "New brick is : %s", -- priv->children[empty_index]->name); -+ gf_msg (this->name, GF_LOG_INFO, 0, 0, "New brick is : %s", -+ priv->children[empty_index]->name); - - ret = _afr_handle_empty_brick_type (this, frame, &local->loc, empty_index, - AFR_METADATA_TRANSACTION, op_type); -diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am -index 23840cd..faee862 100644 ---- a/xlators/mgmt/glusterd/src/Makefile.am -+++ b/xlators/mgmt/glusterd/src/Makefile.am -@@ -16,7 +16,8 @@ glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \ - glusterd-proc-mgmt.c glusterd-svc-mgmt.c glusterd-shd-svc.c \ - glusterd-nfs-svc.c glusterd-quotad-svc.c glusterd-svc-helper.c \ - glusterd-conn-helper.c glusterd-snapd-svc.c glusterd-snapd-svc-helper.c \ -- glusterd-bitd-svc.c glusterd-scrub-svc.c glusterd-server-quorum.c -+ glusterd-bitd-svc.c glusterd-scrub-svc.c glusterd-server-quorum.c \ -+ glusterd-reset-brick.c - - - glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ -diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c -index 7522003..92e6386 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c -+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c -@@ -1830,7 +1830,7 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict) - brick_alloc = _gf_true; - - ret = glusterd_new_brick_validate (brick, brickinfo, msg, -- sizeof (msg)); -+ sizeof (msg), NULL); - if (ret) { - *op_errstr = gf_strdup (msg); - ret = -1; -diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c -index b024fdb..d81204e 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-handler.c -+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c -@@ -5926,6 +5926,7 @@ rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = { - [GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", GLUSTER_CLI_GET_VOL_OPT, glusterd_handle_get_vol_opt, NULL, 0, DRC_NA}, - [GLUSTER_CLI_BITROT] = {"BITROT", GLUSTER_CLI_BITROT, glusterd_handle_bitrot, NULL, 0, DRC_NA}, - [GLUSTER_CLI_GET_STATE] = {"GET_STATE", GLUSTER_CLI_GET_STATE, glusterd_handle_get_state, NULL, 0, DRC_NA}, -+ [GLUSTER_CLI_RESET_BRICK] = {"RESET_BRICK", GLUSTER_CLI_RESET_BRICK, glusterd_handle_reset_brick, NULL, 0, DRC_NA}, - }; - - struct rpcsvc_program gd_svc_cli_prog = { -diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c -index 45a5912..17beb79 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-hooks.c -+++ b/xlators/mgmt/glusterd/src/glusterd-hooks.c -@@ -57,6 +57,7 @@ char glusterd_hook_dirnames[GD_OP_MAX][256] = - [GD_OP_LIST_VOLUME] = EMPTY, - [GD_OP_CLEARLOCKS_VOLUME] = EMPTY, - [GD_OP_DEFRAG_BRICK_VOLUME] = EMPTY, -+ [GD_OP_RESET_BRICK] = EMPTY, - }; - #undef EMPTY - -diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h -index af492e0..e39fb92 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-messages.h -+++ b/xlators/mgmt/glusterd/src/glusterd-messages.h -@@ -41,7 +41,7 @@ - - #define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD - --#define GLFS_NUM_MESSAGES 585 -+#define GLFS_NUM_MESSAGES 587 - - #define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1) - /* Messaged with message IDs */ -@@ -2837,7 +2837,7 @@ - * @recommendedaction - * - */ --#define GD_MSG_NFS_VOL_FILE_GEN_FAIL (GLUSTERD_COMP_BASE + 349) -+#define GD_MSG_GLUSTER_SERVICE_START_FAIL (GLUSTERD_COMP_BASE + 349) - - /*! - * @messageid -@@ -2965,7 +2965,7 @@ - * @recommendedaction - * - */ --#define GD_MSG_NFS_SERVER_STOP_FAIL (GLUSTERD_COMP_BASE + 365) -+#define GD_MSG_GLUSTER_SERVICES_STOP_FAIL (GLUSTERD_COMP_BASE + 365) - - /*! - * @messageid -@@ -4728,8 +4728,31 @@ - * @recommendation - * - */ -+#define GD_MSG_BRICK_CLEANUP_SUCCESS (GLUSTERD_COMP_BASE + 584) -+ -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendation -+ * -+ */ - #define GD_MSG_STATE_STR_GET_FAILED (GLUSTERD_COMP_BASE + 585) - -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendedaction -+ * -+ */ -+#define GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD (GLUSTERD_COMP_BASE + 586) -+ -+/*! -+ * @messageid -+ * @diagnosis -+ * @recommendedaction -+ * -+ */ -+#define GD_MSG_RESET_BRICK_CMD_FAIL (GLUSTERD_COMP_BASE + 587) - /*------------*/ - #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" - #endif /* !_GLUSTERD_MESSAGES_H_ */ -diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c -index 092283a..bac0c6a 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c -+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c -@@ -200,6 +200,17 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict, - } - break; - -+ case GD_OP_RESET_BRICK: -+ ret = glusterd_reset_brick_prevalidate (dict, op_errstr, -+ rsp_dict); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_WARNING, 0, -+ GD_MSG_PRE_VALIDATION_FAIL, -+ "Reset brick prevalidation failed."); -+ goto out; -+ } -+ break; -+ - default: - break; - } -@@ -309,6 +320,17 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict, - break; - - } -+ case GD_OP_RESET_BRICK: -+ { -+ ret = glusterd_op_reset_brick (dict, rsp_dict); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_COMMIT_OP_FAIL, -+ "Reset-brick commit failed."); -+ goto out; -+ } -+ break; -+ } - - default: - break; -@@ -682,6 +704,16 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op, - goto out; - } - break; -+ case GD_OP_RESET_BRICK: -+ ret = glusterd_rb_use_rsp_dict (aggr, rsp); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_PRE_VALIDATION_FAIL, -+ "Failed to aggregate prevalidate " -+ "response dictionaries."); -+ goto out; -+ } -+ break; - default: - ret = -1; - gf_msg (this->name, GF_LOG_ERROR, EINVAL, -@@ -985,6 +1017,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict, - case GD_OP_START_VOLUME: - case GD_OP_ADD_BRICK: - case GD_OP_REPLACE_BRICK: -+ case GD_OP_RESET_BRICK: - { - ret = dict_get_str (dict, "volname", &volname); - if (ret) { -diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h -index bf87ec7..2215f17 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h -+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h -@@ -74,4 +74,10 @@ glusterd_mgmt_v3_release_peer_locks (glusterd_op_t op, dict_t *dict, - - int32_t - glusterd_multiple_mgmt_v3_unlock (dict_t *dict, uuid_t uuid); -+ -+int -+glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr, -+ dict_t *rsp_dict); -+int -+glusterd_op_reset_brick (dict_t *dict, dict_t *rsp_dict); - #endif /* _GLUSTERD_MGMT_H_ */ -diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index 313e3de..0521a9c 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c -+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -4133,6 +4133,7 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx) - case GD_OP_BITROT: - case GD_OP_SCRUB_STATUS: - case GD_OP_SCRUB_ONDEMAND: -+ case GD_OP_RESET_BRICK: - { - do_common = _gf_true; - } -diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -index 7bd1de3..7338843 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -+++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -@@ -27,13 +27,6 @@ - - #include - --#define GLUSTERD_GET_RB_MNTPT(path, len, volinfo) \ -- snprintf (path, len, \ -- DEFAULT_VAR_RUN_DIRECTORY"/%s-"RB_CLIENT_MOUNTPOINT, \ -- volinfo->volname); -- --extern uuid_t global_txn_id; -- - int - glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (rpcsvc_request_t *req, - glusterd_op_t op, -@@ -46,15 +39,17 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req) - dict_t *dict = NULL; - char *src_brick = NULL; - char *dst_brick = NULL; -- int32_t op = 0; -- glusterd_op_t cli_op = GD_OP_REPLACE_BRICK; -+ char *cli_op = NULL; -+ glusterd_op_t op = -1; - char *volname = NULL; - char msg[2048] = {0,}; - xlator_t *this = NULL; -+ glusterd_conf_t *conf = NULL; - - GF_ASSERT (req); - this = THIS; - GF_ASSERT (this); -+ conf = this->private; - - ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); - if (ret < 0) { -@@ -96,7 +91,7 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req) - goto out; - } - -- ret = dict_get_int32 (dict, "operation", &op); -+ ret = dict_get_str (dict, "operation", &cli_op); - if (ret) { - gf_msg_debug (this->name, 0, - "dict_get on operation failed"); -@@ -104,6 +99,19 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req) - goto out; - } - -+ op = gd_cli_to_gd_op (cli_op); -+ -+ if (conf->op_version < GD_OP_VERSION_3_9_0 && -+ strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE")) { -+ snprintf (msg, sizeof (msg), "Cannot execute command. The " -+ "cluster is operating at version %d. reset-brick " -+ "command %s is unavailable in this version.", -+ conf->op_version, -+ gd_rb_op_to_str (cli_op)); -+ ret = -1; -+ goto out; -+ } -+ - ret = dict_get_str (dict, "src-brick", &src_brick); - - if (ret) { -@@ -115,52 +123,60 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req) - gf_msg_debug (this->name, 0, - "src brick=%s", src_brick); - -- ret = dict_get_str (dict, "dst-brick", &dst_brick); -+ if (!strcmp (cli_op, "GF_RESET_OP_COMMIT") || -+ !strcmp (cli_op, "GF_RESET_OP_COMMIT_FORCE") || -+ !strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE")) { -+ ret = dict_get_str (dict, "dst-brick", &dst_brick); - -- if (ret) { -- snprintf (msg, sizeof (msg), "Failed to get dest brick"); -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_DICT_GET_FAILED, "%s", msg); -- goto out; -+ if (ret) { -+ snprintf (msg, sizeof (msg), "Failed to get" -+ "dest brick"); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "%s", msg); -+ goto out; -+ } -+ -+ gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick); - } - -- gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick); - gf_msg (this->name, GF_LOG_INFO, 0, -- GD_MSG_REPLACE_BRK_COMMIT_FORCE_REQ_RCVD, -- "Received replace brick commit-force " -- "request operation"); -+ (op == GD_OP_REPLACE_BRICK) ? -+ GD_MSG_REPLACE_BRK_COMMIT_FORCE_REQ_RCVD : -+ GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD, -+ "Received %s request.", -+ gd_rb_op_to_str (cli_op)); -+ -+ gf_event ((op == GD_OP_REPLACE_BRICK) ? EVENT_BRICK_REPLACE : -+ EVENT_BRICK_RESET, "received %s request. Source bricks %s," -+ "destination brick %s.", gd_rb_op_to_str (cli_op), -+ src_brick, (dst_brick) ? dst_brick : ""); - - ret = glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (req, -- GD_OP_REPLACE_BRICK, dict); -+ op, dict); - - out: -+ if (ret) { -+ glusterd_op_send_cli_response (op, ret, 0, req, -+ dict, msg); -+ } -+ ret = 0; - free (cli_req.dict.dict_val);//malloced by xdr - - return ret; - } - - int --glusterd_handle_replace_brick (rpcsvc_request_t *req) -+glusterd_handle_reset_brick (rpcsvc_request_t *req) - { - return glusterd_big_locked_handler (req, - __glusterd_handle_replace_brick); - } - --static int --glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo, -- glusterd_brickinfo_t **brickinfo) -+int -+glusterd_handle_replace_brick (rpcsvc_request_t *req) - { -- int32_t ret = -1; -- -- if (!volinfo || !brickinfo) -- goto out; -- -- *brickinfo = volinfo->rep_brick.dst_brick; -- -- ret = 0; -- --out: -- return ret; -+ return glusterd_big_locked_handler (req, -+ __glusterd_handle_replace_brick); - } - - int -@@ -172,13 +188,13 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, - char *src_brick = NULL; - char *dst_brick = NULL; - char *volname = NULL; -- char *replace_op = NULL; -+ char *op = NULL; -+ glusterd_op_t gd_op = -1; - glusterd_volinfo_t *volinfo = NULL; - glusterd_brickinfo_t *src_brickinfo = NULL; - char *host = NULL; - char *path = NULL; - char msg[2048] = {0}; -- char *dup_dstbrick = NULL; - glusterd_peerinfo_t *peerinfo = NULL; - glusterd_brickinfo_t *dst_brickinfo = NULL; - gf_boolean_t enabled = _gf_false; -@@ -188,8 +204,9 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, - char *task_id_str = NULL; - xlator_t *this = NULL; - gf_boolean_t is_force = _gf_false; -- gsync_status_param_t param = {0,}; -- char *c = NULL; -+ pid_t pid = -1; -+ uuid_t volume_id = {0,}; -+ char *dup_dstbrick = NULL; - - this = THIS; - GF_ASSERT (this); -@@ -197,193 +214,41 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, - priv = this->private; - GF_ASSERT (priv); - -- ret = dict_get_str (dict, "src-brick", &src_brick); -- -- if (ret) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_DICT_GET_FAILED, "Unable to get src brick"); -- goto out; -- } -- -- gf_msg_debug (this->name, 0, "src brick=%s", src_brick); -- -- ret = dict_get_str (dict, "dst-brick", &dst_brick); -- -- if (ret) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_DICT_GET_FAILED, "Unable to get dest brick"); -- goto out; -- } -- -- gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick); -- -- ret = dict_get_str (dict, "volname", &volname); -- -- if (ret) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); -- goto out; -- } -- -- ret = dict_get_str (dict, "operation", &replace_op); -- if (ret) { -- gf_msg_debug (this->name, 0, -- "dict get on replace-brick operation failed"); -- goto out; -- } -- -- ret = glusterd_volinfo_find (volname, &volinfo); -- if (ret) { -- snprintf (msg, sizeof (msg), "volume: %s does not exist", -- volname); -- *op_errstr = gf_strdup (msg); -- goto out; -- } -- -- if (GLUSTERD_STATUS_STARTED != volinfo->status) { -- ret = -1; -- snprintf (msg, sizeof (msg), "volume: %s is not started", -- volname); -- *op_errstr = gf_strdup (msg); -- goto out; -- } -- -- ret = glusterd_disallow_op_for_tier (volinfo, GD_OP_REPLACE_BRICK, -1); -- if (ret) { -- snprintf (msg, sizeof (msg), "Replace brick commands are not " -- "supported on tiered volume %s", volname); -- *op_errstr = gf_strdup (msg); -- goto out; -- } -- -- if (!glusterd_store_is_valid_brickpath (volname, dst_brick) || -- !glusterd_is_valid_volfpath (volname, dst_brick)) { -- snprintf (msg, sizeof (msg), "brick path %s is too " -- "long.", dst_brick); -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_BRKPATH_TOO_LONG, "%s", msg); -- *op_errstr = gf_strdup (msg); -- -- ret = -1; -- goto out; -- } -- -- /* If geo-rep is configured, for this volume, it should be stopped. */ -- param.volinfo = volinfo; -- ret = glusterd_check_geo_rep_running (¶m, op_errstr); -- if (ret || param.is_active) { -- ret = -1; -+ ret = glusterd_brick_op_prerequisites (dict, &op, &gd_op, -+ &volname, &volinfo, -+ &src_brick, &src_brickinfo, -+ pidfile, -+ op_errstr, rsp_dict); -+ if (ret) - goto out; -- } - -- if (glusterd_is_defrag_on(volinfo)) { -- snprintf (msg, sizeof(msg), "Volume name %s rebalance is in " -- "progress. Please retry after completion", volname); -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_OIP_RETRY_LATER, "%s", msg); -- *op_errstr = gf_strdup (msg); -+ if (strcmp (op, "GF_REPLACE_OP_COMMIT_FORCE")) { - ret = -1; - goto out; -- } -- -- if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) { -- is_force = _gf_true; - } else { -- ret = -1; -- goto out; -- } -- -- ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo, -- &src_brickinfo, -- _gf_false); -- if (ret) { -- snprintf (msg, sizeof (msg), "brick: %s does not exist in " -- "volume: %s", src_brick, volname); -- *op_errstr = gf_strdup (msg); -- goto out; -- } -- -- if (dict) { -- if (!glusterd_is_fuse_available ()) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_RB_CMD_FAIL, "Unable to open /dev/" -- "fuse (%s), replace-brick command failed", -- strerror (errno)); -- snprintf (msg, sizeof(msg), "Fuse unavailable\n " -- "Replace-brick failed"); -- *op_errstr = gf_strdup (msg); -- ret = -1; -- goto out; -- } -- } -- -- if (gf_is_local_addr (src_brickinfo->hostname)) { -- gf_msg_debug (this->name, 0, -- "I AM THE SOURCE HOST"); -- if (src_brickinfo->port && rsp_dict) { -- ret = dict_set_int32 (rsp_dict, "src-brick-port", -- src_brickinfo->port); -- if (ret) { -- gf_msg_debug (this->name, 0, -- "Could not set src-brick-port=%d", -- src_brickinfo->port); -- } -- } -- -- GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, src_brickinfo, -- priv); -- -- } -- -- dup_dstbrick = gf_strdup (dst_brick); -- if (!dup_dstbrick) { -- ret = -1; -- gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -- GD_MSG_NO_MEMORY, "Memory allocation failed"); -- goto out; -- } -- -- /* -- * IPv4 address contains '.' and ipv6 addresses contains ':' -- * So finding the last occurance of ':' to -- * mark the start of brick path -- */ -- c = strrchr(dup_dstbrick, ':'); -- if (c != NULL) { -- c[0] = '\0'; -- host = dup_dstbrick; -- path = c++; -- } -- -- if (!host || !path) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_BAD_FORMAT, -- "dst brick %s is not of form :", -- dst_brick); -- ret = -1; -- goto out; -- } -+ is_force = _gf_true; -+ } - -- ret = glusterd_brickinfo_new_from_brick (dst_brick, &dst_brickinfo, -- _gf_true, NULL); -+ ret = glusterd_get_dst_brick_info (&dst_brick, volname, -+ op_errstr, -+ &dst_brickinfo, &host, -+ dict, &dup_dstbrick); - if (ret) - goto out; - - ret = glusterd_new_brick_validate (dst_brick, dst_brickinfo, -- msg, sizeof (msg)); -- if (ret) { -+ msg, sizeof (msg), op); -+ /* fail if brick being replaced with itself */ -+ if (ret) { - *op_errstr = gf_strdup (msg); - ret = -1; - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_BRICK_VALIDATE_FAIL, "%s", *op_errstr); - goto out; -- } -+ } - -- if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) { -- -- volinfo->rep_brick.src_brick = src_brickinfo; -- volinfo->rep_brick.dst_brick = dst_brickinfo; -- } -+ volinfo->rep_brick.src_brick = src_brickinfo; -+ volinfo->rep_brick.dst_brick = dst_brickinfo; - - if (glusterd_rb_check_bricks (volinfo, src_brickinfo, dst_brickinfo)) { - -@@ -489,48 +354,8 @@ rb_kill_destination_brick (glusterd_volinfo_t *volinfo, - return glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_true); - } - --static int --rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict, -- dict_t *req_dict, char *replace_op) --{ -- int ret = 0; -- int dict_ret = 0; -- int dst_port = 0; -- -- dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port); -- if (!dict_ret) -- dst_brickinfo->port = dst_port; -- -- if (gf_is_local_addr (dst_brickinfo->hostname)) { -- gf_msg ("glusterd", GF_LOG_INFO, 0, -- GD_MSG_BRK_PORT_NO_ADD_INDO, -- "adding dst-brick port no"); -- -- if (rsp_dict) { -- ret = dict_set_int32 (rsp_dict, "dst-brick-port", -- dst_brickinfo->port); -- if (ret) { -- gf_msg_debug ("glusterd", 0, -- "Could not set dst-brick port no in rsp dict"); -- goto out; -- } -- } -- -- if (req_dict) { -- ret = dict_set_int32 (req_dict, "dst-brick-port", -- dst_brickinfo->port); -- if (ret) { -- gf_msg_debug ("glusterd", 0, -- "Could not set dst-brick port no"); -- goto out; -- } -- } -- } --out: -- return ret; --} - --static int -+int - glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, - char *old_brick, char *new_brick, - dict_t *dict) -@@ -568,6 +393,7 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, - - strncpy (new_brickinfo->brick_id, old_brickinfo->brick_id, - sizeof (new_brickinfo->brick_id)); -+ new_brickinfo->port = old_brickinfo->port; - - /* A bricks mount dir is required only by snapshots which were - * introduced in gluster-3.6.0 -@@ -584,8 +410,8 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, - sizeof(new_brickinfo->mount_dir)); - } - -- cds_list_add_tail (&new_brickinfo->brick_list, -- &old_brickinfo->brick_list); -+ cds_list_add (&new_brickinfo->brick_list, -+ &old_brickinfo->brick_list); - - volinfo->brick_count++; - -@@ -706,11 +532,11 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) - } - - ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict, -- dict, replace_op); -+ dict); - if (ret) - goto out; - -- if (strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) { -+ if (strcmp (replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) { - ret = -1; - goto out; - } -@@ -729,8 +555,8 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) - ret = glusterd_svcs_stop (volinfo); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_NFS_SERVER_STOP_FAIL, -- "Unable to stop nfs server, ret: %d", ret); -+ GD_MSG_GLUSTER_SERVICES_STOP_FAIL, -+ "Unable to stop gluster services, ret: %d", ret); - } - - ret = glusterd_op_perform_replace_brick (volinfo, src_brick, -@@ -739,7 +565,7 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) - gf_msg (this->name, GF_LOG_CRITICAL, 0, - GD_MSG_BRICK_ADD_FAIL, "Unable to add dst-brick: " - "%s to volume: %s", dst_brick, volinfo->volname); -- (void) glusterd_svcs_manager (volinfo); -+ (void) glusterd_svcs_manager (volinfo); - goto out; - } - -@@ -748,8 +574,8 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) - ret = glusterd_svcs_manager (volinfo); - if (ret) { - gf_msg (this->name, GF_LOG_CRITICAL, 0, -- GD_MSG_NFS_VOL_FILE_GEN_FAIL, -- "Failed to generate nfs volume file"); -+ GD_MSG_GLUSTER_SERVICE_START_FAIL, -+ "Failed to start one or more gluster services."); - } - - -@@ -759,7 +585,7 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict) - volinfo->rep_brick.dst_brick = NULL; - - if (!ret) -- ret = glusterd_store_volinfo (volinfo, -+ ret = glusterd_store_volinfo (volinfo, - GLUSTERD_VOLINFO_VER_AC_INCREMENT); - if (ret) - gf_msg (this->name, GF_LOG_ERROR, 0, -diff --git a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c -new file mode 100644 -index 0000000..d1efe06 ---- /dev/null -+++ b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c -@@ -0,0 +1,430 @@ -+/* -+ Copyright (c) 2016 Red Hat, Inc. -+ This file is part of GlusterFS. -+ -+ This file is licensed to you under your choice of the GNU Lesser -+ General Public License, version 3 or any later version (LGPLv3 or -+ later), or the GNU General Public License, version 2 (GPLv2), in all -+ cases as published by the Free Software Foundation. -+*/ -+#include "common-utils.h" -+#include "cli1-xdr.h" -+#include "xdr-generic.h" -+#include "glusterfs.h" -+#include "glusterd.h" -+#include "glusterd-op-sm.h" -+#include "glusterd-geo-rep.h" -+#include "glusterd-store.h" -+#include "glusterd-utils.h" -+#include "glusterd-svc-mgmt.h" -+#include "glusterd-svc-helper.h" -+#include "glusterd-nfs-svc.h" -+#include "glusterd-volgen.h" -+#include "glusterd-messages.h" -+#include "glusterd-mgmt.h" -+#include "run.h" -+#include "syscall.h" -+ -+#include -+ -+int -+glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr, -+ dict_t *rsp_dict) -+{ -+ int ret = 0; -+ int32_t port = 0; -+ char *src_brick = NULL; -+ char *dst_brick = NULL; -+ char *volname = NULL; -+ char *op = NULL; -+ glusterd_op_t gd_op = -1; -+ glusterd_volinfo_t *volinfo = NULL; -+ glusterd_brickinfo_t *src_brickinfo = NULL; -+ char *host = NULL; -+ char msg[2048] = {0}; -+ glusterd_peerinfo_t *peerinfo = NULL; -+ glusterd_brickinfo_t *dst_brickinfo = NULL; -+ gf_boolean_t enabled = _gf_false; -+ glusterd_conf_t *priv = NULL; -+ char *savetok = NULL; -+ char pidfile[PATH_MAX] = {0}; -+ char *task_id_str = NULL; -+ xlator_t *this = NULL; -+ gf_boolean_t is_force = _gf_false; -+ gsync_status_param_t param = {0,}; -+ pid_t pid = -1; -+ uuid_t volume_id = {0,}; -+ char *dup_dstbrick = NULL; -+ -+ this = THIS; -+ GF_ASSERT (this); -+ -+ priv = this->private; -+ GF_ASSERT (priv); -+ -+ ret = glusterd_brick_op_prerequisites (dict, &op, &gd_op, -+ &volname, &volinfo, -+ &src_brick, &src_brickinfo, -+ pidfile, -+ op_errstr, rsp_dict); -+ if (ret) -+ goto out; -+ -+ if (!strcmp (op, "GF_RESET_OP_START")) -+ goto done; -+ -+ if (!strcmp (op, "GF_RESET_OP_COMMIT_FORCE")) -+ is_force = _gf_true; -+ -+ ret = glusterd_get_dst_brick_info (&dst_brick, volname, -+ op_errstr, -+ &dst_brickinfo, &host, -+ dict, &dup_dstbrick); -+ if (ret) -+ goto out; -+ -+ ret = glusterd_new_brick_validate (dst_brick, dst_brickinfo, -+ msg, sizeof (msg), op); -+ /* if bricks are not same and reset brick was used, fail command. -+ * Only replace brick should be used to replace with new bricks -+ * to the volume. -+ */ -+ if (ret == 0) { -+ if (!gf_uuid_compare (MY_UUID, dst_brickinfo->uuid)) { -+ ret = -1; -+ *op_errstr = gf_strdup -+ ("When destination brick is new," -+ " please use" -+ " gluster volume " -+ "replace-brick " -+ " " -+ "commit force"); -+ if (*op_errstr) -+ gf_msg (this->name, -+ GF_LOG_ERROR, -+ EPERM, -+ GD_MSG_BRICK_VALIDATE_FAIL, -+ "%s", *op_errstr); -+ goto out; -+ } -+ } else if (ret == 1) { -+ if (gf_is_service_running (pidfile, &pid)) { -+ ret = -1; -+ *op_errstr = gf_strdup -+ ("Source brick" -+ " must be stopped." -+ " Please use " -+ "gluster volume " -+ "reset-brick " -+ " start."); -+ if (*op_errstr) -+ gf_msg (this->name, -+ GF_LOG_ERROR, -+ EPERM, -+ GD_MSG_BRICK_VALIDATE_FAIL, -+ "%s", *op_errstr); -+ goto out; -+ } -+ ret = sys_lgetxattr (dst_brickinfo->path, -+ GF_XATTR_VOL_ID_KEY, -+ volume_id, 16); -+ if (gf_uuid_compare (dst_brickinfo->uuid, -+ src_brickinfo->uuid) || -+ (ret >= 0 && is_force == _gf_false)) { -+ ret = -1; -+ *op_errstr = gf_strdup ("Brick not available." -+ "It may be containing " -+ "or be contained " -+ "by an existing brick." -+ "Use 'force' option to " -+ "override this."); -+ if (*op_errstr) -+ gf_msg (this->name, -+ GF_LOG_ERROR, -+ EPERM, -+ GD_MSG_BRICK_VALIDATE_FAIL, -+ "%s", *op_errstr); -+ goto out; -+ } -+ ret = 0; -+ } else { -+ *op_errstr = gf_strdup (msg); -+ ret = -1; -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_BRICK_VALIDATE_FAIL, "%s", *op_errstr); -+ goto out; -+ } -+ -+ volinfo->rep_brick.src_brick = src_brickinfo; -+ volinfo->rep_brick.dst_brick = dst_brickinfo; -+ -+ if (gf_is_local_addr (host)) { -+ ret = glusterd_validate_and_create_brickpath -+ (dst_brickinfo, -+ volinfo->volume_id, -+ op_errstr, is_force); -+ if (ret) -+ goto out; -+ } else { -+ rcu_read_lock (); -+ -+ peerinfo = glusterd_peerinfo_find (NULL, host); -+ if (peerinfo == NULL) { -+ ret = -1; -+ snprintf (msg, sizeof (msg), -+ "%s, is not a friend.", -+ host); -+ *op_errstr = gf_strdup (msg); -+ -+ } else if (!peerinfo->connected) { -+ snprintf (msg, sizeof (msg), "%s," -+ "is not connected at " -+ "the moment.", host); -+ *op_errstr = gf_strdup (msg); -+ ret = -1; -+ -+ } else if (GD_FRIEND_STATE_BEFRIENDED != -+ peerinfo->state.state) { -+ snprintf (msg, sizeof (msg), -+ "%s, is not befriended " -+ "at the moment.", host); -+ *op_errstr = gf_strdup (msg); -+ ret = -1; -+ } -+ rcu_read_unlock (); -+ -+ if (ret) -+ goto out; -+ -+ } -+ -+ ret = glusterd_get_brick_mount_dir -+ (dst_brickinfo->path, -+ dst_brickinfo->hostname, -+ dst_brickinfo->mount_dir); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_BRICK_MOUNTDIR_GET_FAIL, -+ "Failed to get brick mount_dir."); -+ goto out; -+ } -+ -+ ret = dict_set_dynstr_with_alloc (rsp_dict, -+ "brick1.mount_dir", -+ dst_brickinfo->mount_dir); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_SET_FAILED, -+ "Failed to set brick1.mount_dir"); -+ goto out; -+ } -+ -+ ret = dict_set_int32 (rsp_dict, "brick_count", 1); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_SET_FAILED, -+ "Failed to set local_brick_count."); -+ goto out; -+ } -+ -+done: -+ ret = 0; -+out: -+ GF_FREE (dup_dstbrick); -+ gf_msg_debug (this->name, 0, "Returning %d.", ret); -+ -+ return ret; -+} -+ -+int -+glusterd_op_reset_brick (dict_t *dict, dict_t *rsp_dict) -+{ -+ int ret = 0; -+ dict_t *ctx = NULL; -+ char *op = NULL; -+ glusterd_volinfo_t *volinfo = NULL; -+ char *volname = NULL; -+ xlator_t *this = NULL; -+ glusterd_conf_t *priv = NULL; -+ char *src_brick = NULL; -+ char *dst_brick = NULL; -+ glusterd_brickinfo_t *src_brickinfo = NULL; -+ glusterd_brickinfo_t *dst_brickinfo = NULL; -+ char *task_id_str = NULL; -+ char pidfile[PATH_MAX] = {0,}; -+ -+ this = THIS; -+ GF_ASSERT (this); -+ -+ priv = this->private; -+ GF_ASSERT (priv); -+ -+ ret = dict_get_str (dict, "operation", &op); -+ if (ret) { -+ gf_msg_debug (this->name, 0, -+ "dict_get on operation failed"); -+ goto out; -+ } -+ -+ ret = dict_get_str (dict, "volname", &volname); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); -+ goto out; -+ } -+ -+ ret = glusterd_volinfo_find (volname, &volinfo); -+ if (ret) -+ goto out; -+ -+ ret = dict_get_str (dict, "src-brick", &src_brick); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "Unable to get src brick"); -+ goto out; -+ } -+ -+ gf_msg_debug (this->name, 0, "src brick=%s", src_brick); -+ -+ ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo, -+ &src_brickinfo, -+ _gf_false); -+ if (ret) { -+ gf_msg_debug (this->name, 0, -+ "Unable to get src-brickinfo"); -+ goto out; -+ } -+ -+ if (!strcmp (op, "GF_RESET_OP_START")) { -+ (void) glusterd_brick_disconnect (src_brickinfo); -+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, -+ src_brickinfo, priv); -+ ret = glusterd_service_stop ("brick", pidfile, -+ SIGTERM, _gf_false); -+ if (ret == 0) { -+ glusterd_set_brick_status (src_brickinfo, -+ GF_BRICK_STOPPED); -+ (void) glusterd_brick_unlink_socket_file -+ (volinfo, src_brickinfo); -+ gf_msg (this->name, GF_LOG_INFO, 0, -+ GD_MSG_BRICK_CLEANUP_SUCCESS, -+ "Brick cleanup successful."); -+ } else { -+ gf_msg (this->name, GF_LOG_CRITICAL, 0, -+ GD_MSG_BRK_CLEANUP_FAIL, -+ "Unable to cleanup src brick"); -+ goto out; -+ } -+ goto out; -+ } else if (!strcmp (op, "GF_RESET_OP_COMMIT") || -+ !strcmp (op, "GF_RESET_OP_COMMIT_FORCE")) { -+ ret = dict_get_str (dict, "dst-brick", &dst_brick); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, -+ "Unable to get dst brick"); -+ goto out; -+ } -+ -+ gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick); -+ -+ ret = glusterd_get_rb_dst_brickinfo (volinfo, -+ &dst_brickinfo); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_RB_BRICKINFO_GET_FAIL, -+ "Unable to get " -+ "reset brick " -+ "destination brickinfo"); -+ goto out; -+ } -+ -+ ret = glusterd_resolve_brick (dst_brickinfo); -+ if (ret) { -+ gf_msg_debug (this->name, 0, -+ "Unable to resolve dst-brickinfo"); -+ goto out; -+ } -+ -+ ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict, -+ dict); -+ if (ret) -+ goto out; -+ -+ if (gf_is_local_addr (dst_brickinfo->hostname)) { -+ gf_msg_debug (this->name, 0, "I AM THE DESTINATION HOST"); -+ (void) glusterd_brick_disconnect (src_brickinfo); -+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, -+ src_brickinfo, priv); -+ ret = glusterd_service_stop ("brick", pidfile, -+ SIGTERM, _gf_false); -+ if (ret == 0) { -+ glusterd_set_brick_status -+ (src_brickinfo, GF_BRICK_STOPPED); -+ (void) glusterd_brick_unlink_socket_file -+ (volinfo, src_brickinfo); -+ gf_msg (this->name, GF_LOG_INFO, 0, -+ GD_MSG_BRICK_CLEANUP_SUCCESS, -+ "Brick cleanup successful."); -+ } else { -+ gf_msg (this->name, GF_LOG_CRITICAL, 0, -+ GD_MSG_BRK_CLEANUP_FAIL, -+ "Unable to cleanup src brick"); -+ goto out; -+ } -+ } -+ -+ ret = glusterd_svcs_stop (volinfo); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_GLUSTER_SERVICES_STOP_FAIL, -+ "Unable to stop gluster services, ret: %d", -+ ret); -+ goto out; -+ } -+ ret = glusterd_op_perform_replace_brick (volinfo, src_brick, -+ dst_brick, dict); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_CRITICAL, 0, -+ GD_MSG_BRICK_ADD_FAIL, -+ "Unable to add dst-brick: " -+ "%s to volume: %s", dst_brick, -+ volinfo->volname); -+ (void) glusterd_svcs_manager (volinfo); -+ goto out; -+ } -+ -+ volinfo->rebal.defrag_status = 0; -+ -+ ret = glusterd_svcs_manager (volinfo); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_CRITICAL, 0, -+ GD_MSG_GLUSTER_SERVICE_START_FAIL, -+ "Failed to start one or more gluster services."); -+ } -+ -+ -+ ret = glusterd_fetchspec_notify (THIS); -+ glusterd_brickinfo_delete (volinfo->rep_brick.dst_brick); -+ volinfo->rep_brick.src_brick = NULL; -+ volinfo->rep_brick.dst_brick = NULL; -+ -+ if (!ret) -+ ret = glusterd_store_volinfo (volinfo, -+ GLUSTERD_VOLINFO_VER_AC_INCREMENT); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_RBOP_STATE_STORE_FAIL, -+ "Couldn't store" -+ " reset brick operation's state."); -+ -+ } -+ } else { -+ ret = -1; -+ goto out; -+ } -+ -+ -+out: -+ return ret; -+} -diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -index c87a6da..51deeff 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c -@@ -144,6 +144,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret, - case GD_OP_BITROT: - case GD_OP_SCRUB_STATUS: - case GD_OP_SCRUB_ONDEMAND: -+ case GD_OP_RESET_BRICK: - { - /*nothing specific to be done*/ - break; -diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c -index 64a0aeb..47100c1 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-syncop.c -+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c -@@ -248,6 +248,7 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp) - break; - - case GD_OP_REPLACE_BRICK: -+ case GD_OP_RESET_BRICK: - ret = glusterd_rb_use_rsp_dict (aggr, rsp); - if (ret) - goto out; -diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c -index 6b18d17..375b965 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c -@@ -6002,7 +6002,7 @@ glusterd_is_defrag_on (glusterd_volinfo_t *volinfo) - - int - glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo, -- char *op_errstr, size_t len) -+ char *op_errstr, size_t len, char *op) - { - glusterd_brickinfo_t *newbrickinfo = NULL; - int ret = -1; -@@ -6043,8 +6043,12 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo, - newbrickinfo->path)) { - snprintf(op_errstr, len, "Brick: %s not available." - " Brick may be containing or be contained " -- "by an existing brick", brick); -- ret = -1; -+ "by an existing brick.", brick); -+ if (op && (!strcmp (op, "GF_RESET_OP_COMMIT") || -+ !strcmp (op, "GF_RESET_OP_COMMIT_FORCE"))) -+ ret = 1; -+ else -+ ret = -1; - goto out; - } - -@@ -11490,6 +11494,7 @@ glusterd_disallow_op_for_tier (glusterd_volinfo_t *volinfo, glusterd_op_t op, - switch (op) { - case GD_OP_ADD_BRICK: - case GD_OP_REPLACE_BRICK: -+ case GD_OP_RESET_BRICK: - ret = -1; - gf_msg_debug (this->name, 0, "Operation not " - "permitted on tiered volume %s", -@@ -11739,3 +11744,319 @@ get_last_brick_of_brick_group (glusterd_volinfo_t *volinfo, - - return last; - } -+ -+int -+glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo, -+ glusterd_brickinfo_t **brickinfo) -+{ -+ int32_t ret = -1; -+ -+ if (!volinfo || !brickinfo) -+ goto out; -+ -+ *brickinfo = volinfo->rep_brick.dst_brick; -+ -+ ret = 0; -+ -+out: -+ return ret; -+} -+ -+int -+rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict, -+ dict_t *req_dict) -+{ -+ int ret = 0; -+ int dict_ret = 0; -+ int dst_port = 0; -+ -+ dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port); -+ if (!dict_ret) -+ dst_brickinfo->port = dst_port; -+ -+ if (gf_is_local_addr (dst_brickinfo->hostname)) { -+ gf_msg ("glusterd", GF_LOG_INFO, 0, -+ GD_MSG_BRK_PORT_NO_ADD_INDO, -+ "adding dst-brick port no %d", dst_port); -+ -+ if (rsp_dict) { -+ ret = dict_set_int32 (rsp_dict, "dst-brick-port", -+ dst_brickinfo->port); -+ if (ret) { -+ gf_msg_debug ("glusterd", 0, -+ "Could not set dst-brick port no in rsp dict"); -+ goto out; -+ } -+ } -+ -+ if (req_dict && !dict_ret) { -+ ret = dict_set_int32 (req_dict, "dst-brick-port", -+ dst_brickinfo->port); -+ if (ret) { -+ gf_msg_debug ("glusterd", 0, -+ "Could not set dst-brick port no"); -+ goto out; -+ } -+ } -+ } -+out: -+ return ret; -+} -+ -+int -+glusterd_brick_op_prerequisites (dict_t *dict, -+ char **op, -+ glusterd_op_t *gd_op, char **volname, -+ glusterd_volinfo_t **volinfo, -+ char **src_brick, glusterd_brickinfo_t -+ **src_brickinfo, char *pidfile, -+ char **op_errstr, dict_t *rsp_dict) -+{ -+ int ret = 0; -+ char msg[2048] = {0}; -+ gsync_status_param_t param = {0,}; -+ xlator_t *this = NULL; -+ glusterd_conf_t *priv = NULL; -+ glusterd_volinfo_t *v = NULL; -+ glusterd_brickinfo_t *b = NULL; -+ -+ this = THIS; -+ GF_ASSERT (this); -+ -+ priv = this->private; -+ GF_ASSERT (priv); -+ -+ ret = dict_get_str (dict, "operation", op); -+ if (ret) { -+ gf_msg_debug (this->name, 0, -+ "dict get on operation type failed"); -+ goto out; -+ } -+ -+ *gd_op = gd_cli_to_gd_op (*op); -+ if (*gd_op < 0) -+ goto out; -+ -+ ret = dict_get_str (dict, "volname", volname); -+ -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "Unable to get volume name"); -+ goto out; -+ } -+ -+ ret = glusterd_volinfo_find (*volname, volinfo); -+ if (ret) { -+ snprintf (msg, sizeof (msg), "volume: %s does not exist", -+ *volname); -+ *op_errstr = gf_strdup (msg); -+ goto out; -+ } -+ -+ if (GLUSTERD_STATUS_STARTED != (*volinfo)->status) { -+ ret = -1; -+ snprintf (msg, sizeof (msg), "volume: %s is not started", -+ *volname); -+ *op_errstr = gf_strdup (msg); -+ goto out; -+ } -+ -+ ret = glusterd_disallow_op_for_tier (*volinfo, *gd_op, -1); -+ if (ret) { -+ snprintf (msg, sizeof (msg), "%sbrick commands are not " -+ "supported on tiered volume %s", -+ (*gd_op == GD_OP_REPLACE_BRICK) ? "replace-" : -+ "reset-", -+ *volname); -+ *op_errstr = gf_strdup (msg); -+ goto out; -+ } -+ -+ /* If geo-rep is configured, for this volume, it should be stopped. */ -+ param.volinfo = *volinfo; -+ ret = glusterd_check_geo_rep_running (¶m, op_errstr); -+ if (ret || param.is_active) { -+ ret = -1; -+ goto out; -+ } -+ -+ if (glusterd_is_defrag_on(*volinfo)) { -+ snprintf (msg, sizeof(msg), "Volume name %s rebalance is in " -+ "progress. Please retry after completion", *volname); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_OIP_RETRY_LATER, "%s", msg); -+ *op_errstr = gf_strdup (msg); -+ ret = -1; -+ goto out; -+ } -+ -+ if (dict) { -+ if (!glusterd_is_fuse_available ()) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ (*gd_op == GD_OP_REPLACE_BRICK) ? -+ GD_MSG_RB_CMD_FAIL : -+ GD_MSG_RESET_BRICK_CMD_FAIL, -+ "Unable to open /dev/" -+ "fuse (%s), %s command failed", -+ strerror (errno), gd_rb_op_to_str (*op)); -+ snprintf (msg, sizeof(msg), "Fuse unavailable\n " -+ "%s failed", gd_rb_op_to_str (*op)); -+ *op_errstr = gf_strdup (msg); -+ ret = -1; -+ goto out; -+ } -+ } -+ -+ ret = dict_get_str (dict, "src-brick", src_brick); -+ -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, "Unable to get src brick"); -+ goto out; -+ } -+ -+ gf_msg_debug (this->name, 0, "src brick=%s", *src_brick); -+ -+ ret = glusterd_volume_brickinfo_get_by_brick (*src_brick, *volinfo, -+ src_brickinfo, -+ _gf_false); -+ if (ret) { -+ snprintf (msg, sizeof (msg), "brick: %s does not exist in " -+ "volume: %s", *src_brick, *volname); -+ *op_errstr = gf_strdup (msg); -+ goto out; -+ } -+ -+ if (gf_is_local_addr ((*src_brickinfo)->hostname)) { -+ gf_msg_debug (this->name, 0, -+ "I AM THE SOURCE HOST"); -+ if ((*src_brickinfo)->port && rsp_dict) { -+ ret = dict_set_int32 (rsp_dict, "src-brick-port", -+ (*src_brickinfo)->port); -+ if (ret) { -+ gf_msg_debug (this->name, 0, -+ "Could not set src-brick-port=%d", -+ (*src_brickinfo)->port); -+ } -+ } -+ -+ v = *volinfo; -+ b = *src_brickinfo; -+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, v, b, -+ priv); -+ } -+ -+ ret = 0; -+out: -+ return ret; -+} -+ -+int -+glusterd_get_dst_brick_info (char **dst_brick, char *volname, char **op_errstr, -+ glusterd_brickinfo_t **dst_brickinfo, char **host, -+ dict_t *dict, char **dup_dstbrick) -+{ -+ -+ char *path = NULL; -+ char *c = NULL; -+ char msg[2048] = {0}; -+ xlator_t *this = NULL; -+ glusterd_conf_t *priv = NULL; -+ int ret = 0; -+ -+ this = THIS; -+ GF_ASSERT (this); -+ -+ priv = this->private; -+ GF_ASSERT (priv); -+ -+ ret = dict_get_str (dict, "dst-brick", dst_brick); -+ -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, -+ "Unable to get dest brick."); -+ goto out; -+ } -+ -+ gf_msg_debug (this->name, 0, "dst brick=%s", *dst_brick); -+ -+ if (!glusterd_store_is_valid_brickpath (volname, *dst_brick) || -+ !glusterd_is_valid_volfpath (volname, *dst_brick)) { -+ snprintf (msg, sizeof (msg), "brick path %s is too " -+ "long.", *dst_brick); -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_BRKPATH_TOO_LONG, "%s", msg); -+ *op_errstr = gf_strdup (msg); -+ -+ ret = -1; -+ goto out; -+ } -+ -+ *dup_dstbrick = gf_strdup (*dst_brick); -+ if (!*dup_dstbrick) { -+ ret = -1; -+ goto out; -+ } -+ -+ /* -+ * IPv4 address contains '.' and ipv6 addresses contains ':' -+ * So finding the last occurance of ':' to -+ * mark the start of brick path -+ */ -+ c = strrchr(*dup_dstbrick, ':'); -+ if (c != NULL) { -+ c[0] = '\0'; -+ *host = *dup_dstbrick; -+ path = c++; -+ } -+ -+ if (!host || !path) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_BAD_FORMAT, -+ "dst brick %s is not of " -+ "form :", -+ *dst_brick); -+ ret = -1; -+ goto out; -+ } -+ -+ ret = glusterd_brickinfo_new_from_brick (*dst_brick, -+ dst_brickinfo, -+ _gf_true, NULL); -+ if (ret) -+ goto out; -+ -+ ret = 0; -+out: -+ return ret; -+} -+ -+glusterd_op_t -+gd_cli_to_gd_op (char *cli_op) -+{ -+ if (!strcmp (cli_op, "GF_RESET_OP_START") || -+ !strcmp(cli_op, "GF_RESET_OP_COMMIT") || -+ !strcmp (cli_op, "GF_RESET_OP_COMMIT_FORCE")) { -+ return GD_OP_RESET_BRICK; -+ } -+ -+ if (!strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE")) -+ return GD_OP_REPLACE_BRICK; -+ -+ return -1; -+} -+ -+char * -+gd_rb_op_to_str (char *op) -+{ -+ if (!strcmp (op, "GF_RESET_OP_START")) -+ return "reset-brick start"; -+ if (!strcmp (op, "GF_RESET_OP_COMMIT")) -+ return "reset-brick commit"; -+ if (!strcmp (op, "GF_RESET_OP_COMMIT_FORCE")) -+ return "reset-brick commit force"; -+ if (!strcmp (op, "GF_REPLACE_OP_COMMIT_FORCE")) -+ return "replace-brick commit force"; -+ return NULL; -+} -diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h -index ca07efd..419ab48 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-utils.h -+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h -@@ -242,7 +242,7 @@ glusterd_volinfo_bricks_delete (glusterd_volinfo_t *volinfo); - - int - glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo, -- char *op_errstr, size_t len); -+ char *op_errstr, size_t len, char *op); - int32_t - glusterd_volume_brickinfos_delete (glusterd_volinfo_t *volinfo); - -@@ -741,4 +741,36 @@ assign_brick_groups (glusterd_volinfo_t *volinfo); - glusterd_brickinfo_t* - get_last_brick_of_brick_group (glusterd_volinfo_t *volinfo, - glusterd_brickinfo_t *brickinfo); -+int -+glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo, -+ glusterd_brickinfo_t **brickinfo); -+int -+rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict, -+ dict_t *req_dict); -+int -+glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, -+ char *old_brick, char *new_brick, -+ dict_t *dict); -+int32_t -+glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo, -+ glusterd_brickinfo_t *brickinfo); -+char * -+gd_rb_op_to_str (char *op); -+ -+glusterd_op_t -+gd_cli_to_gd_op (char *cli_op); -+ -+int -+glusterd_get_dst_brick_info (char **dst_brick, char *volname, char **op_errstr, -+ glusterd_brickinfo_t **dst_brickinfo, char **host, -+ dict_t *dict, char **dup_dstbrick); -+ -+int -+glusterd_brick_op_prerequisites (dict_t *dict, -+ char **op, -+ glusterd_op_t *gd_op, char **volname, -+ glusterd_volinfo_t **volinfo, -+ char **src_brick, glusterd_brickinfo_t -+ **src_brickinfo, char *pidfile, -+ char **op_errstr, dict_t *rsp_dict); - #endif -diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -index 2b1c50a..204ea3f 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -@@ -1253,7 +1253,7 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr, - goto out; - - ret = glusterd_new_brick_validate (brick, brick_info, msg, -- sizeof (msg)); -+ sizeof (msg), NULL); - if (ret) - goto out; - -diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c -index 7d39637..498672b 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.c -+++ b/xlators/mgmt/glusterd/src/glusterd.c -@@ -123,6 +123,7 @@ const char *gd_op_list[GD_OP_MAX + 1] = { - [GD_OP_SYS_EXEC] = "Execute system commands", - [GD_OP_GSYNC_CREATE] = "Geo-replication Create", - [GD_OP_SNAP] = "Snapshot", -+ [GD_OP_RESET_BRICK] = "Reset Brick", - [GD_OP_MAX] = "Invalid op" - }; - -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index 7ca589c..8013c58 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -119,6 +119,7 @@ typedef enum glusterd_op_ { - GD_OP_TIER_MIGRATE, - GD_OP_SCRUB_STATUS, - GD_OP_SCRUB_ONDEMAND, -+ GD_OP_RESET_BRICK, - GD_OP_MAX, - } glusterd_op_t; - -@@ -950,6 +951,9 @@ int - glusterd_handle_fsm_log (rpcsvc_request_t *req); - - int -+glusterd_handle_reset_brick (rpcsvc_request_t *req); -+ -+int - glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret, - int32_t op_errno, char *op_errstr, - char *hostname, dict_t *dict); -@@ -1192,4 +1196,6 @@ int - glusterd_remove_brick_migrate_cbk (glusterd_volinfo_t *volinfo, - gf_defrag_status_t status); - -+int -+__glusterd_handle_reset_brick (rpcsvc_request_t *req); - #endif --- -1.7.1 - diff --git a/SOURCES/0058-glusterd-ganesha-perform-removal-of-ganesha.conf-on-.patch b/SOURCES/0058-glusterd-ganesha-perform-removal-of-ganesha.conf-on-.patch new file mode 100644 index 0000000..7d7388b --- /dev/null +++ b/SOURCES/0058-glusterd-ganesha-perform-removal-of-ganesha.conf-on-.patch @@ -0,0 +1,54 @@ +From 06a24c4e6ec4d876bb5c9216a6b5f5364d58dc10 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Fri, 28 Apr 2017 17:27:46 +0530 +Subject: [PATCH 58/74] glusterd/ganesha : perform removal of ganesha.conf on + nodes only in ganesha cluster + +Change-Id: I864ecd9391adf80fb1fa6ad2f9891a9ce77135e7 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/17138 +Smoke: Gluster Build System +Reviewed-by: soumya k +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: Kaleb KEITHLEY +--- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index 38fa378..2392341 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -740,17 +740,18 @@ stop_ganesha (char **op_errstr) { + int ret = 0; + runner_t runner = {0,}; + +- runinit (&runner); +- runner_add_args (&runner, +- GANESHA_PREFIX"/ganesha-ha.sh", +- "--setup-ganesha-conf-files", CONFDIR, "no", NULL); +- ret = runner_run (&runner); +- if (ret) { +- gf_asprintf (op_errstr, "removal of symlink ganesha.conf " +- "in /etc/ganesha failed"); +- } +- + if (check_host_list ()) { ++ runinit (&runner); ++ runner_add_args (&runner, ++ GANESHA_PREFIX"/ganesha-ha.sh", ++ "--setup-ganesha-conf-files", CONFDIR, ++ "no", NULL); ++ ret = runner_run (&runner); ++ if (ret) { ++ gf_asprintf (op_errstr, "removal of symlink ganesha.conf " ++ "in /etc/ganesha failed"); ++ } ++ + ret = manage_service ("stop"); + if (ret) + gf_asprintf (op_errstr, "NFS-Ganesha service could not" +-- +1.8.3.1 + diff --git a/SOURCES/0059-Revert-glusterd-ganesha-copy-ganesha-export-configur.patch b/SOURCES/0059-Revert-glusterd-ganesha-copy-ganesha-export-configur.patch deleted file mode 100644 index e37cdc9..0000000 --- a/SOURCES/0059-Revert-glusterd-ganesha-copy-ganesha-export-configur.patch +++ /dev/null @@ -1,529 +0,0 @@ -From 79bef076f8210eab2b0ac8e70580b8906bf818b1 Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Tue, 12 Jul 2016 17:23:03 +0530 -Subject: [PATCH 59/86] Revert "glusterd-ganesha : copy ganesha export configuration files during reboot" - -This reverts commit f71e2fa49af185779b9f43e146effd122d4e9da0. - -Reason: -As part of sync up node reboot this patch copies ganesha export conf file -from a source node. This change is no more require if the export files are -available in shared storage. - -Upstream reference : ->Change-Id: Id9c1ae78377bbd7d5d80aa1c14f534e30feaae97 ->BUG: 1355956 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/14907 ->Reviewed-by: soumya k ->Smoke: Gluster Build System ->CentOS-regression: Gluster Build System ->NetBSD-regression: NetBSD Build System ->Reviewed-by: Kaleb KEITHLEY ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: Id9c1ae78377bbd7d5d80aa1c14f534e30feaae97 -BUG: 1348949 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84778 -Reviewed-by: Atin Mukherjee ---- - extras/ganesha/scripts/Makefile.am | 4 +- - extras/ganesha/scripts/copy-export-ganesha.sh | 97 ----------- - xlators/mgmt/glusterd/src/glusterd-ganesha.c | 194 ++++++++--------------- - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 2 +- - xlators/mgmt/glusterd/src/glusterd-utils.c | 32 ---- - xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 +- - xlators/mgmt/glusterd/src/glusterd.h | 3 +- - 7 files changed, 73 insertions(+), 261 deletions(-) - delete mode 100755 extras/ganesha/scripts/copy-export-ganesha.sh - -diff --git a/extras/ganesha/scripts/Makefile.am b/extras/ganesha/scripts/Makefile.am -index c326fc2..224ed26 100644 ---- a/extras/ganesha/scripts/Makefile.am -+++ b/extras/ganesha/scripts/Makefile.am -@@ -1,6 +1,6 @@ - EXTRA_DIST= ganesha-ha.sh dbus-send.sh create-export-ganesha.sh \ -- generate-epoch.py copy-export-ganesha.sh -+ generate-epoch.py - - scriptsdir = $(libexecdir)/ganesha - scripts_SCRIPTS = create-export-ganesha.sh dbus-send.sh ganesha-ha.sh \ -- generate-epoch.py copy-export-ganesha.sh -+ generate-epoch.py -diff --git a/extras/ganesha/scripts/copy-export-ganesha.sh b/extras/ganesha/scripts/copy-export-ganesha.sh -deleted file mode 100755 -index 9c4afa0..0000000 ---- a/extras/ganesha/scripts/copy-export-ganesha.sh -+++ /dev/null -@@ -1,97 +0,0 @@ --#!/bin/bash -- --#This script is called by glusterd when in case of --#reboot.An export file specific to a volume --#is copied in GANESHA_DIR/exports from online node. -- --# Try loading the config from any of the distro --# specific configuration locations --if [ -f /etc/sysconfig/ganesha ] -- then -- . /etc/sysconfig/ganesha --fi --if [ -f /etc/conf.d/ganesha ] -- then -- . /etc/conf.d/ganesha --fi --if [ -f /etc/default/ganesha ] -- then -- . /etc/default/ganesha --fi -- --GANESHA_DIR=${1%/} --VOL=$2 --CONF= --host=$(hostname -s) --SECRET_PEM="/var/lib/glusterd/nfs/secret.pem" -- --function check_cmd_status() --{ -- if [ "$1" != "0" ] -- then -- rm -rf $GANESHA_DIR/exports/export.$VOL.conf -- exit 1 -- fi --} -- -- --if [ ! -d "$GANESHA_DIR/exports" ]; -- then -- mkdir $GANESHA_DIR/exports -- check_cmd_status `echo $?` --fi -- --function find_rhel7_conf --{ -- while [[ $# > 0 ]] -- do -- key="$1" -- case $key in -- -f) -- CONFFILE="$2" -- ;; -- *) -- ;; -- esac -- shift -- done --} -- --if [ -z $CONFFILE ]; then -- find_rhel7_conf $OPTIONS -- --fi --CONF=${CONFFILE:-/etc/ganesha/ganesha.conf} -- --#remove the old export entry from NFS-Ganesha --#if already exported --dbus-send --type=method_call --print-reply --system \ -- --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ -- org.ganesha.nfsd.exportmgr.ShowExports \ -- | grep -w -q "/$VOL" --if [ $? -eq 0 ]; then -- removed_id=`cat $GANESHA_DIR/exports/export.$VOL.conf |\ -- grep Export_Id | awk -F"[=,;]" '{print$2}' | tr -d '[[:space:]]'` -- -- dbus-send --print-reply --system --dest=org.ganesha.nfsd \ -- /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.RemoveExport \ -- uint16:$removed_id 2>&1 --fi -- --ha_servers=$(pcs status | grep "Online:" | grep -o '\[.*\]' | sed -e 's/\[//' | sed -e 's/\]//') --IFS=$' ' --for server in ${ha_servers} ; do -- current_host=`echo $server | cut -d "." -f 1` -- if [ $host != $current_host ] -- then -- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ -- ${SECRET_PEM} $server:$GANESHA_DIR/exports/export.$VOL.conf \ -- $GANESHA_DIR/exports/export.$VOL.conf -- break -- fi --done -- --if ! (cat $CONF | grep $VOL.conf\"$ ) --then --echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF --fi -diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -index 2406519..38fc1f6 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c -+++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -@@ -427,42 +427,23 @@ create_export_config (char *volname, char **op_errstr) - CONFDIR, volname, NULL); - ret = runner_run(&runner); - -- if (ret && op_errstr) -+ if (ret) - gf_asprintf (op_errstr, "Failed to create" - " NFS-Ganesha export config file."); - - return ret; - } - --int --copy_export_config (char *volname, char **op_errstr) --{ -- runner_t runner = {0,}; -- int ret = -1; -- -- GF_ASSERT(volname); -- runinit (&runner); -- runner_add_args (&runner, "sh", -- GANESHA_PREFIX"/copy-export-ganesha.sh", -- CONFDIR, volname, NULL); -- ret = runner_run(&runner); -- -- if (ret && op_errstr) -- gf_asprintf (op_errstr, "Failed to copy" -- " NFS-Ganesha export config file."); -- -- return ret; --} - /* Exports and unexports a particular volume via NFS-Ganesha */ - int --ganesha_manage_export (char *volname, char *value, char **op_errstr, -- gf_boolean_t reboot) -+ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) - { - runner_t runner = {0,}; - int ret = -1; - char str[1024]; - glusterd_volinfo_t *volinfo = NULL; - dict_t *vol_opts = NULL; -+ char *volname = NULL; - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - gf_boolean_t option = _gf_false; -@@ -474,10 +455,16 @@ ganesha_manage_export (char *volname, char *value, char **op_errstr, - priv = this->private; - - GF_ASSERT (value); -+ GF_ASSERT (dict); - GF_ASSERT (priv); -- GF_VALIDATE_OR_GOTO (this->name, volname, out); -- - -+ ret = dict_get_str (dict, "volname", &volname); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, errno, -+ GD_MSG_DICT_GET_FAILED, -+ "Unable to get volume name"); -+ goto out; -+ } - ret = gf_string2boolean (value, &option); - if (ret == -1) { - gf_msg (this->name, GF_LOG_ERROR, EINVAL, -@@ -485,77 +472,54 @@ ganesha_manage_export (char *volname, char *value, char **op_errstr, - goto out; - } - -- /* * -- * Incase of reboot, following checks are already made before calling -- * ganesha_manage_export. So it will be reductant do it again -- */ -- if (!reboot) { -- ret = glusterd_volinfo_find (volname, &volinfo); -- if (ret) { -- gf_msg (this->name, GF_LOG_ERROR, EINVAL, -- GD_MSG_VOL_NOT_FOUND, -- FMTSTR_CHECK_VOL_EXISTS, volname); -- goto out; -- } -+ ret = glusterd_volinfo_find (volname, &volinfo); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, EINVAL, -+ GD_MSG_VOL_NOT_FOUND, -+ FMTSTR_CHECK_VOL_EXISTS, volname); -+ goto out; -+ } - -- ret = glusterd_check_ganesha_export (volinfo); -- if (ret && option) { -- if (op_errstr) -- gf_asprintf (op_errstr, "ganesha.enable " -- "is already 'on'."); -- ret = -1; -- goto out; -+ ret = glusterd_check_ganesha_export (volinfo); -+ if (ret && option) { -+ gf_asprintf (op_errstr, "ganesha.enable " -+ "is already 'on'."); -+ ret = -1; -+ goto out; - -- } else if (!option && !ret) { -- if (op_errstr) -- gf_asprintf (op_errstr, "ganesha.enable " -- "is already 'off'."); -- ret = -1; -- goto out; -- } -+ } else if (!option && !ret) { -+ gf_asprintf (op_errstr, "ganesha.enable " -+ "is already 'off'."); -+ ret = -1; -+ goto out; - } - -- ret = 0; -- -- /* * -- * Incase of restart, there is chance that global option turned off -- * with volume set command. Still we may need to clean up the -- * configuration files. -- * Otherwise check if global option is enabled, only then proceed -- * */ -- if (!(reboot && !option)) { -- ret = dict_get_str_boolean (priv->opts, -+ /* Check if global option is enabled, proceed only then */ -+ ret = dict_get_str_boolean (priv->opts, - GLUSTERD_STORE_KEY_GANESHA_GLOBAL, _gf_false); -- if (ret == -1) { -- gf_msg_debug (this->name, 0, "Failed to get " -- "global option dict."); -- if (op_errstr) -- gf_asprintf (op_errstr, "The option " -- "nfs-ganesha should be " -- "enabled before setting " -- "ganesha.enable."); -- goto out; -- } -- if (!ret) { -- if (op_errstr) -- gf_asprintf (op_errstr, "The option " -- "nfs-ganesha should be " -- "enabled before setting " -- "ganesha.enable."); -- ret = -1; -- goto out; -- } -+ if (ret == -1) { -+ gf_msg_debug (this->name, 0, "Failed to get " -+ "global option dict."); -+ gf_asprintf (op_errstr, "The option " -+ "nfs-ganesha should be " -+ "enabled before setting ganesha.enable."); -+ goto out; - } -+ if (!ret) { -+ gf_asprintf (op_errstr, "The option " -+ "nfs-ganesha should be " -+ "enabled before setting ganesha.enable."); -+ ret = -1; -+ goto out; -+ } -+ - /* Create the export file only when ganesha.enable "on" is executed */ - if (option) { -- if (reboot) -- ret = copy_export_config (volname, op_errstr); -- else -- ret = create_export_config (volname, op_errstr); -+ ret = create_export_config (volname, op_errstr); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_EXPORT_FILE_CREATE_FAIL, -- "Failed to create/copy " -+ "Failed to create" - "export file for NFS-Ganesha\n"); - goto out; - } -@@ -566,42 +530,25 @@ ganesha_manage_export (char *volname, char *value, char **op_errstr, - CONFDIR, value, volname, NULL); - ret = runner_run (&runner); - if (ret) { -- if (op_errstr) -- gf_asprintf(op_errstr, "Dynamic export" -- " addition/deletion failed." -- " Please see log file for details"); -- /* * -- * Incase of reboot scenarios, we cannot guarantee -- * nfs-ganesha to be running on that node, so that -- * dynamic export may fail -- */ -- if (reboot) -- ret = 0; -- else -- goto out; -+ gf_asprintf(op_errstr, "Dynamic export" -+ " addition/deletion failed." -+ " Please see log file for details"); -+ goto out; - } - } - -+ vol_opts = volinfo->dict; -+ ret = dict_set_dynstr_with_alloc (vol_opts, -+ "features.cache-invalidation", value); -+ if (ret) -+ gf_asprintf (op_errstr, "Cache-invalidation could not" -+ " be set to %s.", value); -+ ret = glusterd_store_volinfo (volinfo, -+ GLUSTERD_VOLINFO_VER_AC_INCREMENT); -+ if (ret) -+ gf_asprintf (op_errstr, "failed to store volinfo for %s" -+ , volinfo->volname); - -- /* * -- * cache-invalidation should be on when a volume is exported -- * and off when a volume is unexported. It is not required -- * for reboot scenarios, already it will be copied. -- * */ -- if (!reboot) { -- vol_opts = volinfo->dict; -- ret = dict_set_dynstr_with_alloc (vol_opts, -- "features.cache-invalidation", value); -- if (ret && op_errstr) -- gf_asprintf (op_errstr, "Cache-invalidation could not" -- " be set to %s.", value); -- ret = glusterd_store_volinfo (volinfo, -- GLUSTERD_VOLINFO_VER_AC_INCREMENT); -- if (ret && op_errstr) -- gf_asprintf (op_errstr, "failed to store volinfo for %s" -- , volinfo->volname); -- -- } - out: - return ret; - } -@@ -862,9 +809,12 @@ glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, - char *key, char *value) - { - -- int32_t ret = -1; -+ int32_t ret = -1; - char *volname = NULL; -+ xlator_t *this = NULL; - gf_boolean_t option = _gf_false; -+ static int export_id = 1; -+ glusterd_volinfo_t *volinfo = NULL; - - GF_ASSERT (dict); - GF_ASSERT (op_errstr); -@@ -873,15 +823,7 @@ glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, - - - if (strcmp (key, "ganesha.enable") == 0) { -- ret = dict_get_str (dict, "volname", &volname); -- if (ret) { -- gf_msg (THIS->name, GF_LOG_ERROR, errno, -- GD_MSG_DICT_GET_FAILED, -- "Unable to get volume name"); -- goto out; -- } -- ret = ganesha_manage_export (volname, value, op_errstr, -- _gf_false); -+ ret = ganesha_manage_export (dict, value, op_errstr); - if (ret < 0) - goto out; - } -diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index 0521a9c..a228ba6 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c -+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -2163,7 +2163,7 @@ glusterd_op_reset_volume (dict_t *dict, char **op_rspstr) - quorum_action = _gf_true; - ret = glusterd_check_ganesha_export (volinfo); - if (ret) { -- ret = ganesha_manage_export (volname, "off", op_rspstr, _gf_false); -+ ret = ganesha_manage_export (dict, "off", op_rspstr); - if (ret) { - gf_msg (THIS->name, GF_LOG_WARNING, 0, - GD_MSG_NFS_GNS_RESET_FAIL, -diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c -index 375b965..bf27fe3 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c -@@ -4093,9 +4093,6 @@ glusterd_import_friend_volume (dict_t *peer_data, size_t count) - glusterd_volinfo_t *old_volinfo = NULL; - glusterd_volinfo_t *new_volinfo = NULL; - glusterd_svc_t *svc = NULL; -- gf_boolean_t newexportvalue; -- gf_boolean_t oldexportvalue; -- char *value = NULL; - - GF_ASSERT (peer_data); - -@@ -4116,8 +4113,6 @@ glusterd_import_friend_volume (dict_t *peer_data, size_t count) - - ret = glusterd_volinfo_find (new_volinfo->volname, &old_volinfo); - if (0 == ret) { -- oldexportvalue = glusterd_check_ganesha_export (old_volinfo); -- - /* Ref count the old_volinfo such that deleting it doesn't crash - * if its been already in use by other thread - */ -@@ -4151,33 +4146,6 @@ glusterd_import_friend_volume (dict_t *peer_data, size_t count) - } - } - -- ret = glusterd_volinfo_get (new_volinfo, "ganesha.enable", &value); -- if (ret) -- goto out; -- ret = gf_string2boolean (value, &newexportvalue); -- if (ret) -- goto out; -- -- /* * -- * if new and old export value is off, then there is no point in calling -- * ganesha_manage_export -- */ -- if (!((newexportvalue == oldexportvalue) && -- newexportvalue == _gf_false)) { -- ret = ganesha_manage_export (new_volinfo->volname, value, -- NULL, _gf_true); -- if (ret) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_NFS_GNS_OP_HANDLE_FAIL, -- "Returning from ganesha_manage_export with" -- " ret: %d for volume %s ganesha.enable %s", -- ret, new_volinfo->volname, -- value); -- gf_event (EVENT_NFS_GANESHA_EXPORT_FAILED, "volume=%s", -- new_volinfo->volname); -- goto out; -- } -- } - ret = glusterd_store_volinfo (new_volinfo, GLUSTERD_VOLINFO_VER_AC_NONE); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, -diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -index 204ea3f..fcb4b3e 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c -@@ -1697,7 +1697,7 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) - } - ret = glusterd_check_ganesha_export (volinfo); - if (ret) { -- ret = ganesha_manage_export (volname, "off", op_errstr, _gf_false); -+ ret = ganesha_manage_export(dict, "off", op_errstr); - if (ret) { - gf_msg (THIS->name, GF_LOG_WARNING, 0, - GD_MSG_NFS_GNS_UNEXPRT_VOL_FAIL, "Could not " -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index 8013c58..84b38e5 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -1072,8 +1072,7 @@ int glusterd_check_ganesha_cmd (char *key, char *value, - char **errstr, dict_t *dict); - int glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr); - int glusterd_op_set_ganesha (dict_t *dict, char **errstr); --int ganesha_manage_export (char *volname, char *value, char **op_errstr, -- gf_boolean_t reboot); -+int ganesha_manage_export (dict_t *dict, char *value, char **op_errstr); - gf_boolean_t glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo); - int stop_ganesha (char **op_errstr); - int tear_down_cluster (gf_boolean_t run_teardown); --- -1.7.1 - diff --git a/SOURCES/0059-glusterd-ganesha-update-cache-invalidation-properly-.patch b/SOURCES/0059-glusterd-ganesha-update-cache-invalidation-properly-.patch new file mode 100644 index 0000000..e86575e --- /dev/null +++ b/SOURCES/0059-glusterd-ganesha-update-cache-invalidation-properly-.patch @@ -0,0 +1,134 @@ +From 2cd1f86d0bd47f93f6e278530fc76a1e44aa9333 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Tue, 25 Apr 2017 16:36:40 +0530 +Subject: [PATCH 59/74] glusterd/ganesha : update cache invalidation properly + during volume stop + +As per current code, during volume stop for ganesha enabled volume the +feature.cache-invalidation was turned "off" in ganesha_manage_export(). +And it never turn back to "on" when volume is started. It is not desire +to modify the volume options during stop, this patch fixes above mentioned +issue. + +Change-Id: Iea9c62e5cda4f54805b41ea6055cf0c3652a634c +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/17111 +Smoke: Gluster Build System +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: Kaleb KEITHLEY +Reviewed-by: Raghavendra Talur +--- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 30 ++++++++++++++----------- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 4 ++-- + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 +- + xlators/mgmt/glusterd/src/glusterd.h | 3 ++- + 4 files changed, 22 insertions(+), 17 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index 2392341..5d6144a 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -463,7 +463,8 @@ manage_export_config (char *volname, char *value, char **op_errstr) + + /* Exports and unexports a particular volume via NFS-Ganesha */ + int +-ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) ++ganesha_manage_export (dict_t *dict, char *value, ++ gf_boolean_t update_cache_invalidation, char **op_errstr) + { + runner_t runner = {0,}; + int ret = -1; +@@ -573,17 +574,20 @@ ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) + } + } + +- vol_opts = volinfo->dict; +- ret = dict_set_dynstr_with_alloc (vol_opts, +- "features.cache-invalidation", value); +- if (ret) +- gf_asprintf (op_errstr, "Cache-invalidation could not" +- " be set to %s.", value); +- ret = glusterd_store_volinfo (volinfo, +- GLUSTERD_VOLINFO_VER_AC_INCREMENT); +- if (ret) +- gf_asprintf (op_errstr, "failed to store volinfo for %s" +- , volinfo->volname); ++ if (update_cache_invalidation) { ++ vol_opts = volinfo->dict; ++ ret = dict_set_dynstr_with_alloc (vol_opts, ++ "features.cache-invalidation", ++ value); ++ if (ret) ++ gf_asprintf (op_errstr, "Cache-invalidation could not" ++ " be set to %s.", value); ++ ret = glusterd_store_volinfo (volinfo, ++ GLUSTERD_VOLINFO_VER_AC_INCREMENT); ++ if (ret) ++ gf_asprintf (op_errstr, "failed to store volinfo for %s" ++ , volinfo->volname); ++ } + + out: + return ret; +@@ -858,7 +862,7 @@ glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, + + + if (strcmp (key, "ganesha.enable") == 0) { +- ret = ganesha_manage_export (dict, value, op_errstr); ++ ret = ganesha_manage_export (dict, value, _gf_true, op_errstr); + if (ret < 0) + goto out; + } +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 06e9e25..86f18f0 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -1128,7 +1128,7 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) + + if ((strcmp (key, "ganesha.enable") == 0) && + (strcmp (value, "off") == 0)) { +- ret = ganesha_manage_export (dict, "off", op_errstr); ++ ret = ganesha_manage_export (dict, "off", _gf_true, op_errstr); + if (ret) + goto out; + } +@@ -1655,7 +1655,7 @@ glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr) + */ + if (volinfo && (!strcmp (key, "all") || !strcmp(key, "ganesha.enable"))) { + if (glusterd_check_ganesha_export (volinfo)) { +- ret = ganesha_manage_export (dict, "off", op_errstr); ++ ret = ganesha_manage_export (dict, "off", _gf_true, op_errstr); + if (ret) + gf_msg (this->name, GF_LOG_WARNING, 0, + GD_MSG_NFS_GNS_RESET_FAIL, +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +index 92db458..725d194 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +@@ -1739,7 +1739,7 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) + } + ret = glusterd_check_ganesha_export (volinfo); + if (ret) { +- ret = ganesha_manage_export(dict, "off", op_errstr); ++ ret = ganesha_manage_export(dict, "off", _gf_false, op_errstr); + if (ret) { + gf_msg (THIS->name, GF_LOG_WARNING, 0, + GD_MSG_NFS_GNS_UNEXPRT_VOL_FAIL, "Could not " +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index 2d8dbb9..3ad5ed6 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -1176,7 +1176,8 @@ int glusterd_check_ganesha_cmd (char *key, char *value, + char **errstr, dict_t *dict); + int glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr); + int glusterd_op_set_ganesha (dict_t *dict, char **errstr); +-int ganesha_manage_export (dict_t *dict, char *value, char **op_errstr); ++int ganesha_manage_export (dict_t *dict, char *value, ++ gf_boolean_t update_cache_invalidation, char **op_errstr); + int manage_export_config (char *volname, char *value, char **op_errstr); + + gf_boolean_t +-- +1.8.3.1 + diff --git a/SOURCES/0060-ganesha-scripts-Modifying-ganesha-ha.sh-for-share-st.patch b/SOURCES/0060-ganesha-scripts-Modifying-ganesha-ha.sh-for-share-st.patch deleted file mode 100644 index 460f042..0000000 --- a/SOURCES/0060-ganesha-scripts-Modifying-ganesha-ha.sh-for-share-st.patch +++ /dev/null @@ -1,191 +0,0 @@ -From b45d1de28c5bc3806af09e2753c5f3396ca9e199 Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Wed, 13 Jul 2016 12:09:43 +0530 -Subject: [PATCH 60/86] ganesha/scripts : Modifying ganesha-ha.sh for share storage related changes - -Currently the ganesha related configurations are "scp"ied for operations like -add, delete, refresh-config in ganesha-ha.sh. This is no more required since -all the conf files are available in shared storage and every node can directly -access them from shared storage. - -More details can be found at http://review.gluster.org/#/c/15105/ - -Upstream reference: ->Change-Id: Ic025eb4dc246db61d6fbe969ca60214751fbf3ba ->BUG: 1355956 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/14909 ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: soumya k ->Smoke: Gluster Build System ->Reviewed-by: Kaleb KEITHLEY ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: Ic025eb4dc246db61d6fbe969ca60214751fbf3ba -BUG: 1348962 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84779 -Reviewed-by: Atin Mukherjee ---- - extras/ganesha/scripts/ganesha-ha.sh | 76 +++++---------------------------- - 1 files changed, 12 insertions(+), 64 deletions(-) - -diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh -index ada21cb..de7c425 100644 ---- a/extras/ganesha/scripts/ganesha-ha.sh -+++ b/extras/ganesha/scripts/ganesha-ha.sh -@@ -106,6 +106,16 @@ manage_service () - { - local action=${1} - local new_node=${2} -+ local option= -+ -+ if [ "$action" == "start" ]; then -+ option="yes" -+ else -+ option="no" -+ fi -+ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ -+${SECRET_PEM} root@${new_node} "/usr/libexec/ganesha/ganesha-ha.sh --setup-ganesha-conf-files $HA_CONFDIR $option" -+ - if [ "$SERVICE_MAN" == "/usr/bin/systemctl" ] - then - ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ -@@ -224,48 +234,20 @@ setup_finalize_ha() - } - - --setup_copy_config() --{ -- local short_host=$(hostname -s) -- local tganesha_conf=$(mktemp -u) -- -- if [ -e ${SECRET_PEM} ]; then -- while [[ ${1} ]]; do -- current_host=`echo ${1} | cut -d "." -f 1` -- if [ ${short_host} != ${current_host} ]; then -- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${HA_CONFDIR}/ganesha-ha.conf ${1}:${HA_CONFDIR}/ -- if [ $? -ne 0 ]; then -- logger "warning: scp ganesha-ha.conf to ${1} failed" -- fi -- fi -- shift -- done -- else -- logger "warning: scp ganesha-ha.conf to ${1} failed" -- fi --} -- - refresh_config () - { - local short_host=$(hostname -s) - local VOL=${1} - local HA_CONFDIR=${2} -- local tganesha_vol_conf=$(mktemp) - local short_host=$(hostname -s) - -- cp ${HA_CONFDIR}/exports/export.$VOL.conf \ --${tganesha_vol_conf} -+ removed_id=`cat $HA_CONFDIR/exports/export.$VOL.conf |\ -+grep Export_Id | awk -F"[=,;]" '{print$2}' | tr -d '[[:space:]]'` - - if [ -e ${SECRET_PEM} ]; then - while [[ ${3} ]]; do - current_host=`echo ${3} | cut -d "." -f 1` - if [ ${short_host} != ${current_host} ]; then -- removed_id=$(ssh -oPasswordAuthentication=no \ ---oStrictHostKeyChecking=no -i ${SECRET_PEM} root@${current_host} \ --"cat $HA_CONFDIR/exports/export.$VOL.conf |\ --grep Export_Id | awk -F\"[=,;]\" '{print \$2}' | tr -d '[[:space:]]'") -- - output=$(ssh -oPasswordAuthentication=no \ - -oStrictHostKeyChecking=no -i ${SECRET_PEM} root@${current_host} \ - "dbus-send --print-reply --system --dest=org.ganesha.nfsd \ -@@ -278,14 +260,6 @@ uint16:$removed_id 2>&1") - exit 1 - fi - sleep 1 -- sed -i s/Export_Id.*/"Export_Id= $removed_id ;"/ \ -- ${tganesha_vol_conf} -- -- scp -q -oPasswordAuthentication=no \ ---oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${tganesha_vol_conf} \ --${current_host}:${HA_CONFDIR}/exports/export.$VOL.conf -- - output=$(ssh -oPasswordAuthentication=no \ - -oStrictHostKeyChecking=no -i ${SECRET_PEM} root@${current_host} \ - "dbus-send --print-reply --system --dest=org.ganesha.nfsd \ -@@ -310,8 +284,6 @@ string:\"EXPORT(Path=/$VOL)\" 2>&1") - fi - - # Run the same command on the localhost, -- removed_id=`cat $HA_CONFDIR/exports/export.$VOL.conf |\ --grep Export_Id | awk -F"[=,;]" '{print$2}' | tr -d '[[:space:]]'` - output=$(dbus-send --print-reply --system --dest=org.ganesha.nfsd \ - /org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.RemoveExport \ - uint16:$removed_id 2>&1) -@@ -334,22 +306,6 @@ string:"EXPORT(Path=/$VOL)" 2>&1) - else - echo "Success: refresh-config completed." - fi -- rm -f ${tganesha_vol_conf} -- --} -- --copy_export_config () --{ -- local new_node=${1} -- -- # The add node should be executed from one of the nodes in ganesha -- # cluster. So all the configuration file will be available in that -- # node itself. So just copy that to new node -- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${GANESHA_CONF} ${new_node}:${GANESHA_CONF} -- -- scp -r -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ --${SECRET_PEM} ${HA_CONFDIR}/exports/ ${new_node}:${HA_CONFDIR}/ - } - - -@@ -870,8 +826,6 @@ main() - - setup_state_volume ${HA_SERVERS} - -- setup_copy_config ${HA_SERVERS} -- - else - - logger "insufficient servers for HA, aborting" -@@ -898,8 +852,6 @@ main() - - logger "adding ${node} with ${vip} to ${HA_NAME}" - -- copy_export_config ${node} ${HA_CONFDIR} -- - determine_service_manager - - manage_service "start" ${node} -@@ -925,8 +877,6 @@ main() - sed -i s/HA_CLUSTER_NODES.*/"HA_CLUSTER_NODES=\"$NEW_NODES\""/ \ - $HA_CONFDIR/ganesha-ha.conf - HA_SERVERS="${HA_SERVERS} ${node}" -- -- setup_copy_config ${HA_SERVERS} - ;; - - delete | --delete) -@@ -945,8 +895,6 @@ $HA_CONFDIR/ganesha-ha.conf - - deletenode_update_haconfig ${node} - -- setup_copy_config ${HA_SERVERS} -- - rm -rf ${HA_VOL_MNT}/nfs-ganesha/${node} - - determine_service_manager --- -1.7.1 - diff --git a/SOURCES/0060-glusterd-ganesha-return-proper-value-in-pre_setup.patch b/SOURCES/0060-glusterd-ganesha-return-proper-value-in-pre_setup.patch new file mode 100644 index 0000000..50f8012 --- /dev/null +++ b/SOURCES/0060-glusterd-ganesha-return-proper-value-in-pre_setup.patch @@ -0,0 +1,44 @@ +From 0ae0579f3c92ecf6270eea308905518ce75efb7b Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Wed, 22 Feb 2017 18:26:30 +0530 +Subject: [PATCH 60/74] glusterd/ganesha : return proper value in pre_setup() + +Change-Id: I6f7ce82488904c7d418ee078162f26f1ec81e9d9 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/16733 +Smoke: Gluster Build System +Reviewed-by: Atin Mukherjee +Reviewed-by: Raghavendra Talur +Tested-by: Raghavendra Talur +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +--- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index 5d6144a..cd591df 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -834,15 +834,14 @@ pre_setup (gf_boolean_t run_setup, char **op_errstr) + { + int ret = 0; + +- ret = check_host_list(); +- +- if (ret) { ++ if (check_host_list()) { + ret = setup_cluster(run_setup); + if (ret == -1) + gf_asprintf (op_errstr, "Failed to set up HA " + "config for NFS-Ganesha. " + "Please check the log file for details"); +- } ++ } else ++ ret = -1; + + return ret; + } +-- +1.8.3.1 + diff --git a/SOURCES/0061-ganesha-scripts-remove-dependency-over-export-config.patch b/SOURCES/0061-ganesha-scripts-remove-dependency-over-export-config.patch new file mode 100644 index 0000000..e1b2e22 --- /dev/null +++ b/SOURCES/0061-ganesha-scripts-remove-dependency-over-export-config.patch @@ -0,0 +1,51 @@ +From e3dd661b5c8fce818a8e8b601d30bf1af8c3466e Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Thu, 23 Feb 2017 16:21:52 +0530 +Subject: [PATCH 61/74] ganesha/scripts : remove dependency over export + configuration file for unexport + +Currently unexport is performed by reading export id from volume configuration +file. So unexport has dependency over that file. This patch will unexport with +help of dbus command ShowExport. And it will only unexport the share which is +added via cli. + +Change-Id: I6f3c9b2bb48f0328b18e9cc0e4b9356174afd596 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/16771 +Smoke: Gluster Build System +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: Kaleb KEITHLEY +Reviewed-by: Raghavendra Talur +--- + extras/ganesha/scripts/dbus-send.sh | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/extras/ganesha/scripts/dbus-send.sh b/extras/ganesha/scripts/dbus-send.sh +index c071d03..a602cd4 100755 +--- a/extras/ganesha/scripts/dbus-send.sh ++++ b/extras/ganesha/scripts/dbus-send.sh +@@ -41,8 +41,18 @@ string:"EXPORT(Path=/$VOL)" + #This function removes an export dynamically(uses the export_id of the export) + function dynamic_export_remove() + { +- removed_id=`cat $GANESHA_DIR/exports/export.$VOL.conf |\ +-grep Export_Id | awk -F"[=,;]" '{print$2}'| tr -d '[[:space:]]'` ++ # Below bash fetch all the export from ShowExport command and search ++ # export entry based on path and then get its export entry. ++ # There are two possiblities for path, either entire volume will be ++ # exported or subdir. It handles both cases. But it remove only first ++ # entry from the list based on assumption that entry exported via cli ++ # has lowest export id value ++ removed_id=$(dbus-send --type=method_call --print-reply --system \ ++ --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ ++ org.ganesha.nfsd.exportmgr.ShowExports | grep -B 1 -we \ ++ "/"$VOL -e "/"$VOL"/" | grep uint16 | awk '{print $2}' \ ++ | head -1) ++ + dbus-send --print-reply --system \ + --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ + org.ganesha.nfsd.exportmgr.RemoveExport uint16:$removed_id +-- +1.8.3.1 + diff --git a/SOURCES/0061-glusterd-ganesha-create-export-configuration-file-in.patch b/SOURCES/0061-glusterd-ganesha-create-export-configuration-file-in.patch deleted file mode 100644 index 2fde145..0000000 --- a/SOURCES/0061-glusterd-ganesha-create-export-configuration-file-in.patch +++ /dev/null @@ -1,376 +0,0 @@ -From 74a0dd4ffd4bae7e5b304edf2b1b3991b15df65b Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Wed, 13 Jul 2016 11:38:10 +0530 -Subject: [PATCH 61/86] glusterd/ganesha : create export configuration file in shared storage - -This is the second patch which moves export related configuration for -a volume into shared storage. The main change includes in scripts -create-export-ganesha.sh, dbus-send.sh and the handling of volume set -command "ganesha.enable". The manipulation of EXPORT_ID move from -dbus-send.sh to create-export-ganesha.sh. - -In volume set handling following has performed - - stage | commit ----------------------------------------------------------- -1.) gluster v set ganesha.enable on - - None | create export file - | in node where cli executed, - | thne export volume via dbus - -2.) gluster v set ganesha.enable off - -unexport volume via dbus | remove export file from the - | shared storage ------------------------------------------------------------ - -More details can be found at http://review.gluster.org/#/c/15105/ - -Upstream reference : ->Change-Id: Ia8b0e89bc8fff24b0bc5d20a538a89212894a8e4 ->BUG: 1355956 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/14908 ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: soumya k ->Smoke: Gluster Build System ->Reviewed-by: Kaleb KEITHLEY ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: Ia8b0e89bc8fff24b0bc5d20a538a89212894a8e4 -BUG: 1344675 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84780 -Reviewed-by: Atin Mukherjee ---- - extras/ganesha/scripts/create-export-ganesha.sh | 54 ++++++++++----------- - extras/ganesha/scripts/dbus-send.sh | 59 +--------------------- - xlators/mgmt/glusterd/src/glusterd-ganesha.c | 55 ++++++++++++++------- - xlators/mgmt/glusterd/src/glusterd-op-sm.c | 6 ++ - xlators/mgmt/glusterd/src/glusterd.h | 1 + - 5 files changed, 72 insertions(+), 103 deletions(-) - -diff --git a/extras/ganesha/scripts/create-export-ganesha.sh b/extras/ganesha/scripts/create-export-ganesha.sh -index a1a35db..1ffba42 100755 ---- a/extras/ganesha/scripts/create-export-ganesha.sh -+++ b/extras/ganesha/scripts/create-export-ganesha.sh -@@ -21,14 +21,17 @@ if [ -f /etc/default/ganesha ] - fi - - GANESHA_DIR=${1%/} --VOL=$2 --CONF= -+OPTION=$2 -+VOL=$3 -+CONF=$GANESHA_DIR"/ganesha.conf" -+declare -i EXPORT_ID - - function check_cmd_status() - { - if [ "$1" != "0" ] - then - rm -rf $GANESHA_DIR/exports/export.$VOL.conf -+ sed -i /$VOL.conf/d $CONF - exit 1 - fi - } -@@ -40,28 +43,6 @@ if [ ! -d "$GANESHA_DIR/exports" ]; - check_cmd_status `echo $?` - fi - --function find_rhel7_conf --{ -- while [[ $# > 0 ]] -- do -- key="$1" -- case $key in -- -f) -- CONFFILE="$2" -- ;; -- *) -- ;; -- esac -- shift -- done --} -- --if [ -z $CONFFILE ]; then -- find_rhel7_conf $OPTIONS -- --fi --CONF=${CONFFILE:-/etc/ganesha/ganesha.conf} -- - function write_conf() - { - echo -e "# WARNING : Using Gluster CLI will overwrite manual -@@ -85,9 +66,26 @@ echo ' Transports = "UDP","TCP";' - echo ' SecType = "sys";' - echo " }" - } -- --write_conf $@ > $GANESHA_DIR/exports/export.$VOL.conf --if ! (cat $CONF | grep $VOL.conf\"$ ) -+if [ "$OPTION" = "on" ]; - then --echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF -+ if ! (cat $CONF | grep $VOL.conf\"$ ) -+ then -+ write_conf $@ > $GANESHA_DIR/exports/export.$VOL.conf -+ echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF -+ count=`ls -l $GANESHA_DIR/exports/*.conf | wc -l` -+ if [ "$count" = "1" ] ; then -+ EXPORT_ID=2 -+ else -+ EXPORT_ID=`cat $GANESHA_DIR/.export_added` -+ check_cmd_status `echo $?` -+ EXPORT_ID=EXPORT_ID+1 -+ sed -i s/Export_Id.*/"Export_Id= $EXPORT_ID ;"/ \ -+ $GANESHA_DIR/exports/export.$VOL.conf -+ check_cmd_status `echo $?` -+ fi -+ echo $EXPORT_ID > $GANESHA_DIR/.export_added -+ fi -+else -+ rm -rf $GANESHA_DIR/exports/export.$VOL.conf -+ sed -i /$VOL.conf/d $CONF - fi -diff --git a/extras/ganesha/scripts/dbus-send.sh b/extras/ganesha/scripts/dbus-send.sh -index 14af095..c071d03 100755 ---- a/extras/ganesha/scripts/dbus-send.sh -+++ b/extras/ganesha/scripts/dbus-send.sh -@@ -15,71 +15,22 @@ if [ -f /etc/default/ganesha ] - . /etc/default/ganesha - fi - --declare -i EXPORT_ID - GANESHA_DIR=${1%/} - OPTION=$2 - VOL=$3 --CONF= -- --function find_rhel7_conf --{ -- while [[ $# > 0 ]] -- do -- key="$1" -- case $key in -- -f) -- CONFFILE="$2" -- break; -- ;; -- *) -- ;; -- esac -- shift -- done --} -- --if [ -z $CONFFILE ] -- then -- find_rhel7_conf $OPTIONS -- --fi -- --CONF=${CONFFILE:-/etc/ganesha/ganesha.conf} -+CONF=$GANESHA_DIR"/ganesha.conf" - - function check_cmd_status() - { - if [ "$1" != "0" ] -- then -- rm -rf $GANESHA_DIR/exports/export.$VOL.conf -- sed -i /$VOL.conf/d $CONF -- exit 1 -+ then -+ logger "dynamic export failed on node :${hostname -s}" - fi - } - - #This function keeps track of export IDs and increments it with every new entry - function dynamic_export_add() - { -- count=`ls -l $GANESHA_DIR/exports/*.conf | wc -l` -- if [ "$count" = "1" ] ; -- then -- EXPORT_ID=2 -- else -- #if [ -s /var/lib/ganesha/export_removed ]; -- # then -- # EXPORT_ID=`head -1 /var/lib/ganesha/export_removed` -- # sed -i -e "1d" /var/lib/ganesha/export_removed -- # else -- -- EXPORT_ID=`cat $GANESHA_DIR/.export_added` -- check_cmd_status `echo $?` -- EXPORT_ID=EXPORT_ID+1 -- #fi -- fi -- echo $EXPORT_ID > $GANESHA_DIR/.export_added -- check_cmd_status `echo $?` -- sed -i s/Export_Id.*/"Export_Id= $EXPORT_ID ;"/ \ --$GANESHA_DIR/exports/export.$VOL.conf -- check_cmd_status `echo $?` - dbus-send --system \ - --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ - org.ganesha.nfsd.exportmgr.AddExport string:$GANESHA_DIR/exports/export.$VOL.conf \ -@@ -92,14 +43,10 @@ function dynamic_export_remove() - { - removed_id=`cat $GANESHA_DIR/exports/export.$VOL.conf |\ - grep Export_Id | awk -F"[=,;]" '{print$2}'| tr -d '[[:space:]]'` -- check_cmd_status `echo $?` - dbus-send --print-reply --system \ - --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ - org.ganesha.nfsd.exportmgr.RemoveExport uint16:$removed_id - check_cmd_status `echo $?` -- sed -i /$VOL.conf/d $CONF -- rm -rf $GANESHA_DIR/exports/export.$VOL.conf -- - } - - if [ "$OPTION" = "on" ]; -diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -index 38fc1f6..670c21f 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c -+++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c -@@ -180,17 +180,22 @@ glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo) { - return is_exported; - } - -- -+/* * -+ * The below function is called as part of commit phase for volume set option -+ * "ganesha.enable". If the value is "on", it creates export configuration file -+ * and then export the volume via dbus command. Incase of "off", the volume -+ * will be already unexported during stage phase, so it will remove the conf -+ * file from shared storage -+ */ - int - glusterd_check_ganesha_cmd (char *key, char *value, char **errstr, dict_t *dict) - { - int ret = 0; -- xlator_t *this = NULL; -+ char *volname = NULL; - -- this = THIS; -- GF_ASSERT (this); - GF_ASSERT (key); - GF_ASSERT (value); -+ GF_ASSERT (dict); - - if ((strcmp (key, "ganesha.enable") == 0)) { - if ((strcmp (value, "on")) && (strcmp (value, "off"))) { -@@ -199,15 +204,28 @@ glusterd_check_ganesha_cmd (char *key, char *value, char **errstr, dict_t *dict) - ret = -1; - goto out; - } -- ret = glusterd_handle_ganesha_op (dict, errstr, key, value); -- if (ret) { -- gf_msg (this->name, GF_LOG_ERROR, 0, -- GD_MSG_NFS_GNS_OP_HANDLE_FAIL, -- "Handling NFS-Ganesha" -- " op failed."); -- } -+ if (strcmp (value, "on") == 0) { -+ ret = glusterd_handle_ganesha_op (dict, errstr, key, -+ value); -+ -+ } else if (is_origin_glusterd (dict)) { -+ ret = dict_get_str (dict, "volname", &volname); -+ if (ret) { -+ gf_msg ("glusterd-ganesha", GF_LOG_ERROR, errno, -+ GD_MSG_DICT_GET_FAILED, -+ "Unable to get volume name"); -+ goto out; -+ } -+ ret = create_export_config (volname, "off", errstr); -+ } - } - out: -+ if (ret) { -+ gf_msg ("glusterd-ganesha", GF_LOG_ERROR, 0, -+ GD_MSG_NFS_GNS_OP_HANDLE_FAIL, -+ "Handling NFS-Ganesha" -+ " op failed."); -+ } - return ret; - } - -@@ -415,7 +433,7 @@ check_host_list (void) - } - - int --create_export_config (char *volname, char **op_errstr) -+create_export_config (char *volname, char *value, char **op_errstr) - { - runner_t runner = {0,}; - int ret = -1; -@@ -424,7 +442,7 @@ create_export_config (char *volname, char **op_errstr) - runinit (&runner); - runner_add_args (&runner, "sh", - GANESHA_PREFIX"/create-export-ganesha.sh", -- CONFDIR, volname, NULL); -+ CONFDIR, value, volname, NULL); - ret = runner_run(&runner); - - if (ret) -@@ -513,9 +531,12 @@ ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) - goto out; - } - -- /* Create the export file only when ganesha.enable "on" is executed */ -+ /* * -+ * Create the export file from the node where ganesha.enable "on" -+ * is executed -+ * */ - if (option) { -- ret = create_export_config (volname, op_errstr); -+ ret = create_export_config (volname, "on", op_errstr); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_EXPORT_FILE_CREATE_FAIL, -@@ -810,11 +831,7 @@ glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, - { - - int32_t ret = -1; -- char *volname = NULL; -- xlator_t *this = NULL; - gf_boolean_t option = _gf_false; -- static int export_id = 1; -- glusterd_volinfo_t *volinfo = NULL; - - GF_ASSERT (dict); - GF_ASSERT (op_errstr); -diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -index a228ba6..75b809d 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c -+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c -@@ -1060,6 +1060,12 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) - if (ret) - goto out; - -+ if ((strcmp (key, "ganesha.enable") == 0) && -+ (strcmp (value, "off") == 0)) { -+ ret = ganesha_manage_export (dict, "off", op_errstr); -+ if (ret) -+ goto out; -+ } - ret = glusterd_check_quota_cmd (key, value, errstr, sizeof (errstr)); - if (ret) - goto out; -diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h -index 84b38e5..d981fa5 100644 ---- a/xlators/mgmt/glusterd/src/glusterd.h -+++ b/xlators/mgmt/glusterd/src/glusterd.h -@@ -1073,6 +1073,7 @@ int glusterd_check_ganesha_cmd (char *key, char *value, - int glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr); - int glusterd_op_set_ganesha (dict_t *dict, char **errstr); - int ganesha_manage_export (dict_t *dict, char *value, char **op_errstr); -+int create_export_config (char *volname, char *value, char **op_errstr); - gf_boolean_t glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo); - int stop_ganesha (char **op_errstr); - int tear_down_cluster (gf_boolean_t run_teardown); --- -1.7.1 - diff --git a/SOURCES/0062-event-fix-gf_event-messages-for-replace-reset-brick-.patch b/SOURCES/0062-event-fix-gf_event-messages-for-replace-reset-brick-.patch deleted file mode 100644 index 3e5202d..0000000 --- a/SOURCES/0062-event-fix-gf_event-messages-for-replace-reset-brick-.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 4923703a45ea10bbad8a84c7fd02fe3f9fa8db37 Mon Sep 17 00:00:00 2001 -From: Anuradha Talur -Date: Wed, 31 Aug 2016 15:27:31 +0530 -Subject: [PATCH 62/86] event: fix gf_event messages for replace/reset brick op - ->Change-Id: I80ebeeaffd2b228d7d0796c8d08bc2a051c4ccac ->BUG: 1266876 ->Signed-off-by: Anuradha Talur ->Reviewed-on: http://review.gluster.org/15370 ->Smoke: Gluster Build System ->Reviewed-by: Atin Mukherjee ->CentOS-regression: Gluster Build System ->NetBSD-regression: NetBSD Build System ->Reviewed-by: Pranith Kumar Karampuri - -Change-Id: I80ebeeaffd2b228d7d0796c8d08bc2a051c4ccac -BUG: 1256524 -Signed-off-by: Ashish Pandey -Reviewed-on: https://code.engineering.redhat.com/gerrit/84810 -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 28 ++++++++++++------- - events/eventskeygen.py | 3 +- - xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 5 --- - 3 files changed, 20 insertions(+), 16 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 4b2653b..647505e 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -1844,10 +1844,10 @@ cli_cmd_volume_reset_brick_cbk (struct cli_state *state, - int ret = -1; - rpc_clnt_procedure_t *proc = NULL; - call_frame_t *frame = NULL; -- dict_t *options = NULL; -- int sent = 0; -- int parse_error = 0; -- cli_local_t *local = NULL; -+ dict_t *options = NULL; -+ int sent = 0; -+ int parse_error = 0; -+ cli_local_t *local = NULL; - - #ifdef GF_SOLARIS_HOST_OS - cli_out ("Command not supported on Solaris"); -@@ -1875,14 +1875,22 @@ cli_cmd_volume_reset_brick_cbk (struct cli_state *state, - - out: - if (ret) { -- gf_event (EVENT_BRICK_RESET, "Volume reset-brick failed."); - cli_cmd_sent_status_get (&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out ("Volume reset-brick failed"); - } else { -- gf_event (EVENT_BRICK_RESET, "Volume reset-brick succeeded."); -+ if (wordcount > 5) { -+ gf_event (EVENT_BRICK_RESET_COMMIT, -+ "Volume=%s;source-brick=%s;" -+ "destination-brick=%s", -+ (char *)words[2], (char *)words[3], -+ (char *)words[4]); -+ } else { -+ gf_event (EVENT_BRICK_RESET_START, -+ "Volume=%s;source-brick=%s", -+ (char *)words[2], (char *)words[3]); -+ } - } -- - CLI_STACK_DESTROY (frame); - - return ret; -@@ -1928,14 +1936,14 @@ cli_cmd_volume_replace_brick_cbk (struct cli_state *state, - - out: - if (ret) { -- gf_event (EVENT_BRICK_REPLACE, "Volume replace-brick failed."); - cli_cmd_sent_status_get (&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out ("Volume replace-brick failed"); - } else { -- gf_event (EVENT_BRICK_RESET, "Volume replace-brick succeeded."); -+ gf_event (EVENT_BRICK_REPLACE, -+ "Volume=%s;source-brick=%s;destination-brick=%s", -+ (char *)words[2], (char *)words[3], (char *)words[4]); - } -- - CLI_STACK_DESTROY (frame); - - return ret; -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 2869e45..801bee3 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -31,7 +31,8 @@ keys = ( - "EVENT_VOLUME_DELETE", - "EVENT_VOLUME_SET", - "EVENT_VOLUME_RESET", -- "EVENT_BRICK_RESET", -+ "EVENT_BRICK_RESET_START", -+ "EVENT_BRICK_RESET_COMMIT", - "EVENT_BRICK_REPLACE", - - #geo-rep events -diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -index 7338843..aaa5a35 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -+++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c -@@ -146,11 +146,6 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req) - "Received %s request.", - gd_rb_op_to_str (cli_op)); - -- gf_event ((op == GD_OP_REPLACE_BRICK) ? EVENT_BRICK_REPLACE : -- EVENT_BRICK_RESET, "received %s request. Source bricks %s," -- "destination brick %s.", gd_rb_op_to_str (cli_op), -- src_brick, (dst_brick) ? dst_brick : ""); -- - ret = glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (req, - op, dict); - --- -1.7.1 - diff --git a/SOURCES/0062-glusterd-ganesha-add-proper-NULL-check-in-manage_exp.patch b/SOURCES/0062-glusterd-ganesha-add-proper-NULL-check-in-manage_exp.patch new file mode 100644 index 0000000..2d769b5 --- /dev/null +++ b/SOURCES/0062-glusterd-ganesha-add-proper-NULL-check-in-manage_exp.patch @@ -0,0 +1,34 @@ +From 05c63817ac715fdcf9065568d796b93d97c0be7f Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Tue, 2 May 2017 14:06:00 +0530 +Subject: [PATCH 62/74] glusterd/ganesha : add proper NULL check in + manage_export_config + +Change-Id: I872b2b6b027f04e61f60ad85588f50e1ef2f988c +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/17150 +Smoke: Gluster Build System +Reviewed-by: soumya k +NetBSD-regression: NetBSD Build System +Reviewed-by: Kaleb KEITHLEY +CentOS-regression: Gluster Build System +--- + xlators/mgmt/glusterd/src/glusterd-ganesha.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +index cd591df..7ba25ee 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c ++++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c +@@ -454,7 +454,7 @@ manage_export_config (char *volname, char *value, char **op_errstr) + CONFDIR, value, volname, NULL); + ret = runner_run(&runner); + +- if (ret && !(*op_errstr)) ++ if (ret && op_errstr) + gf_asprintf (op_errstr, "Failed to create" + " NFS-Ganesha export config file."); + +-- +1.8.3.1 + diff --git a/SOURCES/0063-cluster-ec-Add-events-for-EC-translator.patch b/SOURCES/0063-cluster-ec-Add-events-for-EC-translator.patch deleted file mode 100644 index 27ab298..0000000 --- a/SOURCES/0063-cluster-ec-Add-events-for-EC-translator.patch +++ /dev/null @@ -1,95 +0,0 @@ -From e27365c0ab577aefc7e0b45dacb47f28510b8036 Mon Sep 17 00:00:00 2001 -From: Ashish Pandey -Date: Tue, 30 Aug 2016 14:17:58 +0530 -Subject: [PATCH 63/86] cluster/ec: Add events for EC translator - -This patch will generates events in following -cases which will be consumed by new event -framework. - -Consider an EC volume with (K+M) configuration -K = Data bricks -M = Redundancy bricks - -1- EVENT_EC_MIN_BRICKS_NOT_UP - - When minimum "K" number of bricks, required - for any ec fop, are not up. -2- EVENT_EC_MIN_BRICKS_UP - When minimum "K" number of bricks, required - for any ec fop, are up. - ->Change-Id: I0414b8968c39740a171e5aa14b087afd524d574f ->BUG: 1371470 ->Signed-off-by: Ashish Pandey ->Reviewed-on: http://review.gluster.org/15348 ->Tested-by: Pranith Kumar Karampuri ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Smoke: Gluster Build System ->Reviewed-by: Pranith Kumar Karampuri - -Change-Id: I0414b8968c39740a171e5aa14b087afd524d574f -BUG: 1361084 -Signed-off-by: Ashish Pandey -Reviewed-on: https://code.engineering.redhat.com/gerrit/84812 -Reviewed-by: Atin Mukherjee ---- - events/eventskeygen.py | 4 ++-- - xlators/cluster/ec/src/ec.c | 5 ++++- - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 801bee3..9906a26 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -124,8 +124,8 @@ keys = ( - "EVENT_COMPARE_FRIEND_VOLUME_FAILED", - "EVENT_NFS_GANESHA_EXPORT_FAILED", - #ec events -- "EVENT_EC_DATA_BRICKS_NOT_UP", -- "EVENT_EC_DATA_BRICKS_UP", -+ "EVENT_EC_MIN_BRICKS_NOT_UP", -+ "EVENT_EC_MIN_BRICKS_UP", - #georep async events - "EVENT_GEOREP_FAULTY", - #quota async events -diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c -index 94d1241..591ab25 100644 ---- a/xlators/cluster/ec/src/ec.c -+++ b/xlators/cluster/ec/src/ec.c -@@ -20,6 +20,7 @@ - #include "ec.h" - #include "ec-messages.h" - #include "ec-heald.h" -+#include "events.h" - - static char *ec_read_policies[EC_READ_POLICY_MAX + 1] = { - [EC_ROUND_ROBIN] = "round-robin", -@@ -313,6 +314,7 @@ ec_up (xlator_t *this, ec_t *ec) - ec->up = 1; - gf_msg (this->name, GF_LOG_INFO, 0, - EC_MSG_EC_UP, "Going UP"); -+ gf_event (EVENT_EC_MIN_BRICKS_UP, "subvol=%s", this->name); - } - - void -@@ -326,6 +328,7 @@ ec_down (xlator_t *this, ec_t *ec) - ec->up = 0; - gf_msg (this->name, GF_LOG_INFO, 0, - EC_MSG_EC_DOWN, "Going DOWN"); -+ gf_event (EVENT_EC_MIN_BRICKS_NOT_UP, "subvol=%s", this->name); - } - - void -@@ -433,7 +436,7 @@ void - ec_pending_fops_completed(ec_t *ec) - { - if (ec->shutdown) { -- default_notify(ec->xl, GF_EVENT_PARENT_DOWN, NULL); -+ default_notify (ec->xl, GF_EVENT_PARENT_DOWN, NULL); - } - } - --- -1.7.1 - diff --git a/SOURCES/0063-ganesha-minor-improvments-for-commit-e91cdf4-17081.patch b/SOURCES/0063-ganesha-minor-improvments-for-commit-e91cdf4-17081.patch new file mode 100644 index 0000000..1a96b75 --- /dev/null +++ b/SOURCES/0063-ganesha-minor-improvments-for-commit-e91cdf4-17081.patch @@ -0,0 +1,34 @@ +From 1212ea61f7c2e04529ec6fa40bba447fc2bd0fe8 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Wed, 3 May 2017 12:47:14 +0530 +Subject: [PATCH 63/74] ganesha : minor improvments for commit e91cdf4 (17081) + +Change-Id: I3af13e081c5e46cc6f2c132e7a5106ac3355c850 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://review.gluster.org/17152 +Smoke: Gluster Build System +Reviewed-by: soumya k +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +Reviewed-by: Kaleb KEITHLEY +Signed-off-by: Jiffin Tony Thottan +--- + extras/ganesha/scripts/ganesha-ha.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index db2fa54..0e4d23a 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -275,7 +275,7 @@ string:\"EXPORT(Export_Id=$export_id)\" 2>&1") + ret=$? + logger <<< "${output}" + if [ ${ret} -ne 0 ]; then +- echo "Refresh-config failed on ${current_host}" ++ echo "Refresh-config failed on ${current_host}. Please check logs on ${current_host}" + else + echo "Refresh-config completed on ${current_host}." + fi +-- +1.8.3.1 + diff --git a/SOURCES/0064-common-ha-surviving-ganesha.nfsd-not-put-in-grace-on.patch b/SOURCES/0064-common-ha-surviving-ganesha.nfsd-not-put-in-grace-on.patch new file mode 100644 index 0000000..ab90a1a --- /dev/null +++ b/SOURCES/0064-common-ha-surviving-ganesha.nfsd-not-put-in-grace-on.patch @@ -0,0 +1,51 @@ +From 16d3a7d636d115c44516dc415b26d2c6d0d17424 Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Tue, 13 Jun 2017 07:36:50 -0400 +Subject: [PATCH 64/74] common-ha: surviving ganesha.nfsd not put in grace on + fail-over + +Behavior change is seen in new HA in RHEL 7.4 Beta. Up to now clone +RAs have been created with "pcs resource create ... meta notify=true". +Their notify method is invoked with pre-start or post-stop when one of +the clone RAs is started or stopped. + +In 7.4 Beta the notify method we observe that the notify method is not +invoked when one of the clones is stopped (or started). + +Ken Gaillot, one of the pacemaker devs, wrote: + With the above command, pcs puts the notify=true meta-attribute + on the primitive instead of the clone. Looking at the pcs help, + that seems expected (--clone notify=true would put it on the clone, + meta notify=true puts it on the primitive). If you drop the "meta" + above, I think it will work again. + +And indeed his suggested fix does work on both RHEL 7.4 Beta and RHEL +7.3 and presumably Fedora. + +Change-Id: Idbb539f1366df6d39f77431c357dff4e53a2df6d +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://review.gluster.org/17534 +Smoke: Gluster Build System +Reviewed-by: soumya k +NetBSD-regression: NetBSD Build System +CentOS-regression: Gluster Build System +--- + extras/ganesha/scripts/ganesha-ha.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index 0e4d23a..ce5ff20 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -445,7 +445,7 @@ setup_create_resources() + # ganesha-active crm_attribute + sleep 5 + +- pcs resource create nfs-grace ocf:heartbeat:ganesha_grace --clone meta notify=true ++ pcs resource create nfs-grace ocf:heartbeat:ganesha_grace --clone notify=true + if [ $? -ne 0 ]; then + logger "warning: pcs resource create nfs-grace ocf:heartbeat:ganesha_grace --clone failed" + fi +-- +1.8.3.1 + diff --git a/SOURCES/0064-storage-posix-Integrate-important-events-with-gf_eve.patch b/SOURCES/0064-storage-posix-Integrate-important-events-with-gf_eve.patch deleted file mode 100644 index 48a55ec..0000000 --- a/SOURCES/0064-storage-posix-Integrate-important-events-with-gf_eve.patch +++ /dev/null @@ -1,291 +0,0 @@ -From c7aea7a5c2ddcc311cab8f7383d038d2caaf7d35 Mon Sep 17 00:00:00 2001 -From: Pranith Kumar K -Date: Wed, 7 Sep 2016 04:19:32 +0530 -Subject: [PATCH 64/86] storage/posix: Integrate important events with gf_event - -Patch on master: http://review.gluster.org/#/c/15342/ -Patch on release-3.9: http://review.gluster.org/#/c/15497/ - -Change-Id: Icc23b22de02e45d2b0f8c6339ee628b439a4ffa8 -BUG: 1361086 -Signed-off-by: Pranith Kumar K -Reviewed-on: https://code.engineering.redhat.com/gerrit/84803 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - events/eventskeygen.py | 4 +- - xlators/storage/posix/src/posix-helpers.c | 39 ++++++++------- - xlators/storage/posix/src/posix.c | 76 +++++++++++++++++++---------- - 3 files changed, 73 insertions(+), 46 deletions(-) - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 9906a26..02a9bdb 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -140,9 +140,9 @@ keys = ( - #posix events - "EVENT_POSIX_SAME_GFID", - "EVENT_POSIX_ALREADY_PART_OF_VOLUME", -- "EVENT_POSIX_INVALID_BRICK", -+ "EVENT_POSIX_BRICK_NOT_IN_VOLUME", - "EVENT_POSIX_BRICK_VERIFICATION_FAILED", -- "EVENT_POSIX_ACL_NOTSUP", -+ "EVENT_POSIX_ACL_NOT_SUPPORTED", - "EVENT_POSIX_HEALTH_CHECK_FAILED", - #afr events - "EVENT_AFR_QUORUM_MET", -diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c -index f93e815..f52836f 100644 ---- a/xlators/storage/posix/src/posix-helpers.c -+++ b/xlators/storage/posix/src/posix-helpers.c -@@ -31,6 +31,7 @@ - #include - #endif /* GF_BSD_HOST_OS */ - -+#include - #include "glusterfs.h" - #include "checksum.h" - #include "dict.h" -@@ -49,7 +50,7 @@ - #include "glusterfs3-xdr.h" - #include "hashfn.h" - #include "glusterfs-acl.h" --#include -+#include "events.h" - - char *marker_xattrs[] = {"trusted.glusterfs.quota.*", - "trusted.glusterfs.*.xtime", -@@ -1746,6 +1747,8 @@ posix_fs_health_check (xlator_t *this) - time_t time_sec = {0,}; - char buff[64] = {0}; - char file_path[PATH_MAX] = {0}; -+ char *op = NULL; -+ int op_errno = 0; - - GF_VALIDATE_OR_GOTO (this->name, this, out); - priv = this->private; -@@ -1761,16 +1764,14 @@ posix_fs_health_check (xlator_t *this) - - fd = open (file_path, O_CREAT|O_RDWR, 0644); - if (fd == -1) { -- gf_msg (this->name, GF_LOG_WARNING, errno, -- P_MSG_HEALTHCHECK_FAILED, -- "open() on %s returned", file_path); -+ op_errno = errno; -+ op = "open"; - goto out; - } - nofbytes = sys_write (fd, timestamp, timelen); -- if (nofbytes != timelen) { -- gf_msg (this->name, GF_LOG_WARNING, errno, -- P_MSG_HEALTHCHECK_FAILED, -- "write() on %s returned", file_path); -+ if (nofbytes < 0) { -+ op_errno = errno; -+ op = "write"; - goto out; - } - /* Seek the offset to the beginning of the file, so that the offset for -@@ -1778,9 +1779,8 @@ posix_fs_health_check (xlator_t *this) - sys_lseek(fd, 0, SEEK_SET); - nofbytes = sys_read (fd, buff, timelen); - if (nofbytes == -1) { -- gf_msg (this->name, GF_LOG_WARNING, errno, -- P_MSG_HEALTHCHECK_FAILED, -- "read() on %s returned", file_path); -+ op_errno = errno; -+ op = "read"; - goto out; - } - ret = 0; -@@ -1788,6 +1788,14 @@ out: - if (fd != -1) { - sys_close (fd); - } -+ if (ret && file_path[0]) { -+ gf_msg (this->name, GF_LOG_WARNING, errno, -+ P_MSG_HEALTHCHECK_FAILED, -+ "%s() on %s returned", op, file_path); -+ gf_event (EVENT_POSIX_HEALTH_CHECK_FAILED, -+ "op=%s;path=%s;error=%s;brick=%s:%s", op, file_path, -+ op_errno, priv->hostname, priv->base_path); -+ } - return ret; - - } -@@ -1823,14 +1831,8 @@ posix_health_check_thread_proc (void *data) - - /* Do the health-check.*/ - ret = posix_fs_health_check (this); -- -- if (ret < 0) { -- gf_msg (this->name, GF_LOG_WARNING, errno, -- P_MSG_HEALTHCHECK_FAILED, -- "health_check on %s returned", -- priv->base_path); -+ if (ret < 0) - goto abort; -- } - - pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); - } -@@ -1850,6 +1852,7 @@ abort: - /* health-check failed */ - gf_msg (this->name, GF_LOG_EMERG, 0, P_MSG_HEALTHCHECK_FAILED, - "health-check failed, going down"); -+ - xlator_notify (this->parents->xlator, GF_EVENT_CHILD_DOWN, this); - - ret = sleep (30); -diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c -index cecf5dc..2d9e3f6 100644 ---- a/xlators/storage/posix/src/posix.c -+++ b/xlators/storage/posix/src/posix.c -@@ -56,6 +56,7 @@ - #include "posix-aio.h" - #include "glusterfs-acl.h" - #include "posix-messages.h" -+#include "events.h" - - extern char *marker_xattrs[]; - #define ALIGN_SIZE 4096 -@@ -1485,6 +1486,12 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, - "and this can lead to inconsistencies.", - loc->path, uuid_utoa (uuid_req), - gfid_path ? gfid_path : ""); -+ -+ gf_event (EVENT_POSIX_SAME_GFID, "gfid=%s;path=%s;" -+ "newpath=%s;brick=%s:%s", -+ uuid_utoa (uuid_req), -+ gfid_path ? gfid_path : "", loc->path, -+ priv->hostname, priv->base_path); - } - } else if (!uuid_req && frame->root->pid != GF_SERVER_PID_TRASH) { - op_ret = -1; -@@ -6852,6 +6859,31 @@ init (xlator_t *this) - goto out; - } - -+ _private = GF_CALLOC (1, sizeof (*_private), -+ gf_posix_mt_posix_private); -+ if (!_private) { -+ ret = -1; -+ goto out; -+ } -+ -+ _private->base_path = gf_strdup (dir_data->data); -+ _private->base_path_length = strlen (_private->base_path); -+ -+ ret = dict_get_str (this->options, "hostname", &_private->hostname); -+ if (ret) { -+ _private->hostname = GF_CALLOC (256, sizeof (char), -+ gf_common_mt_char); -+ if (!_private->hostname) { -+ goto out; -+ } -+ ret = gethostname (_private->hostname, 256); -+ if (ret < 0) { -+ gf_msg (this->name, GF_LOG_WARNING, errno, -+ P_MSG_HOSTNAME_MISSING, -+ "could not find hostname "); -+ } -+ } -+ - /* Check for Extended attribute support, if not present, log it */ - op_ret = sys_lsetxattr (dir_data->data, - "trusted.glusterfs.test", "working", 8, 0); -@@ -6912,6 +6944,10 @@ init (xlator_t *this) - "mismatching volume-id (%s) received. " - "already is a part of volume %s ", - tmp_data->data, uuid_utoa (old_uuid)); -+ gf_event (EVENT_POSIX_ALREADY_PART_OF_VOLUME, -+ "volume-id=%s;brick=%s:%s", -+ uuid_utoa (old_uuid), -+ _private->hostname, _private->base_path); - ret = -1; - goto out; - } -@@ -6921,12 +6957,18 @@ init (xlator_t *this) - P_MSG_VOLUME_ID_ABSENT, - "Extended attribute trusted.glusterfs." - "volume-id is absent"); -+ gf_event (EVENT_POSIX_BRICK_NOT_IN_VOLUME, -+ "brick=%s:%s", -+ _private->hostname, _private->base_path); - ret = -1; - goto out; - - } else if ((size == -1) && (errno != ENODATA) && - (errno != ENOATTR)) { - /* Wrong 'volume-id' is set, it should be error */ -+ gf_event (EVENT_POSIX_BRICK_VERIFICATION_FAILED, -+ "brick=%s:%s", -+ _private->hostname, _private->base_path); - gf_msg (this->name, GF_LOG_WARNING, errno, - P_MSG_VOLUME_ID_FETCH_FAILED, - "%s: failed to fetch volume-id", -@@ -6935,6 +6977,9 @@ init (xlator_t *this) - goto out; - } else { - ret = -1; -+ gf_event (EVENT_POSIX_BRICK_VERIFICATION_FAILED, -+ "brick=%s:%s", -+ _private->hostname, _private->base_path); - gf_msg (this->name, GF_LOG_ERROR, 0, - P_MSG_VOLUME_ID_FETCH_FAILED, - "failed to fetch proper volume id from export"); -@@ -6985,24 +7030,18 @@ init (xlator_t *this) - } - } - -+ ret = 0; -+ - size = sys_lgetxattr (dir_data->data, POSIX_ACL_ACCESS_XATTR, - NULL, 0); -- if ((size < 0) && (errno == ENOTSUP)) -+ if ((size < 0) && (errno == ENOTSUP)) { - gf_msg (this->name, GF_LOG_WARNING, errno, - P_MSG_ACL_NOTSUP, - "Posix access control list is not supported."); -- -- ret = 0; -- _private = GF_CALLOC (1, sizeof (*_private), -- gf_posix_mt_posix_private); -- if (!_private) { -- ret = -1; -- goto out; -+ gf_event (EVENT_POSIX_ACL_NOT_SUPPORTED, -+ "brick=%s:%s", _private->hostname, _private->base_path); - } - -- _private->base_path = gf_strdup (dir_data->data); -- _private->base_path_length = strlen (_private->base_path); -- - /* - * _XOPEN_PATH_MAX is the longest file path len we MUST - * support according to POSIX standard. When prepended -@@ -7040,21 +7079,6 @@ init (xlator_t *this) - - LOCK_INIT (&_private->lock); - -- ret = dict_get_str (this->options, "hostname", &_private->hostname); -- if (ret) { -- _private->hostname = GF_CALLOC (256, sizeof (char), -- gf_common_mt_char); -- if (!_private->hostname) { -- goto out; -- } -- ret = gethostname (_private->hostname, 256); -- if (ret < 0) { -- gf_msg (this->name, GF_LOG_WARNING, errno, -- P_MSG_HOSTNAME_MISSING, -- "could not find hostname "); -- } -- } -- - _private->export_statfs = 1; - tmp_data = dict_get (this->options, "export-statfs-size"); - if (tmp_data) { --- -1.7.1 - diff --git a/SOURCES/0065-cluster-tier-add-tiering-events.patch b/SOURCES/0065-cluster-tier-add-tiering-events.patch deleted file mode 100644 index 23cf782..0000000 --- a/SOURCES/0065-cluster-tier-add-tiering-events.patch +++ /dev/null @@ -1,289 +0,0 @@ -From d0cd618dc5019be166aa914c62ace8585303f9b4 Mon Sep 17 00:00:00 2001 -From: Milind Changire -Date: Mon, 5 Sep 2016 21:51:19 +0530 -Subject: [PATCH 65/86] cluster/tier: add tiering events - -Add events for: -* tier attach and detach -* tier pause and resume -* tier rising and dropping hi and lo watermarks - -Update eventskeygen.py with tiering events. -Update cli help with: -* attach: add optional force argument -* detach: make force available as non-optional argument on its own - ->Reviewed-on: http://review.gluster.org/15232 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Dan Lambright ->Tested-by: Dan Lambright - -Change-Id: I43990d3a8742151a4a7889bafa19cb572fe661bd -BUG: 1361068 -Signed-off-by: Milind Changire -Reviewed-on: https://code.engineering.redhat.com/gerrit/84832 -Tested-by: Atin Mukherjee -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 23 ++++++++++- - events/eventskeygen.py | 13 ++++++ - xlators/cluster/dht/src/Makefile.am | 1 + - xlators/cluster/dht/src/dht-common.h | 2 + - xlators/cluster/dht/src/dht-rebalance.c | 5 ++ - xlators/cluster/dht/src/tier.c | 62 +++++++++++++++++++++++++++++++ - 6 files changed, 104 insertions(+), 2 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 647505e..4f6caab 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -1122,6 +1122,7 @@ cli_cmd_volume_tier_cbk (struct cli_state *state, - rpc_clnt_procedure_t *proc = NULL; - cli_local_t *local = NULL; - int i = 0; -+ eventtypes_t event = EVENT_LAST; - - if (wordcount < 4) { - cli_usage_out (word->pattern); -@@ -1140,6 +1141,15 @@ cli_cmd_volume_tier_cbk (struct cli_state *state, - - ret = do_cli_cmd_volume_detach_tier (state, word, - words, wordcount-1); -+ if (!strcmp (words[wordcount-2], "commit")) { -+ event = EVENT_TIER_DETACH_COMMIT; -+ } else if (!strcmp (words[wordcount-2], "start")) { -+ event = EVENT_TIER_DETACH_START; -+ } else if (!strcmp (words[wordcount-2], "stop")) { -+ event = EVENT_TIER_DETACH_STOP; -+ } else if (!strcmp (words[wordcount-2], "force")) { -+ event = EVENT_TIER_DETACH_FORCE; -+ } - goto out; - - } else if (!strcmp(words[1], "attach-tier")) { -@@ -1152,6 +1162,11 @@ cli_cmd_volume_tier_cbk (struct cli_state *state, - - ret = do_cli_cmd_volume_attach_tier (state, word, - words, wordcount-1); -+ if (!strcmp (words[wordcount-2], "force")) { -+ event = EVENT_TIER_ATTACH_FORCE; -+ } else { -+ event = EVENT_TIER_ATTACH; -+ } - goto out; - } - -@@ -1176,6 +1191,10 @@ cli_cmd_volume_tier_cbk (struct cli_state *state, - out: - if (ret) { - cli_out ("Tier command failed"); -+ } else { -+ if (event != EVENT_LAST) { -+ gf_event (event, "vol=%s", words[2]); -+ } - } - if (options) - dict_unref (options); -@@ -2946,8 +2965,8 @@ struct cli_cmd volume_cmds[] = { - #if !defined(__NetBSD__) - { "volume tier status\n" - "volume tier start [force]\n" -- "volume tier attach [] ...\n" -- "volume tier detach \n", -+ "volume tier attach [] ... [force]\n" -+ "volume tier detach \n", - cli_cmd_volume_tier_cbk, - "Tier translator specific operations."}, - -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 02a9bdb..4f7ec44 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -150,6 +150,19 @@ keys = ( - "EVENT_AFR_SUBVOL_UP", - "EVENT_AFR_SUBVOLS_DOWN", - "EVENT_AFR_SPLIT_BRAIN", -+ -+ "EVENT_TIER_ATTACH", -+ "EVENT_TIER_ATTACH_FORCE", -+ "EVENT_TIER_DETACH_START", -+ "EVENT_TIER_DETACH_STOP", -+ "EVENT_TIER_DETACH_COMMIT", -+ "EVENT_TIER_DETACH_FORCE", -+ "EVENT_TIER_PAUSE", -+ "EVENT_TIER_RESUME", -+ "EVENT_TIER_WATERMARK_HI", -+ "EVENT_TIER_WATERMARK_DROPPED_TO_MID", -+ "EVENT_TIER_WATERMARK_RAISED_TO_MID", -+ "EVENT_TIER_WATERMARK_DROPPED_TO_LOW", - ) - - LAST_EVENT = "EVENT_LAST" -diff --git a/xlators/cluster/dht/src/Makefile.am b/xlators/cluster/dht/src/Makefile.am -index 29be5ce..9c38221 100644 ---- a/xlators/cluster/dht/src/Makefile.am -+++ b/xlators/cluster/dht/src/Makefile.am -@@ -36,6 +36,7 @@ noinst_HEADERS = dht-common.h dht-mem-types.h dht-messages.h dht-helper.h tier-c - AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ - -I$(top_srcdir)/libglusterfs/src/gfdb \ - -I$(top_srcdir)/xlators/lib/src \ -+ -I$(top_srcdir)/rpc/rpc-lib/src \ - -DDATADIR=\"$(localstatedir)\" \ - -DLIBDIR=\"$(libdir)\" \ - -DLIBGFDB_VERSION=\"$(LIBGFDB_VERSION)\" -diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h -index fa06252..96df385 100644 ---- a/xlators/cluster/dht/src/dht-common.h -+++ b/xlators/cluster/dht/src/dht-common.h -@@ -18,6 +18,7 @@ - #include "syncop.h" - #include "refcount.h" - #include "timer.h" -+#include "protocol-common.h" - - #ifndef _DHT_H - #define _DHT_H -@@ -401,6 +402,7 @@ typedef struct gf_tier_conf { - * in the last cycle of promote or demote */ - int32_t last_promote_qfile_index; - int32_t last_demote_qfile_index; -+ char volname[GD_VOLUME_NAME_MAX + 1]; - } gf_tier_conf_t; - - struct gf_defrag_info_ { -diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c -index 77f6ec2..58b0d74 100644 ---- a/xlators/cluster/dht/src/dht-rebalance.c -+++ b/xlators/cluster/dht/src/dht-rebalance.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include "events.h" - - - #define GF_DISK_SECTOR_SIZE 512 -@@ -4071,6 +4072,8 @@ gf_defrag_check_pause_tier (gf_tier_conf_t *tier_conf) - gf_msg ("tier", GF_LOG_DEBUG, 0, - DHT_MSG_TIER_PAUSED, - "woken %d", woke); -+ -+ gf_event (EVENT_TIER_PAUSE, "vol=%s", tier_conf->volname); - out: - state = tier_conf->pause_state; - -@@ -4167,6 +4170,8 @@ gf_defrag_resume_tier (xlator_t *this, gf_defrag_info_t *defrag) - - gf_defrag_set_pause_state (&defrag->tier_conf, TIER_RUNNING); - -+ gf_event (EVENT_TIER_RESUME, "vol=%s", defrag->tier_conf.volname); -+ - return 0; - } - -diff --git a/xlators/cluster/dht/src/tier.c b/xlators/cluster/dht/src/tier.c -index c387bf8..83903e1 100644 ---- a/xlators/cluster/dht/src/tier.c -+++ b/xlators/cluster/dht/src/tier.c -@@ -14,6 +14,7 @@ - #include "tier.h" - #include "tier-common.h" - #include "syscall.h" -+#include "events.h" - - /*Hard coded DB info*/ - static gfdb_db_type_t dht_tier_db_type = GFDB_SQLITE3; -@@ -321,6 +322,36 @@ exit: - return ret; - } - -+static void -+tier_send_watermark_event (const char *volname, -+ tier_watermark_op_t old_wm, -+ tier_watermark_op_t new_wm) -+{ -+ if (old_wm == TIER_WM_LOW || old_wm == TIER_WM_NONE) { -+ if (new_wm == TIER_WM_MID) { -+ gf_event (EVENT_TIER_WATERMARK_RAISED_TO_MID, -+ "vol=%s", volname); -+ } else if (new_wm == TIER_WM_HI) { -+ gf_event (EVENT_TIER_WATERMARK_HI, "vol=%s", volname); -+ } -+ } else if (old_wm == TIER_WM_MID) { -+ if (new_wm == TIER_WM_LOW) { -+ gf_event (EVENT_TIER_WATERMARK_DROPPED_TO_LOW, -+ "vol=%s", volname); -+ } else if (new_wm == TIER_WM_HI) { -+ gf_event (EVENT_TIER_WATERMARK_HI, "vol=%s", volname); -+ } -+ } else if (old_wm == TIER_WM_HI) { -+ if (new_wm == TIER_WM_MID) { -+ gf_event (EVENT_TIER_WATERMARK_DROPPED_TO_MID, -+ "vol=%s", volname); -+ } else if (new_wm == TIER_WM_LOW) { -+ gf_event (EVENT_TIER_WATERMARK_DROPPED_TO_LOW, -+ "vol=%s", volname); -+ } -+ } -+} -+ - int - tier_check_watermark (xlator_t *this) - { -@@ -352,6 +383,10 @@ tier_check_watermark (xlator_t *this) - - if (wm != tier_conf->watermark_last) { - -+ tier_send_watermark_event (tier_conf->volname, -+ tier_conf->watermark_last, -+ wm); -+ - tier_conf->watermark_last = wm; - gf_msg (this->name, GF_LOG_INFO, 0, - DHT_MSG_LOG_TIER_STATUS, -@@ -2204,6 +2239,31 @@ err: - } - - -+static void -+tier_save_vol_name (xlator_t *this) -+{ -+ dht_conf_t *conf = NULL; -+ gf_defrag_info_t *defrag = NULL; -+ char *suffix = NULL; -+ int name_len = 0; -+ -+ -+ conf = this->private; -+ defrag = conf->defrag; -+ -+ suffix = strstr (this->name, "-tier-dht"); -+ -+ if (suffix) -+ name_len = suffix - this->name; -+ else -+ name_len = strlen (this->name); -+ -+ if (name_len > GD_VOLUME_NAME_MAX) -+ name_len = GD_VOLUME_NAME_MAX; -+ -+ strncpy (defrag->tier_conf.volname, this->name, name_len); -+ defrag->tier_conf.volname[name_len] = 0; -+} - - int - tier_init (xlator_t *this) -@@ -2402,6 +2462,8 @@ tier_init (xlator_t *this) - defrag->write_freq_threshold, - defrag->read_freq_threshold); - -+ tier_save_vol_name (this); -+ - ret = 0; - - out: --- -1.7.1 - diff --git a/SOURCES/0065-common-ha-enable-and-disable-selinux-ganesha_use_fus.patch b/SOURCES/0065-common-ha-enable-and-disable-selinux-ganesha_use_fus.patch new file mode 100644 index 0000000..42536be --- /dev/null +++ b/SOURCES/0065-common-ha-enable-and-disable-selinux-ganesha_use_fus.patch @@ -0,0 +1,85 @@ +From f16ba446e30197ff1724a5e257b35fb41330835d Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Wed, 21 Jun 2017 10:01:20 -0400 +Subject: [PATCH 65/74] common-ha: enable and disable selinux + ganesha_use_fusefs + +Starting in Fedora 26 and RHEL 7.4 there are new targeted policies +in selinux which include a tuneable to allow ganesha.nfsd to access +the gluster (FUSE) shared_storage volume where ganesha maintains its +state. + +N.B. rpm doesn't have a way to distinguish between RHEL 7.3 or 7.4 +so it can't be enabled for RHEL at this time. /usr/sbin/semanage is +in policycoreutils-python in RHEL (versus policycoreutils-python-utils +in Fedora.) Once RHEL 7.4 GAs we may also wish to specify the version +for RHEL 7 explicitly, i.e. + Requires: selinux-policy >= 3.13.1-160. +But beware, the corresponding version in Fedora 26 seems to be +selinux-policy-3.13.1.258 or so. (Maybe earlier versions, but that's +what's currently in the F26 beta. + +release-3.10 is the upstream master branch for glusterfs-ganesha. For +release-3.11 and later storhaug needs a similar change, which is +tracked by https://github.com/linux-ha-storage/storhaug/issues/11 + +Maybe at some point we would want to consider migrating the targeted +policies for glusterfs (and nfs-ganesha) from selinux-policy to a +glusterfs-selinux (and nfs-ganesha-selinux) subpackage? + +Change-Id: I04a5443edd00636cbded59a2baddfa98095bf7ac +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://review.gluster.org/17597 +Smoke: Gluster Build System +Reviewed-by: Niels de Vos +Reviewed-by: jiffin tony Thottan +CentOS-regression: Gluster Build System +Signed-off-by: Jiffin Tony Thottan +--- + glusterfs.spec.in | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 0bad6cf..17f814b 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -410,6 +410,10 @@ Requires: pcs, dbus + %if ( 0%{?rhel} && 0%{?rhel} == 6 ) + Requires: cman, pacemaker, corosync + %endif ++%if ( 0%{?fedora} && 0%{?fedora} > 25 ) ++Requires(post): policycoreutils-python-utils ++Requires(postun): policycoreutils-python-utils ++%endif + %if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 5 ) + # we need portblock resource-agent in 3.9.5 and later. + Requires: resource-agents >= 3.9.5 +@@ -876,6 +880,12 @@ modprobe fuse + exit 0 + %endif + ++%if ( 0%{?fedora} && 0%{?fedora} > 25 ) ++%post ganesha ++semanage boolean -m ganesha_use_fusefs --on ++exit 0 ++%endif ++ + %if ( 0%{?_build_server} ) + %if ( 0%{!?_without_georeplication:1} ) + %post geo-replication +@@ -998,6 +1008,12 @@ fi + %postun api + /sbin/ldconfig + ++%if ( 0%{?fedora} && 0%{?fedora} > 25 ) ++%postun ganesha ++semanage boolean -m ganesha_use_fusefs --off ++exit 0 ++%endif ++ + %postun libs + /sbin/ldconfig + +-- +1.8.3.1 + diff --git a/SOURCES/0066-packaging-glusterfs-ganesha-update-sometimes-fails-s.patch b/SOURCES/0066-packaging-glusterfs-ganesha-update-sometimes-fails-s.patch new file mode 100644 index 0000000..541d5da --- /dev/null +++ b/SOURCES/0066-packaging-glusterfs-ganesha-update-sometimes-fails-s.patch @@ -0,0 +1,66 @@ +From f472b5db12723f1a478ad5886fac82958a04e131 Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Wed, 12 Jul 2017 07:43:51 -0400 +Subject: [PATCH 66/74] packaging: glusterfs-ganesha update sometimes fails + semanage + +Depending on how dnf orders updates, the updated version of +selinux-policy-targeted with ganesha_use_fusefs may not be updated +before the glusterfs-ganesha update execute its %post scriptlet +containing the `semanage ganesha_use_fusefs ...` command. In such +situations the semanage command (silently) fails. + +Use a %trigger (and %triggerun) to run the scriptlet (again) after +selinux-policy-targeted with ganesha_use_fusefs has been installed +or updated. + +Note: the %triggerun is probably unnecessary, but it doesn't hurt. + +The release-3.10 branch is the "upstream master" for the glusterfs- +ganesha subpackage. + +Note: to be merged after https://review.gluster.org/17806 + +Change-Id: I1ad06d79fa1711e4abf038baf9f0a5b7bb665934 +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://review.gluster.org/17756 +Smoke: Gluster Build System +CentOS-regression: Gluster Build System +Reviewed-by: Niels de Vos +Signed-off-by: Jiffin Tony Thottan +--- + glusterfs.spec.in | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 17f814b..e6e2ba3 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1027,6 +1027,24 @@ exit 0 + %endif + + ##----------------------------------------------------------------------------- ++## All %%trigger should be placed here and keep them sorted ++## ++%if ( 0%{?fedora} && 0%{?fedora} > 25 ) ++%trigger ganesha -- selinux-policy-targeted ++semanage boolean -m ganesha_use_fusefs --on ++exit 0 ++%endif ++ ++##----------------------------------------------------------------------------- ++## All %%triggerun should be placed here and keep them sorted ++## ++%if ( 0%{?fedora} && 0%{?fedora} > 25 ) ++%triggerun ganesha -- selinux-policy-targeted ++semanage boolean -m ganesha_use_fusefs --off ++exit 0 ++%endif ++ ++##----------------------------------------------------------------------------- + ## All %%files should be placed here and keep them grouped + ## + %files +-- +1.8.3.1 + diff --git a/SOURCES/0066-xlators-ganesha-Remove-the-ganesha-xlator-code-entir.patch b/SOURCES/0066-xlators-ganesha-Remove-the-ganesha-xlator-code-entir.patch deleted file mode 100644 index 309bac8..0000000 --- a/SOURCES/0066-xlators-ganesha-Remove-the-ganesha-xlator-code-entir.patch +++ /dev/null @@ -1,274 +0,0 @@ -From 9f919b8632a82e8343ce3c2a665453f5bdd69350 Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Mon, 1 Aug 2016 12:11:24 +0530 -Subject: [PATCH 66/86] xlators/ganesha : Remove the ganesha xlator code entirely from source - -ganesha xlator is dummy xlator which introduced as part of cli options. -But all the ganesha related cli commands are handled from glusterd only. -There is no point in keeping this xlator. Hence removing the same since -it does not have any role in NFS-Ganesha intergration with gluster - -Upstream reference : ->Change-Id: Id438d2fabd3afe7e91ae26522df8495c8e9e9308 ->BUG: 1361999 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/15055 ->Smoke: Gluster Build System ->Reviewed-by: soumya k ->NetBSD-regression: NetBSD Build System ->Reviewed-by: Kaleb KEITHLEY ->CentOS-regression: Gluster Build System ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: Id438d2fabd3afe7e91ae26522df8495c8e9e9308 -BUG: 1348949 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84775 -Reviewed-by: Soumya Koduri -Reviewed-by: Milind Changire -Reviewed-by: Atin Mukherjee ---- - configure.ac | 2 - - glusterfs.spec.in | 4 +- - xlators/features/Makefile.am | 2 +- - xlators/features/ganesha/Makefile.am | 3 - - xlators/features/ganesha/src/Makefile.am | 18 ----- - xlators/features/ganesha/src/ganesha-mem-types.h | 21 ----- - xlators/features/ganesha/src/ganesha.c | 90 ---------------------- - xlators/features/ganesha/src/ganesha.h | 18 ----- - 8 files changed, 4 insertions(+), 154 deletions(-) - delete mode 100644 xlators/features/ganesha/Makefile.am - delete mode 100644 xlators/features/ganesha/src/Makefile.am - delete mode 100644 xlators/features/ganesha/src/ganesha-mem-types.h - delete mode 100644 xlators/features/ganesha/src/ganesha.c - delete mode 100644 xlators/features/ganesha/src/ganesha.h - -diff --git a/configure.ac b/configure.ac -index 75ebcd4..94e195c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -147,8 +147,6 @@ AC_CONFIG_FILES([Makefile - xlators/features/quiesce/src/Makefile - xlators/features/barrier/Makefile - xlators/features/barrier/src/Makefile -- xlators/features/ganesha/Makefile -- xlators/features/ganesha/src/Makefile - xlators/features/index/Makefile - xlators/features/index/src/Makefile - xlators/features/protect/Makefile -diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index a60f216..7d3f2da 100644 ---- a/glusterfs.spec.in -+++ b/glusterfs.spec.in -@@ -1160,7 +1160,6 @@ exit 0 - %files client-xlators - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/*.so - %exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/pump.so --%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/ganesha.so - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/client.so - - %if ( 0%{!?_without_extra_xlators:1} ) -@@ -2008,6 +2007,9 @@ end - %endif - - %changelog -+* Fri Sep 16 2016 Jiffin Tony Thottan -+- Remove ganesha.so from client xlators -+ - * Fri Sep 16 2016 Aravinda VK - - Added Python subpackage "cliutils" under gluster (#1342356) - -diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am -index c63eb75..68dc38b 100644 ---- a/xlators/features/Makefile.am -+++ b/xlators/features/Makefile.am -@@ -1,5 +1,5 @@ - SUBDIRS = locks quota read-only mac-compat quiesce marker index barrier \ -- arbiter protect compress changelog changetimerecorder ganesha \ -+ arbiter protect compress changelog changetimerecorder \ - gfid-access $(GLUPY_SUBDIR) upcall snapview-client snapview-server \ - trash shard bit-rot leases - -diff --git a/xlators/features/ganesha/Makefile.am b/xlators/features/ganesha/Makefile.am -deleted file mode 100644 -index a985f42..0000000 ---- a/xlators/features/ganesha/Makefile.am -+++ /dev/null -@@ -1,3 +0,0 @@ --SUBDIRS = src -- --CLEANFILES = -diff --git a/xlators/features/ganesha/src/Makefile.am b/xlators/features/ganesha/src/Makefile.am -deleted file mode 100644 -index 3bf291b..0000000 ---- a/xlators/features/ganesha/src/Makefile.am -+++ /dev/null -@@ -1,18 +0,0 @@ --xlator_LTLIBRARIES = ganesha.la -- --xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features -- --noinst_HEADERS = ganesha.h ganesha-mem-types.h -- --ganesha_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) -- --ganesha_la_SOURCES = ganesha.c -- --AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -- -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\ -- -DGANESHA_DIR=\"$(sysconfdir)/ganesha\" \ -- -DGYSNCD_PREFIX=\"$(libexecdir)/glusterfs\" -- --AM_CFLAGS = -Wall $(GF_CFLAGS) -- --CLEANFILES = -diff --git a/xlators/features/ganesha/src/ganesha-mem-types.h b/xlators/features/ganesha/src/ganesha-mem-types.h -deleted file mode 100644 -index c4976c0..0000000 ---- a/xlators/features/ganesha/src/ganesha-mem-types.h -+++ /dev/null -@@ -1,21 +0,0 @@ --/* -- Copyright (c) 2015 Red Hat, Inc. -- This file is part of GlusterFS. -- -- This file is licensed to you under your choice of the GNU Lesser -- General Public License, version 3 or any later version (LGPLv3 or -- later), or the GNU General Public License, version 2 (GPLv2), in all -- cases as published by the Free Software Foundation. --*/ --#ifndef __GANESHA_MEM_TYPES_H__ --#define __GANESHA_MEM_TYPES_H__ -- -- --#include "mem-types.h" -- --enum gf_ganesha_mem_types_ { -- gf_ganesha_mt_priv_t = gf_common_mt_end + 1, -- gf_ganesha_mt_end --}; -- --#endif -diff --git a/xlators/features/ganesha/src/ganesha.c b/xlators/features/ganesha/src/ganesha.c -deleted file mode 100644 -index 8599154..0000000 ---- a/xlators/features/ganesha/src/ganesha.c -+++ /dev/null -@@ -1,90 +0,0 @@ --/* -- Copyright (c) 2015 Red Hat, Inc. -- This file is part of GlusterFS. -- -- This file is licensed to you under your choice of the GNU Lesser -- General Public License, version 3 or any later version (LGPLv3 or -- later), or the GNU General Public License, version 2 (GPLv2), in all -- cases as published by the Free Software Foundation. --*/ -- -- --#include "ganesha.h" --#include "ganesha-mem-types.h" -- -- --int32_t --mem_acct_init (xlator_t *this) --{ -- int ret = -1; -- -- if (!this) -- return ret; -- -- ret = xlator_mem_acct_init (this, gf_ganesha_mt_end + 1); -- -- if (ret != 0) -- gf_log (this->name, GF_LOG_WARNING, "Memory accounting" -- "init failed"); -- -- return ret; --} -- --int32_t --init (xlator_t *this) --{ -- int ret = -1; -- ganesha_priv_t *priv = NULL; -- -- if (!this->children || this->children->next) { -- gf_log (this->name, GF_LOG_ERROR, -- "Need subvolume == 1"); -- goto err; -- } -- -- if (!this->parents) { -- gf_log (this->name, GF_LOG_WARNING, -- "Dangling volume. Check volfile"); -- goto err; -- } -- -- priv = GF_CALLOC (1, sizeof (*priv), gf_ganesha_mt_priv_t); -- if (!priv) -- goto err; -- -- this->private = priv; -- ret = 0; -- --err: -- return ret; --} -- -- --void --fini (xlator_t *this) --{ -- ganesha_priv_t *priv = this->private; -- -- this->private = NULL; -- if (priv) -- GF_FREE (priv); -- -- return; --} -- --struct xlator_fops fops = { --}; -- --struct xlator_cbks cbks = { --}; -- --struct volume_options options[] = { -- -- { .key = {"ganesha.enable"}, -- .default_value = "off", -- .type = GF_OPTION_TYPE_BOOL, -- .description = "export volume via NFS-Ganesha" -- }, -- { .key = {NULL} -- }, --}; -diff --git a/xlators/features/ganesha/src/ganesha.h b/xlators/features/ganesha/src/ganesha.h -deleted file mode 100644 -index 86320e9..0000000 ---- a/xlators/features/ganesha/src/ganesha.h -+++ /dev/null -@@ -1,18 +0,0 @@ --/* -- Copyright (c) 2015 Red Hat, Inc. -- This file is part of GlusterFS. -- -- This file is licensed to you under your choice of the GNU Lesser -- General Public License, version 3 or any later version (LGPLv3 or -- later), or the GNU General Public License, version 2 (GPLv2), in all -- cases as published by the Free Software Foundation. --*/ -- --#include "xlator.h" --#include "ganesha-mem-types.h" -- --typedef struct { -- char *host_name; --} ganesha_priv_t; -- -- --- -1.7.1 - diff --git a/SOURCES/0067-packaging-own-files-in-var-run-gluster-shared_storag.patch b/SOURCES/0067-packaging-own-files-in-var-run-gluster-shared_storag.patch new file mode 100644 index 0000000..ccaf613 --- /dev/null +++ b/SOURCES/0067-packaging-own-files-in-var-run-gluster-shared_storag.patch @@ -0,0 +1,70 @@ +From aa20e41c3087f9ec68d0a7890ed953e5bc7aa096 Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Wed, 26 Jul 2017 10:36:11 -0400 +Subject: [PATCH 67/74] packaging: own files in + (/var)/run/gluster/shared_storage/nfs-ganesha + +The nfs-ganesha rpm owns /etc/ganesha and /etc/ganesha/ganesha.conf, +but gluster-ganesha installs a ganesha-ha.conf.sample in /etc/ganesha/ + +Ganesha HA expects to find the config files in /var/run/.../nfs-ganesha +and for there to be symlinks from /etc/ganesha/* to /var/run/... + +As exports are created the ganesha export files are written to +/var/run/gluster/shared_storage/nfs-ganesha/exports/* + +This change creates rpm %ghosts for most of these files to manage +ownership within rpm and ensure they are not deleted or overwritten +during package install/upgrade/removal. The name of the exports varies, +so it's not possible AFAIK to create wildcard %ghosts for them. + +Change-Id: Ic4389291c0af0bd72c22fa742cdfa2011b9286f3 +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://review.gluster.org/17883 +Smoke: Gluster Build System +CentOS-regression: Gluster Build System +Reviewed-by: Niels de Vos +Signed-off-by: Jiffin Tony Thottan +--- + glusterfs.spec.in | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index e6e2ba3..cbc77c3 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -818,6 +818,13 @@ sed -i 's|option working-directory /etc/glusterd|option working-directory %{_sha + install -D -p -m 0644 extras/glusterfs-logrotate \ + %{buildroot}%{_sysconfdir}/logrotate.d/glusterfs + ++# ganesha ghosts ++mkdir -p %{buildroot}%{_sysconfdir}/ganesha ++touch %{buildroot}%{_sysconfdir}/ganesha/ganesha-ha.conf ++mkdir -p %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/exports ++touch %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha.conf ++touch %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha-ha.conf ++ + %if ( 0%{!?_without_georeplication:1} ) + mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/geo-replication + touch %{buildroot}%{_sharedstatedir}/glusterd/geo-replication/gsyncd_template.conf +@@ -1309,10 +1316,16 @@ exit 0 + + %if ( 0%{?_build_server} ) + %files ganesha +-%{_sysconfdir}/ganesha/* ++%dir %{_libexecdir}/ganesha + %{_libexecdir}/ganesha/* + %{_prefix}/lib/ocf/resource.d/heartbeat/* + %{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh ++%{_sysconfdir}/ganesha/ganesha-ha.conf.sample ++%ghost %config(noreplace) %{_sysconfdir}/ganesha/ganesha-ha.conf ++%ghost %dir %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha ++%ghost %dir %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/exports ++%ghost %config(noreplace) %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha.conf ++%ghost %config(noreplace) %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha-ha.conf + %endif + + %if ( 0%{?_build_server} ) +-- +1.8.3.1 + diff --git a/SOURCES/0067-snapshot-eventsapi-Integrate-snapshot-events-with-ev.patch b/SOURCES/0067-snapshot-eventsapi-Integrate-snapshot-events-with-ev.patch deleted file mode 100644 index dd1f107..0000000 --- a/SOURCES/0067-snapshot-eventsapi-Integrate-snapshot-events-with-ev.patch +++ /dev/null @@ -1,970 +0,0 @@ -From dca6f06c6b49ba92c1f2278e806c615a1a6b4b16 Mon Sep 17 00:00:00 2001 -From: Avra Sengupta -Date: Fri, 26 Aug 2016 14:05:07 +0530 -Subject: [PATCH 67/79] snapshot/eventsapi: Integrate snapshot events with eventsapi - - Backport of http://review.gluster.org/#/c/15329/ - -1. EVENT_SNAPSHOT_CREATED : snapshot_name=snap1 volume_name=test_vol - snapshot_uuid=26dd6c52-6021-40b1-a507-001a80401d70 -2. EVENT_SNAPSHOT_CREATE_FAILED : snapshot_name=snap1 volume_name=test_vol - error=Snapshot snap1 already exists -3. EVENT_SNAPSHOT_ACTIVATED : snapshot_name=snap1 - snapshot_uuid=26dd6c52-6021-40b1-a507-001a80401d70 -4. EVENT_SNAPSHOT_ACTIVATE_FAILED: snapshot_name=snap1 - error=Snapshot snap1 is already activated. -5. EVENT_SNAPSHOT_DEACTIVATED : snapshot_name=snap1 - snapshot_uuid=26dd6c52-6021-40b1-a507-001a80401d70 -6. EVENT_SNAPSHOT_DEACTIVATE_FAILED : snapshot_name=snap3 - error=Snapshot (snap3) does not exist. -7. EVENT_SNAPSHOT_SOFT_LIMIT_REACHED : volume_name=test_vol - volume_id=2ace2616-5591-4b9b-be2a-38592dda5758 -8. EVENT_SNAPSHOT_HARD_LIMIT_REACHED : volume_name=test_vol - volume_id=2ace2616-5591-4b9b-be2a-38592dda5758 -9. EVENT_SNAPSHOT_RESTORED : snapshot_name=snap1 volume_name=test_vol - snapshot_uuid=3a840ec5-08da-4f2b-850d-1d5539a5d14d -10. EVENT_SNAPSHOT_RESTORE_FAILED : snapshot_name=snap10 - error=Snapshot (snap10) does not exist -11. EVENT_SNAPSHOT_DELETED : snapshot_name=snap1 - snapshot_uuid=d9ff3d4f-f579-4345-a4da-4f9353f0950c -12. EVENT_SNAPSHOT_DELETE_FAILED : snapshot_name=snap2 - error=Snapshot (snap2) does not exist -13. EVENT_SNAPSHOT_CLONED : clone_uuid=93ba9f06-cb9c-4ace-aa52-2616e7f31022 - snapshot_name=snap1 clone_name=clone2 -14. EVENT_SNAPSHOT_CLONE_FAILED : snapshot_name=snap1 clone_name=clone2 - error=Volume with name:clone2 already exists -15. EVENT_SNAPSHOT_CONFIG_UPDATED : auto-delete=enable config_type=system_config - config_type=volume_config hard_limit=100 -16. EVENT_SNAPSHOT_CONFIG_UPDATE_FAILED : - error=Invalid snap-max-soft-limit 110. Expected range 1 - 100 -17. EVENT_SNAPSHOT_SCHEDULER_INITIALISED : status=Success -18. EVENT_SNAPSHOT_SCHEDULER_INIT_FAILED -19. EVENT_SNAPSHOT_SCHEDULER_ENABLED : status=Successfuly Enabled -20. EVENT_SNAPSHOT_SCHEDULER_ENABLE_FAILED : - error=Snapshot scheduler is already enabled. -21. EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADDED : status=Successfuly added job job1 -22. EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED : - status=Failed to add job job1 error=The job already exists. -23. EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDITED : - status=Successfuly edited job job1 -24. EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED : - status=Failed to edit job job2 - error=The job cannot be found. -25. EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETED : - status=Successfuly deleted job job1 -26. EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED : - status=Failed to delete job job1 - error=The job cannot be found. -27. EVENT_SNAPSHOT_SCHEDULER_DISABLED : status=Successfuly Disabled -28. EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED : - error=Snapshot scheduler is already disabled. - -Also excluded conf.py for client build - -> Reviewed-on: http://review.gluster.org/15329 -> Tested-by: Aravinda VK -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Rajesh Joseph - -(cherry picked from commit c1278de9a5fb6a64455f42b8b17a8d05b74c2420) - -Change-Id: I3479cc3fb7af3c76ded67cf289f99547d0a55d21 -BUG: 1361184 -Signed-off-by: Avra Sengupta -Reviewed-on: https://code.engineering.redhat.com/gerrit/84811 -Reviewed-by: Milind Changire -Tested-by: Atin Mukherjee -Reviewed-by: Atin Mukherjee ---- - cli/src/cli-rpc-ops.c | 384 ++++++++++++++++++-- - configure.ac | 1 + - extras/snap_scheduler/Makefile.am | 4 +- - extras/snap_scheduler/conf.py.in | 11 + - extras/snap_scheduler/snap_scheduler.py | 77 ++++- - glusterfs.spec.in | 5 + - .../mgmt/glusterd/src/glusterd-snapshot-utils.c | 1 + - xlators/mgmt/glusterd/src/glusterd-snapshot.c | 105 +++++- - 9 files changed, 550 insertions(+), 39 deletions(-) - create mode 100644 extras/snap_scheduler/conf.py.in - -diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c -index dcf2a12..e8fc658 100644 ---- a/cli/src/cli-rpc-ops.c -+++ b/cli/src/cli-rpc-ops.c -@@ -39,6 +39,7 @@ - #include "cli-quotad-client.h" - #include "run.h" - #include "quota-common-utils.h" -+#include "events.h" - - enum gf_task_types { - GF_TASK_TYPE_REBALANCE, -@@ -10316,6 +10317,334 @@ out: - } - - int -+gf_cli_generate_snapshot_event (gf_cli_rsp *rsp, dict_t *dict, -+ int32_t type, char *snap_name, -+ char *volname, char *snap_uuid, -+ char *clone_name) -+{ -+ int ret = -1; -+ int config_command = 0; -+ int32_t delete_cmd = -1; -+ uint64_t hard_limit = 0; -+ uint64_t soft_limit = 0; -+ char *auto_delete = NULL; -+ char *snap_activate = NULL; -+ char msg[PATH_MAX] = {0, }; -+ char option[PATH_MAX] = {0, }; -+ -+ GF_VALIDATE_OR_GOTO ("cli", dict, out); -+ GF_VALIDATE_OR_GOTO ("cli", rsp, out); -+ -+ switch (type) { -+ case GF_SNAP_OPTION_TYPE_CREATE: -+ if (!snap_name) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get snap name"); -+ goto out; -+ } -+ -+ if (!volname) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get volume name"); -+ goto out; -+ } -+ -+ if (rsp->op_ret != 0) { -+ gf_event (EVENT_SNAPSHOT_CREATE_FAILED, -+ "snapshot_name=%s;volume_name=%s;error=%s", -+ snap_name, volname, -+ rsp->op_errstr ? rsp->op_errstr : -+ "Please check log file for details"); -+ ret = 0; -+ break; -+ } -+ -+ if (!snap_uuid) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); -+ goto out; -+ } -+ -+ gf_event (EVENT_SNAPSHOT_CREATED, "snapshot_name=%s;" -+ "volume_name=%s;snapshot_uuid=%s", snap_name, -+ volname, snap_uuid); -+ -+ ret = 0; -+ break; -+ -+ case GF_SNAP_OPTION_TYPE_ACTIVATE: -+ if (!snap_name) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get snap name"); -+ goto out; -+ } -+ -+ if (rsp->op_ret != 0) { -+ gf_event (EVENT_SNAPSHOT_ACTIVATE_FAILED, -+ "snapshot_name=%s;error=%s", snap_name, -+ rsp->op_errstr ? rsp->op_errstr : -+ "Please check log file for details"); -+ ret = 0; -+ break; -+ } -+ -+ if (!snap_uuid) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); -+ goto out; -+ } -+ -+ gf_event (EVENT_SNAPSHOT_ACTIVATED, "snapshot_name=%s;" -+ "snapshot_uuid=%s", snap_name, snap_uuid); -+ -+ ret = 0; -+ break; -+ -+ case GF_SNAP_OPTION_TYPE_DEACTIVATE: -+ if (!snap_name) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get snap name"); -+ goto out; -+ } -+ -+ if (rsp->op_ret != 0) { -+ gf_event (EVENT_SNAPSHOT_DEACTIVATE_FAILED, -+ "snapshot_name=%s;error=%s", snap_name, -+ rsp->op_errstr ? rsp->op_errstr : -+ "Please check log file for details"); -+ ret = 0; -+ break; -+ } -+ -+ if (!snap_uuid) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); -+ goto out; -+ } -+ -+ gf_event (EVENT_SNAPSHOT_DEACTIVATED, "snapshot_name=%s;" -+ "snapshot_uuid=%s", snap_name, snap_uuid); -+ -+ ret = 0; -+ break; -+ -+ case GF_SNAP_OPTION_TYPE_RESTORE: -+ if (!snap_name) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get snap name"); -+ goto out; -+ } -+ -+ if (rsp->op_ret != 0) { -+ gf_event (EVENT_SNAPSHOT_RESTORE_FAILED, -+ "snapshot_name=%s;error=%s", snap_name, -+ rsp->op_errstr ? rsp->op_errstr : -+ "Please check log file for details"); -+ ret = 0; -+ break; -+ } -+ -+ if (!snap_uuid) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); -+ goto out; -+ } -+ -+ if (!volname) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to get volname"); -+ goto out; -+ } -+ -+ gf_event (EVENT_SNAPSHOT_RESTORED, "snapshot_name=%s;" -+ "snapshot_uuid=%s;volume_name=%s", -+ snap_name, snap_uuid, volname); -+ -+ ret = 0; -+ break; -+ -+ case GF_SNAP_OPTION_TYPE_DELETE: -+ ret = dict_get_int32 (dict, "sub-cmd", &delete_cmd); -+ if (ret) { -+ gf_log ("cli", GF_LOG_ERROR, "Could not get sub-cmd"); -+ goto out; -+ } -+ -+ /* -+ * Need not generate any event (success or failure) for delete * -+ * all, as it will trigger individual delete for all snapshots * -+ */ -+ if (delete_cmd == GF_SNAP_DELETE_TYPE_ALL) { -+ ret = 0; -+ break; -+ } -+ -+ if (!snap_name) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get snap name"); -+ goto out; -+ } -+ -+ if (rsp->op_ret != 0) { -+ gf_event (EVENT_SNAPSHOT_DELETE_FAILED, -+ "snapshot_name=%s;error=%s", snap_name, -+ rsp->op_errstr ? rsp->op_errstr : -+ "Please check log file for details"); -+ ret = 0; -+ break; -+ } -+ -+ if (!snap_uuid) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); -+ goto out; -+ } -+ -+ gf_event (EVENT_SNAPSHOT_DELETED, "snapshot_name=%s;" -+ "snapshot_uuid=%s", snap_name, snap_uuid); -+ -+ ret = 0; -+ break; -+ -+ case GF_SNAP_OPTION_TYPE_CLONE: -+ if (!clone_name) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get clone name"); -+ goto out; -+ } -+ -+ if (!snap_name) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to get snapname name"); -+ goto out; -+ } -+ -+ if (rsp->op_ret != 0) { -+ gf_event (EVENT_SNAPSHOT_CLONE_FAILED, -+ "snapshot_name=%s;clone_name=%s;" -+ "error=%s", snap_name, clone_name, -+ rsp->op_errstr ? rsp->op_errstr : -+ "Please check log file for details"); -+ ret = 0; -+ break; -+ } -+ -+ if (!snap_uuid) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid"); -+ goto out; -+ } -+ -+ gf_event (EVENT_SNAPSHOT_CLONED, "snapshot_name=%s;" -+ "clone_name=%s;clone_uuid=%s", -+ snap_name, clone_name, snap_uuid); -+ -+ ret = 0; -+ break; -+ -+ case GF_SNAP_OPTION_TYPE_CONFIG: -+ if (rsp->op_ret != 0) { -+ gf_event (EVENT_SNAPSHOT_CONFIG_UPDATE_FAILED, -+ "error=%s", -+ rsp->op_errstr ? rsp->op_errstr : -+ "Please check log file for details"); -+ ret = 0; -+ break; -+ } -+ -+ ret = dict_get_int32 (dict, "config-command", &config_command); -+ if (ret) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Could not fetch config type"); -+ goto out; -+ } -+ -+ if (config_command == GF_SNAP_CONFIG_DISPLAY) { -+ ret = 0; -+ break; -+ } -+ -+ /* These are optional parameters therefore ignore the error */ -+ ret = dict_get_uint64 (dict, "snap-max-hard-limit", -+ &hard_limit); -+ ret = dict_get_uint64 (dict, "snap-max-soft-limit", -+ &soft_limit); -+ ret = dict_get_str (dict, "auto-delete", -+ &auto_delete); -+ ret = dict_get_str (dict, "snap-activate-on-create", -+ &snap_activate); -+ -+ if (!hard_limit && !soft_limit && -+ !auto_delete && !snap_activate) { -+ ret = -1; -+ gf_log ("cli", GF_LOG_ERROR, "At least one option from " -+ "snap-max-hard-limit, snap-max-soft-limit, " -+ "auto-delete and snap-activate-on-create " -+ "should be set"); -+ goto out; -+ } -+ -+ volname = NULL; -+ ret = dict_get_str (dict, "volname", &volname); -+ -+ if (hard_limit || soft_limit) { -+ snprintf (option, sizeof(option), "%s=%"PRIu64, -+ hard_limit ? "hard_limit" : "soft_limit", -+ hard_limit ? hard_limit:soft_limit); -+ } else if (auto_delete || snap_activate) { -+ snprintf (option, sizeof(option), "%s=%s", -+ auto_delete ? "auto-delete" : "snap-activate", -+ auto_delete ? auto_delete:snap_activate); -+ } -+ -+ snprintf (msg, sizeof(msg), "config_type=%s;%s", -+ volname?"volume_config":"system_config", option); -+ -+ gf_event (EVENT_SNAPSHOT_CONFIG_UPDATED, "%s", msg); -+ -+ ret = 0; -+ break; -+ -+ default: -+ gf_log ("cli", GF_LOG_WARNING, -+ "Cannot generate event for unknown type."); -+ ret = 0; -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ -+/* -+ * Fetch necessary data from dict at one place instead of * -+ * repeating the same code again and again. * -+ */ -+int -+gf_cli_snapshot_get_data_from_dict (dict_t *dict, char **snap_name, -+ char **volname, char **snap_uuid, -+ int8_t *soft_limit_flag, -+ char **clone_name) -+{ -+ int ret = -1; -+ -+ GF_VALIDATE_OR_GOTO ("cli", dict, out); -+ -+ if (snap_name) -+ ret = dict_get_str (dict, "snapname", snap_name); -+ -+ if (volname) -+ ret = dict_get_str (dict, "volname1", volname); -+ -+ if (snap_uuid) -+ ret = dict_get_str (dict, "snapuuid", snap_uuid); -+ -+ if (soft_limit_flag) -+ ret = dict_get_int8 (dict, "soft-limit-reach", -+ soft_limit_flag); -+ -+ if (clone_name) -+ ret = dict_get_str (dict, "clonename", clone_name); -+ -+ ret = 0; -+out: -+ return ret; -+} -+ -+int - gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - int count, void *myframe) - { -@@ -10329,6 +10658,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - gf_boolean_t snap_driven = _gf_false; - int8_t soft_limit_flag = -1; - char *volname = NULL; -+ char *snap_uuid = NULL; - - GF_ASSERT (myframe); - -@@ -10363,6 +10693,24 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - goto out; - } - -+ ret = gf_cli_snapshot_get_data_from_dict (dict, &snap_name, &volname, -+ &snap_uuid, &soft_limit_flag, -+ &clone_name); -+ if (ret) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to fetch data from dict."); -+ goto out; -+ } -+ -+#if (USE_EVENTS) -+ ret = gf_cli_generate_snapshot_event (&rsp, dict, type, snap_name, -+ volname, snap_uuid, clone_name); -+ if (ret) { -+ gf_log ("cli", GF_LOG_ERROR, -+ "Failed to generate snapshot event"); -+ goto out; -+ } -+#endif -+ - /* Snapshot status and delete command is handled separately */ - if (global_state->mode & GLUSTER_MODE_XML && - GF_SNAP_OPTION_TYPE_STATUS != type && -@@ -10386,19 +10734,13 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - goto out; - } - -- ret = dict_get_str (dict, "snapname", &snap_name); -- if (ret) { -+ if (!snap_name) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get snap name"); - goto out; - } - -- /* TODO : Instead of using volname1 directly use -- * volname$i in loop once snapshot of multiple -- * volumes are supported -- */ -- ret = dict_get_str (dict, "volname1", &volname); -- if (ret) { -+ if (!volname) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get volume name"); - goto out; -@@ -10407,8 +10749,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - cli_out ("snapshot create: success: Snap %s created " - "successfully", snap_name); - -- ret = dict_get_int8 (dict, "soft-limit-reach", -- &soft_limit_flag); - if (soft_limit_flag == 1) { - cli_out ("Warning: Soft-limit of volume (%s) is " - "reached. Snapshot creation is not possible " -@@ -10426,15 +10766,13 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - goto out; - } - -- ret = dict_get_str (dict, "clonename", &clone_name); -- if (ret) { -+ if (!clone_name) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get clone name"); - goto out; - } - -- ret = dict_get_str (dict, "snapname", &snap_name); -- if (ret) { -+ if (!snap_name) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get snapname name"); - goto out; -@@ -10447,9 +10785,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - break; - - case GF_SNAP_OPTION_TYPE_RESTORE: -- /* TODO: Check if rsp.op_ret needs to be checked here. Or is -- * it ok to check this in the start of the function where we -- * get rsp.*/ - if (rsp.op_ret) { - cli_err("snapshot restore: failed: %s", - rsp.op_errstr ? rsp.op_errstr : -@@ -10458,8 +10793,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - goto out; - } - -- ret = dict_get_str (dict, "snapname", &snap_name); -- if (ret) { -+ if (!snap_name) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get snap name"); - goto out; -@@ -10471,9 +10805,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - ret = 0; - break; - case GF_SNAP_OPTION_TYPE_ACTIVATE: -- /* TODO: Check if rsp.op_ret needs to be checked here. Or is -- * it ok to check this in the start of the function where we -- * get rsp.*/ - if (rsp.op_ret) { - cli_err("snapshot activate: failed: %s", - rsp.op_errstr ? rsp.op_errstr : -@@ -10482,8 +10813,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - goto out; - } - -- ret = dict_get_str (dict, "snapname", &snap_name); -- if (ret) { -+ if (!snap_name) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get snap name"); - goto out; -@@ -10496,9 +10826,6 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - break; - - case GF_SNAP_OPTION_TYPE_DEACTIVATE: -- /* TODO: Check if rsp.op_ret needs to be checked here. Or is -- * it ok to check this in the start of the function where we -- * get rsp.*/ - if (rsp.op_ret) { - cli_err("snapshot deactivate: failed: %s", - rsp.op_errstr ? rsp.op_errstr : -@@ -10507,8 +10834,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov, - goto out; - } - -- ret = dict_get_str (dict, "snapname", &snap_name); -- if (ret) { -+ if (!snap_name) { - gf_log ("cli", GF_LOG_ERROR, - "Failed to get snap name"); - goto out; -diff --git a/configure.ac b/configure.ac -index 94e195c..011cf14 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -43,6 +43,7 @@ AC_CONFIG_FILES([Makefile - geo-replication/src/peer_mountbroker - extras/peer_add_secret_pub - geo-replication/syncdaemon/configinterface.py -+ extras/snap_scheduler/conf.py - glusterfsd/Makefile - glusterfsd/src/Makefile - rpc/Makefile -diff --git a/extras/snap_scheduler/Makefile.am b/extras/snap_scheduler/Makefile.am -index 896595f..ffc1579 100644 ---- a/extras/snap_scheduler/Makefile.am -+++ b/extras/snap_scheduler/Makefile.am -@@ -1,7 +1,7 @@ - snap_schedulerdir = $(sbindir)/ - --snap_scheduler_SCRIPTS = gcron.py snap_scheduler.py -+snap_scheduler_SCRIPTS = gcron.py snap_scheduler.py conf.py - --EXTRA_DIST = gcron.py snap_scheduler.py -+EXTRA_DIST = gcron.py snap_scheduler.py conf.py - - CLEANFILES = -diff --git a/extras/snap_scheduler/conf.py.in b/extras/snap_scheduler/conf.py.in -new file mode 100644 -index 0000000..6dcca05 ---- /dev/null -+++ b/extras/snap_scheduler/conf.py.in -@@ -0,0 +1,11 @@ -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+ -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+GLUSTERFS_LIBEXECDIR = '@GLUSTERFS_LIBEXECDIR@' -diff --git a/extras/snap_scheduler/snap_scheduler.py b/extras/snap_scheduler/snap_scheduler.py -index af092e2..23d5aa3 100755 ---- a/extras/snap_scheduler/snap_scheduler.py -+++ b/extras/snap_scheduler/snap_scheduler.py -@@ -19,7 +19,10 @@ import logging.handlers - import sys - import shutil - from errno import EEXIST -- -+from conf import GLUSTERFS_LIBEXECDIR -+sys.path.insert(1, GLUSTERFS_LIBEXECDIR) -+from events.gf_event import gf_event -+from events import eventtypes - - SCRIPT_NAME = "snap_scheduler" - scheduler_enabled = False -@@ -55,6 +58,42 @@ INVALID_SCHEDULE = 15 - INVALID_ARG = 16 - VOLUME_DOES_NOT_EXIST = 17 - -+def print_error (error_num): -+ if error_num == INTERNAL_ERROR: -+ return "Internal Error" -+ elif error_num == SHARED_STORAGE_DIR_DOESNT_EXIST: -+ return "The shared storage directory ("+SHARED_STORAGE_DIR+")" \ -+ " does not exist." -+ elif error_num == SHARED_STORAGE_NOT_MOUNTED: -+ return "The shared storage directory ("+SHARED_STORAGE_DIR+")" \ -+ " is not mounted." -+ elif error_num == ANOTHER_TRANSACTION_IN_PROGRESS: -+ return "Another transaction is in progress." -+ elif error_num == INIT_FAILED: -+ return "Initialisation failed." -+ elif error_num == SCHEDULING_ALREADY_DISABLED: -+ return "Snapshot scheduler is already disabled." -+ elif error_num == SCHEDULING_ALREADY_ENABLED: -+ return "Snapshot scheduler is already enabled." -+ elif error_num == NODE_NOT_INITIALISED: -+ return "The node is not initialised." -+ elif error_num == ANOTHER_SCHEDULER_ACTIVE: -+ return "Another scheduler is active." -+ elif error_num == JOB_ALREADY_EXISTS: -+ return "The job already exists." -+ elif error_num == JOB_NOT_FOUND: -+ return "The job cannot be found." -+ elif error_num == INVALID_JOBNAME: -+ return "The job name is invalid." -+ elif error_num == INVALID_VOLNAME: -+ return "The volume name is invalid." -+ elif error_num == INVALID_SCHEDULE: -+ return "The schedule is invalid." -+ elif error_num == INVALID_ARG: -+ return "The argument is invalid." -+ elif error_num == VOLUME_DOES_NOT_EXIST: -+ return "The volume does not exist." -+ - def output(msg): - print("%s: %s" % (SCRIPT_NAME, msg)) - -@@ -499,6 +538,7 @@ def initialise_scheduler(): - - log.info("Successfully initialised snapshot scheduler for this node") - output("Successfully initialised snapshot scheduler for this node") -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_INITIALISED, status="Success") - - ret = 0 - return ret -@@ -545,6 +585,8 @@ def perform_operation(args): - ret = initialise_scheduler() - if ret != 0: - output("Failed to initialise snapshot scheduling") -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_INIT_FAILED, -+ error=print_error(ret)) - return ret - - # Disable snapshot scheduler -@@ -552,6 +594,11 @@ def perform_operation(args): - ret = disable_scheduler() - if ret == 0: - subprocess.Popen(["touch", "-h", GCRON_TASKS]) -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_DISABLED, -+ status="Successfuly Disabled") -+ else: -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_DISABLE_FAILED, -+ error=print_error(ret)) - return ret - - # Check if the symlink to GCRON_TASKS is properly set in the shared storage -@@ -582,6 +629,11 @@ def perform_operation(args): - ret = enable_scheduler() - if ret == 0: - subprocess.Popen(["touch", "-h", GCRON_TASKS]) -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_ENABLED, -+ status="Successfuly Enabled") -+ else: -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_ENABLE_FAILED, -+ error=print_error(ret)) - return ret - - # Disable snapshot scheduler -@@ -589,6 +641,11 @@ def perform_operation(args): - ret = disable_scheduler() - if ret == 0: - subprocess.Popen(["touch", "-h", GCRON_TASKS]) -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_DISABLED, -+ status="Successfuly Disabled") -+ else: -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_DISABLE_FAILED, -+ error=print_error(ret)) - return ret - - # List snapshot schedules -@@ -604,6 +661,12 @@ def perform_operation(args): - ret = add_schedules(args.jobname, args.schedule, args.volname) - if ret == 0: - subprocess.Popen(["touch", "-h", GCRON_TASKS]) -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_SCHEDULE_ADDED, -+ status="Successfuly added job "+args.jobname) -+ else: -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED, -+ status="Failed to add job "+args.jobname, -+ error=print_error(ret)) - return ret - - # Delete snapshot schedules -@@ -614,6 +677,12 @@ def perform_operation(args): - ret = delete_schedules(args.jobname) - if ret == 0: - subprocess.Popen(["touch", "-h", GCRON_TASKS]) -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_SCHEDULE_DELETED, -+ status="Successfuly deleted job "+args.jobname) -+ else: -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED, -+ status="Failed to delete job "+args.jobname, -+ error=print_error(ret)) - return ret - - # Edit snapshot schedules -@@ -624,6 +693,12 @@ def perform_operation(args): - ret = edit_schedules(args.jobname, args.schedule, args.volname) - if ret == 0: - subprocess.Popen(["touch", "-h", GCRON_TASKS]) -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_SCHEDULE_EDITED, -+ status="Successfuly edited job "+args.jobname) -+ else: -+ gf_event (eventtypes.SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED, -+ status="Failed to edit job "+args.jobname, -+ error=print_error(ret)) - return ret - - ret = INVALID_ARG -diff --git a/glusterfs.spec.in b/glusterfs.spec.in -index 7d3f2da..5982b1f 100644 ---- a/glusterfs.spec.in -+++ b/glusterfs.spec.in -@@ -1053,6 +1053,7 @@ exit 0 - %exclude %{_sbindir}/glusterd - %exclude %{_sbindir}/snap_scheduler.py - %exclude %{_datadir}/glusterfs/scripts/stop-all-gluster-processes.sh -+%exclude %{_sbindir}/conf.py - %if 0%{?_tmpfilesdir:1} - %exclude %{_tmpfilesdir}/gluster.conf - %endif -@@ -1325,6 +1326,7 @@ exit 0 - # snap_scheduler - %{_sbindir}/snap_scheduler.py - %{_sbindir}/gcron.py -+%{_sbindir}/conf.py - - # /var/lib/glusterd, e.g. hookscripts, etc. - %ghost %attr(0644,-,-) %config(noreplace) %{_sharedstatedir}/glusterd/glusterd.info -@@ -2007,6 +2009,9 @@ end - %endif - - %changelog -+* Fri Sep 16 2016 Avra Sengupta -+- Added conf.py for snap scheduler -+ - * Fri Sep 16 2016 Jiffin Tony Thottan - - Remove ganesha.so from client xlators - -diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c -index 2fa9a59..81b9aa0 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c -+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c -@@ -4041,6 +4041,7 @@ glusterd_is_snap_soft_limit_reached (glusterd_volinfo_t *volinfo, dict_t *dict) - "set soft limit exceed flag in " - "response dictionary"); - } -+ - goto out; - } - ret = 0; -diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c -index 85f2a3f..70595ef 100644 ---- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c -+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c -@@ -61,6 +61,7 @@ - #include "xdr-generic.h" - - #include "lvm-defaults.h" -+#include "events.h" - - char snap_mount_dir[PATH_MAX]; - struct snap_create_args_ { -@@ -7961,6 +7962,7 @@ glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict) - int i = 0; - char *volname = NULL; - char key[PATH_MAX] = {0, }; -+ char msg[PATH_MAX] = {0, }; - glusterd_volinfo_t *volinfo = NULL; - uint64_t limit = 0; - int64_t count = 0; -@@ -8035,6 +8037,10 @@ glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict) - "Deleting snapshot %s.", limit, volinfo->volname, - snap->snapname); - -+ snprintf (msg, sizeof(msg), "snapshot_name=%s;" -+ "snapshot_uuid=%s", snap->snapname, -+ uuid_utoa(snap->snap_id)); -+ - LOCK (&snap->lock); - { - snap->snap_status = GD_SNAP_STATUS_DECOMMISSION; -@@ -8057,6 +8063,13 @@ glusterd_handle_snap_limit (dict_t *dict, dict_t *rsp_dict) - snap->snapname); - } - unlock: UNLOCK (&snap->lock); -+ if (is_origin_glusterd (dict) == _gf_true) { -+ if (ret) -+ gf_event (EVENT_SNAPSHOT_DELETE_FAILED, -+ "%s", msg); -+ else -+ gf_event (EVENT_SNAPSHOT_DELETED, "%s", msg); -+ } - } - - out: -@@ -8142,13 +8155,20 @@ int32_t - glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret, - char **op_errstr, dict_t *rsp_dict) - { -- xlator_t *this = NULL; -- glusterd_conf_t *priv = NULL; -- int ret = -1; -- int32_t cleanup = 0; -- glusterd_snap_t *snap = NULL; -- char *snapname = NULL; -- char *auto_delete = NULL; -+ xlator_t *this = NULL; -+ glusterd_conf_t *priv = NULL; -+ int ret = -1; -+ int32_t cleanup = 0; -+ glusterd_snap_t *snap = NULL; -+ char *snapname = NULL; -+ char *auto_delete = NULL; -+ char *volname = NULL; -+ glusterd_volinfo_t *volinfo = NULL; -+ uint64_t opt_hard_max = GLUSTERD_SNAPS_MAX_HARD_LIMIT; -+ uint64_t opt_max_soft = GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT; -+ int64_t effective_max_limit = 0; -+ int64_t soft_limit = 0; -+ int32_t snap_activate = _gf_false; - - this = THIS; - -@@ -8215,6 +8235,77 @@ glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret, - goto out; - } - -+ /* -+ * If activate_on_create was enabled, and we have reached this * -+ * section of the code, that means, that after successfully * -+ * creating the snapshot, we have also successfully started the * -+ * snapshot bricks on all nodes. So from originator node we can * -+ * send EVENT_SNAPSHOT_ACTIVATED event. * -+ * * -+ * Also check, if hard limit and soft limit is reached in case * -+ * of successfuly creating the snapshot, and generate the event * -+ */ -+ if (is_origin_glusterd (dict) == _gf_true) { -+ snap_activate = dict_get_str_boolean (priv->opts, -+ GLUSTERD_STORE_KEY_SNAP_ACTIVATE, -+ _gf_false); -+ -+ if (snap_activate == _gf_true) { -+ gf_event (EVENT_SNAPSHOT_ACTIVATED, "snapshot_name=%s;" -+ "snapshot_uuid=%s", snap->snapname, -+ uuid_utoa(snap->snap_id)); -+ } -+ -+ ret = dict_get_str (dict, "volname1", &volname); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_DICT_GET_FAILED, -+ "Failed to get volname."); -+ goto out; -+ } -+ -+ ret = glusterd_volinfo_find (volname, &volinfo); -+ if (ret) { -+ gf_msg (this->name, GF_LOG_ERROR, 0, -+ GD_MSG_VOL_NOT_FOUND, -+ "Failed to get volinfo."); -+ goto out; -+ } -+ -+ /* config values snap-max-hard-limit and snap-max-soft-limit are -+ * optional and hence we are not erroring out if values are not -+ * present -+ */ -+ gd_get_snap_conf_values_if_present (priv->opts, &opt_hard_max, -+ &opt_max_soft); -+ -+ if (volinfo->snap_max_hard_limit < opt_hard_max) -+ effective_max_limit = volinfo->snap_max_hard_limit; -+ else -+ effective_max_limit = opt_hard_max; -+ -+ /* -+ * Check for hard limit. If it is reached after taking * -+ * this snapshot, then generate event for the same. If * -+ * it is not reached, then check for the soft limit, * -+ * and generate event accordingly. * -+ */ -+ if (volinfo->snap_count >= effective_max_limit) { -+ gf_event (EVENT_SNAPSHOT_HARD_LIMIT_REACHED, -+ "volume_name=%s;volume_id=%s", -+ volname, -+ uuid_utoa(volinfo->volume_id)); -+ } else { -+ soft_limit = (opt_max_soft * effective_max_limit)/100; -+ if (volinfo->snap_count >= soft_limit) { -+ gf_event (EVENT_SNAPSHOT_SOFT_LIMIT_REACHED, -+ "volume_name=%s;volume_id=%s", -+ volname, -+ uuid_utoa(volinfo->volume_id)); -+ } -+ } -+ } -+ - /* "auto-delete" might not be set by user explicitly, - * in that case it's better to consider the default value. - * Hence not erroring out if Key is not found. --- -1.7.1 - diff --git a/SOURCES/0068-common-ha-enable-and-disable-selinux-gluster_use_exe.patch b/SOURCES/0068-common-ha-enable-and-disable-selinux-gluster_use_exe.patch new file mode 100644 index 0000000..f537ebb --- /dev/null +++ b/SOURCES/0068-common-ha-enable-and-disable-selinux-gluster_use_exe.patch @@ -0,0 +1,59 @@ +From c90038f9a3e01d07f1e797c613b0863a43e06d35 Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Mon, 17 Jul 2017 11:07:40 -0400 +Subject: [PATCH 68/74] common-ha: enable and disable selinux + gluster_use_execmem + +Starting in Fedora 26 and RHEL 7.4 there are new targeted policies in +selinux which include a tuneable to allow glusterd->ganesha-ha.sh->pcs +to access the pcs config, i.e. gluster-use-execmem. + +Note. rpm doesn't have a way to distinguish between RHEL 7.3 or 7.4 +or between 3.13.1-X and 3.13.1-Y so it can't be enabled for RHEL at +this time. + +/usr/sbin/semanage is in policycoreutils-python in RHEL (versus +policycoreutils-python-utils in Fedora.) + +Requires selinux-policy >= 3.13.1-160 in RHEL7. The corresponding +version in Fedora 26 seems to be selinux-policy-3.13.1-259 or so. (Maybe +earlier versions, but that's what was in F26 when I checked.) + +Change-Id: Ic474b3f7739ff5be1e99d94d00b55caae4ceb5a0 +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://review.gluster.org/17806 +Smoke: Gluster Build System +CentOS-regression: Gluster Build System +Reviewed-by: soumya k +Reviewed-by: Atin Mukherjee +--- + extras/ganesha/scripts/ganesha-ha.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index ce5ff20..0b7642d 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -984,6 +984,9 @@ main() + usage + exit 0 + fi ++ ++ semanage boolean -m gluster_use_execmem --on ++ + HA_CONFDIR=${1%/}; shift + local ha_conf=${HA_CONFDIR}/ganesha-ha.conf + local node="" +@@ -1129,6 +1132,9 @@ $HA_CONFDIR/ganesha-ha.conf + ;; + + esac ++ ++ semanage boolean -m gluster_use_execmem --off ++ + } + + main $* +-- +1.8.3.1 + diff --git a/SOURCES/0068-ganesha-glusterd-Correct-the-path-for-ganesha-conf-d.patch b/SOURCES/0068-ganesha-glusterd-Correct-the-path-for-ganesha-conf-d.patch deleted file mode 100644 index 1335566..0000000 --- a/SOURCES/0068-ganesha-glusterd-Correct-the-path-for-ganesha-conf-d.patch +++ /dev/null @@ -1,50 +0,0 @@ -From fd2b5cb2ba62aac2bf1c466074f233ec17168594 Mon Sep 17 00:00:00 2001 -From: Jiffin Tony Thottan -Date: Tue, 30 Aug 2016 18:36:51 +0530 -Subject: [PATCH 68/86] ganesha/glusterd : Correct the path for ganesha conf dir in Makefile - -The value for ganesha conf dir in Makefile.am is mistakenly entered as -following : -DCONFDIR=\"/$(runstatedir)/gluster/shared_storage/nfs-ganesha\" - -Here value for runstatedir is seems to "NULL" which results wrong path -for ganesha configuration directory - -Upstream reference : ->Change-Id: I0b7ebd8e2503de0cb79b601553c4405d0d1fd711 ->BUG: 1355956 ->Signed-off-by: Jiffin Tony Thottan ->Reviewed-on: http://review.gluster.org/15355 ->NetBSD-regression: NetBSD Build System ->Reviewed-by: soumya k ->Reviewed-by: Niels de Vos ->CentOS-regression: Gluster Build System ->Smoke: Gluster Build System ->Signed-off-by: Jiffin Tony Thottan - -Change-Id: I0b7ebd8e2503de0cb79b601553c4405d0d1fd711 -BUG: 1348949 -Signed-off-by: Jiffin Tony Thottan -Reviewed-on: https://code.engineering.redhat.com/gerrit/84840 -Reviewed-by: Soumya Koduri -Reviewed-by: Atin Mukherjee ---- - xlators/mgmt/glusterd/src/Makefile.am | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am -index faee862..33a1fc4 100644 ---- a/xlators/mgmt/glusterd/src/Makefile.am -+++ b/xlators/mgmt/glusterd/src/Makefile.am -@@ -48,7 +48,7 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ - -I$(CONTRIBDIR)/userspace-rcu \ - -DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\" \ -- -DCONFDIR=\"/$(runstatedir)/gluster/shared_storage/nfs-ganesha\" \ -+ -DCONFDIR=\"$(localstatedir)/run/gluster/shared_storage/nfs-ganesha\" \ - -DGANESHA_PREFIX=\"$(libexecdir)/ganesha\" \ - -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(XML_CPPFLAGS) - --- -1.7.1 - diff --git a/SOURCES/0069-events-dht-dht-cli-events.patch b/SOURCES/0069-events-dht-dht-cli-events.patch deleted file mode 100644 index 0fe918e..0000000 --- a/SOURCES/0069-events-dht-dht-cli-events.patch +++ /dev/null @@ -1,308 +0,0 @@ -From fc9748357b79e76fe1c60c9c458c5dde9a9684e3 Mon Sep 17 00:00:00 2001 -From: N Balachandran -Date: Fri, 16 Sep 2016 22:08:53 +0530 -Subject: [PATCH 69/86] events/dht: dht cli events - -Adding events for add/remove brick and rebalance -from the cli. - -upstream patch : http://review.gluster.org/15500 - -Change-Id: Ibb3cc307ba5825e5dd6ba3c46acf074e37f365d2 -BUG: 1361066 -Signed-off-by: N Balachandran -Reviewed-on: https://code.engineering.redhat.com/gerrit/84838 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - cli/src/cli-cmd-volume.c | 170 +++++++++++++++++++++++++++++++++++++++++++++- - events/eventskeygen.py | 22 ++++++ - 2 files changed, 190 insertions(+), 2 deletions(-) - -diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c -index 4f6caab..f2679d2 100644 ---- a/cli/src/cli-cmd-volume.c -+++ b/cli/src/cli-cmd-volume.c -@@ -613,6 +613,10 @@ cli_cmd_volume_defrag_cbk (struct cli_state *state, struct cli_cmd_word *word, - int sent = 0; - int parse_error = 0; - cli_local_t *local = NULL; -+#if (USE_EVENTS) -+ eventtypes_t event = EVENT_LAST; -+#endif -+ - #ifdef GF_SOLARIS_HOST_OS - cli_out ("Command not supported on Solaris"); - goto out; -@@ -642,6 +646,19 @@ out: - cli_cmd_sent_status_get (&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out ("Volume rebalance failed"); -+ } else { -+ -+#if (USE_EVENTS) -+ if (!(strcmp (words[wordcount-1], "start")) || -+ !(strcmp (words[wordcount-1], "force"))) { -+ event = EVENT_VOLUME_REBALANCE_START; -+ } else if (!strcmp (words[wordcount-1], "stop")) { -+ event = EVENT_VOLUME_REBALANCE_STOP; -+ } -+ -+ if (event != EVENT_LAST) -+ gf_event (event, "volume=%s", (char *)words[2]); -+#endif - } - - CLI_STACK_DESTROY (frame); -@@ -853,6 +870,115 @@ out: - - } - -+static -+int -+cli_event_remove_brick_str (dict_t *options, char **event_str, -+ eventtypes_t *event) -+{ -+ int ret = -1; -+ char *bricklist = NULL; -+ char *brick = NULL; -+ char *volname = NULL; -+ char key[256] = {0,}; -+ const char *eventstrformat = "volume=%s;bricks=%s"; -+ int32_t command = 0; -+ int32_t i = 1; -+ int32_t count = 0; -+ int32_t eventstrlen = 1; -+ char *tmp_ptr = NULL; -+ -+ if (!options || !event_str || !event) -+ goto out; -+ -+ ret = dict_get_str (options, "volname", &volname); -+ if (ret || !volname) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to fetch volname"); -+ ret = -1; -+ goto out; -+ } -+ /* Get the list of bricks for the event */ -+ ret = dict_get_int32 (options, "command", &command); -+ if (ret) { -+ gf_log ("cli", GF_LOG_ERROR, "Failed to fetch command"); -+ ret = -1; -+ goto out; -+ } -+ -+ switch (command) { -+ case GF_OP_CMD_START: -+ *event = EVENT_VOLUME_REMOVE_BRICK_START; -+ break; -+ case GF_OP_CMD_COMMIT: -+ *event = EVENT_VOLUME_REMOVE_BRICK_COMMIT; -+ break; -+ case GF_OP_CMD_COMMIT_FORCE: -+ *event = EVENT_VOLUME_REMOVE_BRICK_FORCE; -+ break; -+ case GF_OP_CMD_STOP: -+ *event = EVENT_VOLUME_REMOVE_BRICK_STOP; -+ break; -+ default: -+ *event = EVENT_LAST; -+ break; -+ } -+ -+ ret = -1; -+ -+ if (*event == EVENT_LAST) { -+ goto out; -+ } -+ -+ /* I could just get this from words[] but this is cleaner in case the -+ * format changes */ -+ while (i) { -+ snprintf (key, sizeof (key), "brick%d", i); -+ ret = dict_get_str (options, key, &brick); -+ if (ret) { -+ break; -+ } -+ eventstrlen += strlen (brick) + 1; -+ i++; -+ } -+ -+ count = --i; -+ -+ eventstrlen += 1; -+ -+ bricklist = GF_CALLOC (eventstrlen, sizeof (char), gf_common_mt_char); -+ if (!bricklist) { -+ goto out; -+ } -+ -+ tmp_ptr = bricklist; -+ -+ i = 1; -+ while (i <= count) { -+ snprintf (key, sizeof (key), "brick%d", i); -+ ret = dict_get_str (options, key, &brick); -+ if (ret) { -+ break; -+ } -+ snprintf (tmp_ptr, eventstrlen, "%s ", brick); -+ eventstrlen -= (strlen (brick) + 1); -+ tmp_ptr += (strlen (brick) + 1); -+ i++; -+ } -+ -+ if (!ret) { -+ gf_asprintf (event_str, eventstrformat, volname, -+ bricklist); -+ } else { -+ gf_asprintf (event_str, eventstrformat, volname, -+ ""); -+ } -+ -+ ret = 0; -+out: -+ GF_FREE (bricklist); -+ return ret; -+} -+ -+ - int - cli_cmd_volume_add_brick_cbk (struct cli_state *state, - struct cli_cmd_word *word, const char **words, -@@ -867,6 +993,12 @@ cli_cmd_volume_add_brick_cbk (struct cli_state *state, - gf_answer_t answer = GF_ANSWER_NO; - cli_local_t *local = NULL; - -+#if (USE_EVENTS) -+ char *event_str = NULL; -+ char *bricks = NULL; -+ const char *eventstrformat = "volume=%s;bricks=%s"; -+#endif -+ - const char *question = "Changing the 'stripe count' of the volume is " - "not a supported feature. In some cases it may result in data " - "loss on the volume. Also there may be issues with regular " -@@ -895,6 +1027,20 @@ cli_cmd_volume_add_brick_cbk (struct cli_state *state, - } - } - -+#if (USE_EVENTS) -+ /* Get the list of bricks for the event */ -+ -+ ret = dict_get_str (options, "bricks", &bricks); -+ -+ if (!ret) { -+ gf_asprintf (&event_str, eventstrformat, (char *)words[2], -+ &bricks[1] /*Skip leading space*/); -+ } else { -+ gf_asprintf (&event_str, eventstrformat, (char *)words[2], -+ ""); -+ } -+#endif -+ - if (state->mode & GLUSTER_MODE_WIGNORE) { - ret = dict_set_int32 (options, "force", _gf_true); - if (ret) { -@@ -917,10 +1063,14 @@ out: - cli_cmd_sent_status_get (&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out ("Volume add-brick failed"); -+ } else { -+#if (USE_EVENTS) -+ gf_event (EVENT_VOLUME_ADD_BRICK, event_str); -+ GF_FREE (event_str); -+#endif - } - - CLI_STACK_DESTROY (frame); -- - return ret; - } - -@@ -1792,7 +1942,11 @@ cli_cmd_volume_remove_brick_cbk (struct cli_state *state, - int need_question = 0; - cli_local_t *local = NULL; - char *volname = NULL; -- -+#if (USE_EVENTS) -+ eventtypes_t event = EVENT_LAST; -+ char *event_str = NULL; -+ int event_ret = -1; -+#endif - const char *question = "Removing brick(s) can result in data loss. " - "Do you want to Continue?"; - -@@ -1815,6 +1969,10 @@ cli_cmd_volume_remove_brick_cbk (struct cli_state *state, - goto out; - } - -+#if (USE_EVENTS) -+ event_ret = cli_event_remove_brick_str (options, &event_str, &event); -+#endif -+ - if (!strcmp (volname, GLUSTER_SHARED_STORAGE)) { - question = "Removing brick from the shared storage volume" - "(gluster_shared_storage), will affect features " -@@ -1846,10 +2004,18 @@ out: - cli_cmd_sent_status_get (&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out ("Volume remove-brick failed"); -+ } else { -+#if (USE_EVENTS) -+ if (!event_ret) { -+ gf_event (event, event_str); -+ GF_FREE (event_str); -+ } -+#endif - } - - CLI_STACK_DESTROY (frame); - -+ - return ret; - - } -diff --git a/events/eventskeygen.py b/events/eventskeygen.py -index 4f7ec44..7fdf6a8 100644 ---- a/events/eventskeygen.py -+++ b/events/eventskeygen.py -@@ -151,6 +151,7 @@ keys = ( - "EVENT_AFR_SUBVOLS_DOWN", - "EVENT_AFR_SPLIT_BRAIN", - -+ #tier events - "EVENT_TIER_ATTACH", - "EVENT_TIER_ATTACH_FORCE", - "EVENT_TIER_DETACH_START", -@@ -163,6 +164,27 @@ keys = ( - "EVENT_TIER_WATERMARK_DROPPED_TO_MID", - "EVENT_TIER_WATERMARK_RAISED_TO_MID", - "EVENT_TIER_WATERMARK_DROPPED_TO_LOW", -+ -+ #dht events -+ #add/remove brick events -+ "EVENT_VOLUME_ADD_BRICK", -+ "EVENT_VOLUME_ADD_BRICK_FAILED", -+ "EVENT_VOLUME_REMOVE_BRICK_START", -+ "EVENT_VOLUME_REMOVE_BRICK_START_FAILED", -+ "EVENT_VOLUME_REMOVE_BRICK_COMMIT", -+ "EVENT_VOLUME_REMOVE_BRICK_COMMIT_FAILED", -+ "EVENT_VOLUME_REMOVE_BRICK_STOP", -+ "EVENT_VOLUME_REMOVE_BRICK_STOP_FAILED", -+ "EVENT_VOLUME_REMOVE_BRICK_FORCE", -+ "EVENT_VOLUME_REMOVE_BRICK_FORCE_FAILED", -+ "EVENT_VOLUME_REMOVE_BRICK_FAILED", -+ -+ #rebalance events -+ "EVENT_VOLUME_REBALANCE_START", -+ "EVENT_VOLUME_REBALANCE_STOP", -+ "EVENT_VOLUME_REBALANCE_FAILED", -+ "EVENT_VOLUME_REBALANCE_COMPLETE", -+ - ) - - LAST_EVENT = "EVENT_LAST" --- -1.7.1 - diff --git a/SOURCES/0069-ganesha-ha-don-t-set-SELinux-booleans-if-SELinux-is-.patch b/SOURCES/0069-ganesha-ha-don-t-set-SELinux-booleans-if-SELinux-is-.patch new file mode 100644 index 0000000..912f9d1 --- /dev/null +++ b/SOURCES/0069-ganesha-ha-don-t-set-SELinux-booleans-if-SELinux-is-.patch @@ -0,0 +1,53 @@ +From 9b299dff3811a48978a76cbdd5f4f66f0cf68d78 Mon Sep 17 00:00:00 2001 +From: Ambarish +Date: Tue, 12 Sep 2017 18:34:29 +0530 +Subject: [PATCH 69/74] ganesha-ha: don't set SELinux booleans if SELinux is + disabled + +semanage commands inside ganesha-ha.sh script will fail if selinux is +Disabled. This patch introduces a check if selinux is enabled or not, +and subsequently run semange commands only on selinux enabled systems. + +Change-Id: Ibee61cbb1d51a73e6c326b49bac5c7ce06feb310 +Signed-off-by: Ambarish +Reviewed-on: https://review.gluster.org/18264 +Reviewed-by: Niels de Vos +Smoke: Gluster Build System +Reviewed-by: Kaleb KEITHLEY +Reviewed-by: jiffin tony Thottan +Reviewed-by: Daniel Gryniewicz +CentOS-regression: Gluster Build System +--- + extras/ganesha/scripts/ganesha-ha.sh | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index 0b7642d..3a18a1a 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -985,7 +985,9 @@ main() + exit 0 + fi + +- semanage boolean -m gluster_use_execmem --on ++ if (selinuxenabled) ;then ++ semanage boolean -m gluster_use_execmem --on ++ fi + + HA_CONFDIR=${1%/}; shift + local ha_conf=${HA_CONFDIR}/ganesha-ha.conf +@@ -1133,8 +1135,9 @@ $HA_CONFDIR/ganesha-ha.conf + + esac + +- semanage boolean -m gluster_use_execmem --off +- ++ if (selinuxenabled) ;then ++ semanage boolean -m gluster_use_execmem --off ++ fi + } + + main $* +-- +1.8.3.1 + diff --git a/SOURCES/0070-build-remove-ganesha-dependency-on-selinux-policy.patch b/SOURCES/0070-build-remove-ganesha-dependency-on-selinux-policy.patch new file mode 100644 index 0000000..f55f1d7 --- /dev/null +++ b/SOURCES/0070-build-remove-ganesha-dependency-on-selinux-policy.patch @@ -0,0 +1,41 @@ +From 1d9693e542fb63ad985a6d6647c0c613f2e677b6 Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Fri, 23 Jun 2017 20:43:16 +0530 +Subject: [PATCH 70/74] build: remove ganesha dependency on selinux-policy + +Problem: +Puddle creation fails with unresolved dependencies + unresolved deps: +*** selinux-policy >= 0:3.13.1-160 + +Solution: +We know a priori about the version at RHEL 7.4 is already the desired +version. So removing this explicit dependency *should* not be a gluster +test blocker. + +Label: DOWNSTREAM ONLY + +Change-Id: Id53ac0e41adc14704932787ee0dd3143e6615aaf +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/109945 +Reviewed-by: Kaleb Keithley +Signed-off-by: Jiffin Tony Thottan +--- + glusterfs.spec.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index cbc77c3..05eff07 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -411,6 +411,7 @@ Requires: pcs, dbus + Requires: cman, pacemaker, corosync + %endif + %if ( 0%{?fedora} && 0%{?fedora} > 25 ) ++Requires: selinux-policy >= 3.13.1-160 + Requires(post): policycoreutils-python-utils + Requires(postun): policycoreutils-python-utils + %endif +-- +1.8.3.1 + diff --git a/SOURCES/0070-dht-events-Added-rebalance-events.patch b/SOURCES/0070-dht-events-Added-rebalance-events.patch deleted file mode 100644 index 740ddc1..0000000 --- a/SOURCES/0070-dht-events-Added-rebalance-events.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 5f467f9f83c0fe81b0f54bcd23ad1f6aa86cd548 Mon Sep 17 00:00:00 2001 -From: N Balachandran -Date: Fri, 16 Sep 2016 22:23:51 +0530 -Subject: [PATCH 70/86] dht/events: Added rebalance events - -The rebalance process will now send an event when it is -complete. -Also fixed a problem where the run-time was not always -set causing spurious rebalance failure events to be sent. - -> Change-Id: Ib445171c78c9560940022bca20c887d31a9bb1ca -> BUG: 1371874 -> Signed-off-by: N Balachandran -> Reviewed-on: http://review.gluster.org/15501 -> Reviewed-by: Raghavendra G -> Reviewed-by: Shyamsundar Ranganathan - ->Reviewed-on: http://review.gluster.org/15520 ->Smoke: Gluster Build System ->CentOS-regression: Gluster Build System ->NetBSD-regression: NetBSD Build System ->Reviewed-by: Atin Mukherjee - -Change-Id: Ia24038c04548a98aac899df10414585b988caa76 -BUG: 1361066 -Signed-off-by: N Balachandran -Reviewed-on: https://code.engineering.redhat.com/gerrit/84875 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - xlators/cluster/dht/src/dht-rebalance.c | 56 +++++++++++++++++++++++++++--- - 1 files changed, 50 insertions(+), 6 deletions(-) - -diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c -index 58b0d74..194fbb0 100644 ---- a/xlators/cluster/dht/src/dht-rebalance.c -+++ b/xlators/cluster/dht/src/dht-rebalance.c -@@ -74,6 +74,49 @@ dht_set_global_defrag_error (gf_defrag_info_t *defrag, int ret) - } - - static int -+dht_send_rebalance_event (xlator_t *this, gf_defrag_status_t status) -+{ -+ int ret = -1; -+ char *volname = NULL; -+ char *tmpstr = NULL; -+ -+ eventtypes_t event = EVENT_LAST; -+ -+ switch (status) { -+ case GF_DEFRAG_STATUS_COMPLETE: -+ event = EVENT_VOLUME_REBALANCE_COMPLETE; -+ break; -+ case GF_DEFRAG_STATUS_FAILED: -+ event = EVENT_VOLUME_REBALANCE_FAILED; -+ break; -+ case GF_DEFRAG_STATUS_STOPPED: -+ event = EVENT_VOLUME_REBALANCE_STOP; -+ break; -+ default: -+ break; -+ -+ } -+ -+ tmpstr = gf_strdup (this->name); -+ if (tmpstr) { -+ volname = strtok(tmpstr, "-dht"); -+ } -+ -+ if (!volname) -+ volname = this->name; -+ -+ if (event != EVENT_LAST) { -+ ret = gf_event (event, "volume=%s", volname); -+ } -+ GF_FREE (tmpstr); -+ return ret; -+} -+ -+ -+ -+ -+ -+static int - dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count, - int32_t size, off_t offset, struct iobref *iobref) - { -@@ -3823,6 +3866,8 @@ out: - defrag->defrag_status = GF_DEFRAG_STATUS_COMPLETE; - } - -+ dht_send_rebalance_event (this, defrag->defrag_status); -+ - LOCK (&defrag->lock); - { - status = dict_new (); -@@ -3973,12 +4018,11 @@ gf_defrag_status_get (gf_defrag_info_t *defrag, dict_t *dict) - if (ret) - gf_log (THIS->name, GF_LOG_WARNING, - "failed to set status"); -- if (elapsed) { -- ret = dict_set_double (dict, "run-time", elapsed); -- if (ret) -- gf_log (THIS->name, GF_LOG_WARNING, -- "failed to set run-time"); -- } -+ -+ ret = dict_set_double (dict, "run-time", elapsed); -+ if (ret) -+ gf_log (THIS->name, GF_LOG_WARNING, -+ "failed to set run-time"); - - ret = dict_set_uint64 (dict, "failures", failures); - if (ret) --- -1.7.1 - diff --git a/SOURCES/0071-common-ha-enable-pacemaker-at-end-of-setup.patch b/SOURCES/0071-common-ha-enable-pacemaker-at-end-of-setup.patch new file mode 100644 index 0000000..9725c05 --- /dev/null +++ b/SOURCES/0071-common-ha-enable-pacemaker-at-end-of-setup.patch @@ -0,0 +1,62 @@ +From 50b87b03d6460b7c5d733924f611efdac134f37d Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Wed, 7 Jun 2017 08:15:48 -0400 +Subject: [PATCH 71/74] common-ha: enable pacemaker at end of setup + +Label: DOWNSTREAM ONLY +Change-Id: I3ccd59b67ed364bfc5d27e88321ab5b9f8d471fd +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://code.engineering.redhat.com/gerrit/108431 +Reviewed-by: Soumya Koduri +--- + extras/ganesha/scripts/ganesha-ha.sh | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index 3a18a1a..b252818 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -787,6 +787,22 @@ setup_state_volume() + } + + ++enable_pacemaker() ++{ ++ while [[ ${1} ]]; do ++ if [ "${SERVICE_MAN}" == "/usr/bin/systemctl" ]; then ++${SECRET_PEM} root@${1} ${SERVICE_MAN} enable pacemaker" ++ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ++${SECRET_PEM} root@${1} "${SERVICE_MAN} enable pacemaker" ++ else ++ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ ++${SECRET_PEM} root@${1} "${SERVICE_MAN} pacemaker enable" ++ fi ++ shift ++ done ++} ++ ++ + addnode_state_volume() + { + local newnode=${1}; shift +@@ -1011,6 +1027,8 @@ main() + + if [ "X${HA_NUM_SERVERS}X" != "X1X" ]; then + ++ determine_service_manager ++ + setup_cluster ${HA_NAME} ${HA_NUM_SERVERS} "${HA_SERVERS}" + + setup_create_resources ${HA_SERVERS} +@@ -1019,6 +1037,8 @@ main() + + setup_state_volume ${HA_SERVERS} + ++ enable_pacemaker ${HA_SERVERS} ++ + else + + logger "insufficient servers for HA, aborting" +-- +1.8.3.1 + diff --git a/SOURCES/0071-geo-rep-Use-configured-log_level-for-libgfchangelog-.patch b/SOURCES/0071-geo-rep-Use-configured-log_level-for-libgfchangelog-.patch deleted file mode 100644 index fe67521..0000000 --- a/SOURCES/0071-geo-rep-Use-configured-log_level-for-libgfchangelog-.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 17976f33033f81429754f14c10b8078f7a24ed8b Mon Sep 17 00:00:00 2001 -From: Aravinda VK -Date: Wed, 3 Aug 2016 17:52:20 +0530 -Subject: [PATCH 71/86] geo-rep: Use configured log_level for libgfchangelog logs - -libgfchangelog was not respecting the log_level configured -in Geo-replication. With this patch Libgfchangelog log level -can be configured using `config changelog_log_level TRACE`. -Default Changelog log level is INFO - -> Reviewed-on: http://review.gluster.org/15078 -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Kotresh HR - -BUG: 1363729 -Change-Id: Ida714931129f6a1331b9d0815da77efcb2b898e3 -Signed-off-by: Aravinda VK -Reviewed-on: https://code.engineering.redhat.com/gerrit/84837 -Reviewed-by: Atin Mukherjee ---- - geo-replication/syncdaemon/gsyncd.py | 1 + - geo-replication/syncdaemon/master.py | 1 - - geo-replication/syncdaemon/resource.py | 4 +++- - geo-replication/syncdaemon/syncdutils.py | 17 +++++++++++++++++ - 4 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py -index c2699a1..b459abc 100644 ---- a/geo-replication/syncdaemon/gsyncd.py -+++ b/geo-replication/syncdaemon/gsyncd.py -@@ -244,6 +244,7 @@ def main_i(): - default=os.devnull, type=str, action='callback', - callback=store_abs) - op.add_option('--gluster-log-level', metavar='LVL') -+ op.add_option('--changelog-log-level', metavar='LVL', default="INFO") - op.add_option('--gluster-params', metavar='PRMS', default='') - op.add_option( - '--glusterd-uuid', metavar='UUID', type=str, default='', -diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py -index 80c4d9d..796b980 100644 ---- a/geo-replication/syncdaemon/master.py -+++ b/geo-replication/syncdaemon/master.py -@@ -673,7 +673,6 @@ class GMasterChangelogMixin(GMasterCommon): - # maximum retries per changelog before giving up - MAX_RETRIES = 10 - -- CHANGELOG_LOG_LEVEL = 9 - CHANGELOG_CONN_RETRIES = 5 - - def archive_and_purge_changelogs(self, changelogs): -diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py -index ed0e7ef..70d420e 100644 ---- a/geo-replication/syncdaemon/resource.py -+++ b/geo-replication/syncdaemon/resource.py -@@ -37,6 +37,7 @@ from syncdutils import GsyncdError, select, privileged, boolify, funcode - from syncdutils import umask, entry2pb, gauxpfx, errno_wrap, lstat - from syncdutils import NoPurgeTimeAvailable, PartialHistoryAvailable - from syncdutils import ChangelogException, ChangelogHistoryNotAvailable -+from syncdutils import get_changelog_log_level - from syncdutils import CHANGELOG_AGENT_CLIENT_VERSION - from gsyncdstatus import GeorepStatus - -@@ -1481,7 +1482,8 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote): - changelog_agent.init() - changelog_agent.register(gconf.local_path, - workdir, gconf.changelog_log_file, -- g2.CHANGELOG_LOG_LEVEL, -+ get_changelog_log_level( -+ gconf.changelog_log_level), - g2.CHANGELOG_CONN_RETRIES) - - register_time = int(time.time()) -diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py -index 40eff05..987e1bf 100644 ---- a/geo-replication/syncdaemon/syncdutils.py -+++ b/geo-replication/syncdaemon/syncdutils.py -@@ -506,3 +506,20 @@ class ChangelogHistoryNotAvailable(Exception): - - class ChangelogException(OSError): - pass -+ -+ -+class GlusterLogLevel(object): -+ NONE = 0 -+ EMERG = 1 -+ ALERT = 2 -+ CRITICAL = 3 -+ ERROR = 4 -+ WARNING = 5 -+ NOTICE = 6 -+ INFO = 7 -+ DEBUG = 8 -+ TRACE = 9 -+ -+ -+def get_changelog_log_level(lvl): -+ return getattr(GlusterLogLevel, lvl, GlusterLogLevel.INFO) --- -1.7.1 - diff --git a/SOURCES/0072-cluster-dht-heal-root-permission-post-add-brick.patch b/SOURCES/0072-cluster-dht-heal-root-permission-post-add-brick.patch deleted file mode 100644 index bb97abe..0000000 --- a/SOURCES/0072-cluster-dht-heal-root-permission-post-add-brick.patch +++ /dev/null @@ -1,195 +0,0 @@ -From a2cb732a71d341edb65e4cdbf103a3fec35e8589 Mon Sep 17 00:00:00 2001 -From: Susant Palai -Date: Wed, 17 Aug 2016 15:10:04 +0530 -Subject: [PATCH 72/86] cluster/dht: heal root permission post add-brick - -Post add-brick event the new brick will have permission of 755 -by default. If the root directory permission was other than 755, -that does not get healed to the new brick leading to permission -errors/inconsistencies. - -For choosing source of attr heal we can trust the subvols which -have layouts with latest ctime(as part of missing directory heal, -we heal the proper attr). In case none of the subvols have layout, -return ESTALE to retrigger a fresh lookup. - -Note: This patch heals the permission of the root directories only. -Since, permission healing of directory is not straight forward and -required intrusive fix, those are not addressed here. - -> Reviewed-on: http://review.gluster.org/15195 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> NetBSD-regression: NetBSD Build System ->Reviewed-by: Raghavendra G - ->Reviewed-on: http://review.gluster.org/15465 ->Smoke: Gluster Build System ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Reviewed-by: Raghavendra G - -Change-Id: If894e3895d070d46b62d2452e52c1eaafcf56c29 -BUG: 1294035 -Signed-off-by: Susant Palai -Reviewed-on: https://code.engineering.redhat.com/gerrit/84877 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - tests/bugs/distribute/bug-1368012.t | 50 ++++++++++++++++++++++++++++++++ - xlators/cluster/dht/src/dht-common.c | 32 +++++++++++++++++++- - xlators/cluster/dht/src/dht-selfheal.c | 16 +++++++-- - 3 files changed, 93 insertions(+), 5 deletions(-) - create mode 100644 tests/bugs/distribute/bug-1368012.t - -diff --git a/tests/bugs/distribute/bug-1368012.t b/tests/bugs/distribute/bug-1368012.t -new file mode 100644 -index 0000000..f89314b ---- /dev/null -+++ b/tests/bugs/distribute/bug-1368012.t -@@ -0,0 +1,50 @@ -+#!/bin/bash -+ -+. $(dirname $0)/../../include.rc -+. $(dirname $0)/../../volume.rc -+ -+cleanup; -+ -+function get_permission { -+ stat -c "%A" $1 -+} -+ -+## Start glusterd -+TEST glusterd; -+TEST pidof glusterd; -+TEST $CLI volume info; -+ -+## Lets create volume -+TEST $CLI volume create $V0 $H0:/${V0}{1,2}; -+ -+## Verify volume is created -+EXPECT "$V0" volinfo_field $V0 'Volume Name'; -+EXPECT 'Created' volinfo_field $V0 'Status'; -+## Start volume and verify -+TEST $CLI volume start $V0; -+TEST $CLI volume set $V0 performance.stat-prefetch off -+EXPECT 'Started' volinfo_field $V0 'Status'; -+TEST glusterfs -s $H0 --volfile-id=$V0 $M0 -+ -+##Test case: Add-brick -+#------------------------------------------------------------ -+#change permission of both root -+TEST chmod 444 $M0 -+ -+#store permission for comparision -+TEST permission_root=`stat -c "%A" $M0` -+TEST echo $permission_root -+#Add-brick -+TEST $CLI volume add-brick $V0 $H0:/${V0}3 -+ -+#Allow one lookup to happen -+TEST pushd $M0 -+TEST ls -+#Generate another lookup -+echo 3 > /proc/sys/vm/drop_caches -+TEST ls -+#check root permission -+EXPECT_WITHIN "5" $permission_root get_permission $M0 -+#check permission on the new-brick -+EXPECT $permission_root get_permission /${V0}3 -+cleanup -diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c -index 5fd0a16..2eb44a1 100644 ---- a/xlators/cluster/dht/src/dht-common.c -+++ b/xlators/cluster/dht/src/dht-common.c -@@ -735,6 +735,27 @@ out: - return ret; - } - -+int static -+is_permission_different (ia_prot_t *prot1, ia_prot_t *prot2) -+{ -+ if ((prot1->owner.read != prot2->owner.read) || -+ (prot1->owner.write != prot2->owner.write) || -+ (prot1->owner.exec != prot2->owner.exec) || -+ (prot1->group.read != prot2->group.read) || -+ (prot1->group.write != prot2->group.write) || -+ (prot1->group.exec != prot2->group.exec) || -+ (prot1->other.read != prot2->other.read) || -+ (prot1->other.write != prot2->other.write) || -+ (prot1->other.exec != prot2->other.exec) || -+ (prot1->suid != prot2->suid) || -+ (prot1->sgid != prot2->sgid) || -+ (prot1->sticky != prot2->sticky)) { -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ - int - dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, -@@ -856,14 +877,21 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - local->stbuf.ia_ctime_nsec, - stbuf->ia_ctime, - stbuf->ia_ctime_nsec)) { -+ /* Choose source */ - local->prebuf.ia_gid = stbuf->ia_gid; - local->prebuf.ia_uid = stbuf->ia_uid; -+ -+ if (__is_root_gfid (stbuf->ia_gfid)) -+ local->prebuf.ia_prot = stbuf->ia_prot; - } - } - if (local->stbuf.ia_type != IA_INVAL) - { - if ((local->stbuf.ia_gid != stbuf->ia_gid) || -- (local->stbuf.ia_uid != stbuf->ia_uid)) { -+ (local->stbuf.ia_uid != stbuf->ia_uid) || -+ (__is_root_gfid (stbuf->ia_gfid) && -+ is_permission_different (&local->stbuf.ia_prot, -+ &stbuf->ia_prot))) { - local->need_selfheal = 1; - } - } -@@ -928,6 +956,8 @@ out: - gf_uuid_copy (local->gfid, local->stbuf.ia_gfid); - local->stbuf.ia_gid = local->prebuf.ia_gid; - local->stbuf.ia_uid = local->prebuf.ia_uid; -+ if (__is_root_gfid(local->stbuf.ia_gfid)) -+ local->stbuf.ia_prot = local->prebuf.ia_prot; - copy = create_frame (this, this->ctx->pool); - if (copy) { - copy_local = dht_local_init (copy, &local->loc, -diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c -index 520a3f3..f43a235 100644 ---- a/xlators/cluster/dht/src/dht-selfheal.c -+++ b/xlators/cluster/dht/src/dht-selfheal.c -@@ -2240,11 +2240,19 @@ dht_dir_attr_heal (void *data) - - for (i = 0; i < call_cnt; i++) { - subvol = conf->subvolumes[i]; -- if (!subvol || (subvol == dht_first_up_subvol (this))) -+ if (!subvol) - continue; -- ret = syncop_setattr (subvol, &local->loc, &local->stbuf, -- (GF_SET_ATTR_UID | GF_SET_ATTR_GID), -- NULL, NULL, NULL, NULL); -+ -+ if (__is_root_gfid (local->stbuf.ia_gfid)) { -+ ret = syncop_setattr (subvol, &local->loc, &local->stbuf, -+ (GF_SET_ATTR_UID | GF_SET_ATTR_GID | GF_SET_ATTR_MODE), -+ NULL, NULL, NULL, NULL); -+ } else { -+ ret = syncop_setattr (subvol, &local->loc, &local->stbuf, -+ (GF_SET_ATTR_UID | GF_SET_ATTR_GID), -+ NULL, NULL, NULL, NULL); -+ } -+ - if (ret) { - gf_uuid_unparse(local->loc.gfid, gfid); - --- -1.7.1 - diff --git a/SOURCES/0072-common-ha-Fix-an-incorrect-syntax-during-setup.patch b/SOURCES/0072-common-ha-Fix-an-incorrect-syntax-during-setup.patch new file mode 100644 index 0000000..54d8d63 --- /dev/null +++ b/SOURCES/0072-common-ha-Fix-an-incorrect-syntax-during-setup.patch @@ -0,0 +1,39 @@ +From eeaf040d3231c30d6d559a70c5e8ae36098d3a9a Mon Sep 17 00:00:00 2001 +From: Soumya Koduri +Date: Wed, 14 Jun 2017 15:20:22 +0530 +Subject: [PATCH 72/74] common-ha: Fix an incorrect syntax during setup + +There was an invalid line introduced as part of +https://code.engineering.redhat.com/gerrit/#/c/108431/ + +Detected by rpmdiff - + https://errata.devel.redhat.com/rpmdiff/show/175336?result_id=4796901 + +This change is to fix the same. + +Label: DOWNSTREAM ONLY + +Change-Id: I55cdd7d866cb175fb620dbbd2d02c36eab291a74 +Signed-off-by: Soumya Koduri +Reviewed-on: https://code.engineering.redhat.com/gerrit/109017 +Reviewed-by: Kaleb Keithley +Tested-by: Kaleb Keithley +--- + extras/ganesha/scripts/ganesha-ha.sh | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index b252818..623fb64 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -791,7 +791,6 @@ enable_pacemaker() + { + while [[ ${1} ]]; do + if [ "${SERVICE_MAN}" == "/usr/bin/systemctl" ]; then +-${SECRET_PEM} root@${1} ${SERVICE_MAN} enable pacemaker" + ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \ + ${SECRET_PEM} root@${1} "${SERVICE_MAN} enable pacemaker" + else +-- +1.8.3.1 + diff --git a/SOURCES/0073-Fix-build-issues-related-to-nfs-ganesha-package.patch b/SOURCES/0073-Fix-build-issues-related-to-nfs-ganesha-package.patch new file mode 100644 index 0000000..d9f3c9a --- /dev/null +++ b/SOURCES/0073-Fix-build-issues-related-to-nfs-ganesha-package.patch @@ -0,0 +1,103 @@ +From 77c5fda269bffe16d8564a5d26ed838ad9b6fcea Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Tue, 14 Nov 2017 12:43:29 +0530 +Subject: [PATCH 73/74] Fix build issues related to nfs-ganesha package + +Signed-off-by: Jiffin Tony Thottan +--- + glusterfs.spec.in | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 05eff07..b6ba91c 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -822,9 +822,6 @@ install -D -p -m 0644 extras/glusterfs-logrotate \ + # ganesha ghosts + mkdir -p %{buildroot}%{_sysconfdir}/ganesha + touch %{buildroot}%{_sysconfdir}/ganesha/ganesha-ha.conf +-mkdir -p %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/exports +-touch %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha.conf +-touch %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha-ha.conf + + %if ( 0%{!?_without_georeplication:1} ) + mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/geo-replication +@@ -888,11 +885,13 @@ modprobe fuse + exit 0 + %endif + ++%if ( 0%{?_build_server} ) + %if ( 0%{?fedora} && 0%{?fedora} > 25 ) + %post ganesha + semanage boolean -m ganesha_use_fusefs --on + exit 0 + %endif ++%endif + + %if ( 0%{?_build_server} ) + %if ( 0%{!?_without_georeplication:1} ) +@@ -1016,11 +1015,13 @@ fi + %postun api + /sbin/ldconfig + ++%if ( 0%{?_build_server} ) + %if ( 0%{?fedora} && 0%{?fedora} > 25 ) + %postun ganesha + semanage boolean -m ganesha_use_fusefs --off + exit 0 + %endif ++%endif + + %postun libs + /sbin/ldconfig +@@ -1037,20 +1038,24 @@ exit 0 + ##----------------------------------------------------------------------------- + ## All %%trigger should be placed here and keep them sorted + ## ++%if ( 0%{?_build_server} ) + %if ( 0%{?fedora} && 0%{?fedora} > 25 ) + %trigger ganesha -- selinux-policy-targeted + semanage boolean -m ganesha_use_fusefs --on + exit 0 + %endif ++%endif + + ##----------------------------------------------------------------------------- + ## All %%triggerun should be placed here and keep them sorted + ## ++%if ( 0%{?_build_server} ) + %if ( 0%{?fedora} && 0%{?fedora} > 25 ) + %triggerun ganesha -- selinux-policy-targeted + semanage boolean -m ganesha_use_fusefs --off + exit 0 + %endif ++%endif + + ##----------------------------------------------------------------------------- + ## All %%files should be placed here and keep them grouped +@@ -1074,6 +1079,11 @@ exit 0 + %if ( ! 0%{?_build_server} ) + # exclude ganesha files + %exclude %{_prefix}/lib/ocf/* ++%exclude %{_libexecdir}/ganesha/* ++%exclude %{_prefix}/lib/ocf/resource.d/heartbeat/* ++%exclude %{_sysconfdir}/ganesha/ganesha-ha.conf.sample ++%exclude %{_sysconfdir}/ganesha/ganesha-ha.conf ++ + # exclude incrementalapi + %exclude %{_libexecdir}/glusterfs/* + %exclude %{_sbindir}/gfind_missing_files +@@ -1323,10 +1333,6 @@ exit 0 + %{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh + %{_sysconfdir}/ganesha/ganesha-ha.conf.sample + %ghost %config(noreplace) %{_sysconfdir}/ganesha/ganesha-ha.conf +-%ghost %dir %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha +-%ghost %dir %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/exports +-%ghost %config(noreplace) %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha.conf +-%ghost %config(noreplace) %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha-ha.conf + %endif + + %if ( 0%{?_build_server} ) +-- +1.8.3.1 + diff --git a/SOURCES/0073-geo-rep-add-geo-rep-events-for-server-side-changes.patch b/SOURCES/0073-geo-rep-add-geo-rep-events-for-server-side-changes.patch deleted file mode 100644 index 96c8f8c..0000000 --- a/SOURCES/0073-geo-rep-add-geo-rep-events-for-server-side-changes.patch +++ /dev/null @@ -1,306 +0,0 @@ -From dc52f3950738c07b9b4e044346266d5f3efee5e2 Mon Sep 17 00:00:00 2001 -From: Saravanakumar Arumugam -Date: Wed, 24 Aug 2016 15:19:53 +0530 -Subject: [PATCH 73/79] geo-rep: add geo-rep events for server side changes - -Event Type defined in #15351 to avoid merge conflicts - -Add geo-rep events applicable to changes in -geo-rep session in the server side. - -> Reviewed-on: http://review.gluster.org/15328 -> Tested-by: Aravinda VK -> Smoke: Gluster Build System -> NetBSD-regression: NetBSD Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Aravinda VK - -Change-Id: Ia66574d2abccad7fce6a96667efbc7c6c8903fc6 -BUG: 1361118 -Signed-off-by: Saravanakumar Arumugam -Reviewed-on: https://code.engineering.redhat.com/gerrit/84879 -Tested-by: Aravinda Vishwanathapura Krishna Murthy -Reviewed-by: Atin Mukherjee ---- - configure.ac | 2 +- - geo-replication/syncdaemon/Makefile.am | 2 +- - geo-replication/syncdaemon/conf.py.in | 14 +++++++ - .../{configinterface.py.in => configinterface.py} | 17 ++++---- - geo-replication/syncdaemon/monitor.py | 41 ++++++++++++-------- - geo-replication/syncdaemon/syncdutils.py | 9 ++++ - 7 files changed, 60 insertions(+), 27 deletions(-) - create mode 100644 geo-replication/syncdaemon/conf.py.in - rename geo-replication/syncdaemon/{configinterface.py.in => configinterface.py} (95%) - -diff --git a/configure.ac b/configure.ac -index 011cf14..e4bf48e 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -42,8 +42,8 @@ AC_CONFIG_FILES([Makefile - geo-replication/src/peer_gsec_create - geo-replication/src/peer_mountbroker - extras/peer_add_secret_pub -- geo-replication/syncdaemon/configinterface.py - extras/snap_scheduler/conf.py -+ geo-replication/syncdaemon/conf.py - glusterfsd/Makefile - glusterfsd/src/Makefile - rpc/Makefile -diff --git a/geo-replication/syncdaemon/Makefile.am b/geo-replication/syncdaemon/Makefile.am -index ed0f5e4..7cdaf45 100644 ---- a/geo-replication/syncdaemon/Makefile.am -+++ b/geo-replication/syncdaemon/Makefile.am -@@ -3,6 +3,6 @@ syncdaemondir = $(libexecdir)/glusterfs/python/syncdaemon - syncdaemon_PYTHON = gconf.py gsyncd.py __init__.py master.py README.md repce.py \ - resource.py configinterface.py syncdutils.py monitor.py libcxattr.py \ - $(top_builddir)/contrib/ipaddr-py/ipaddr.py libgfchangelog.py changelogagent.py \ -- gsyncdstatus.py -+ gsyncdstatus.py conf.py - - CLEANFILES = -diff --git a/geo-replication/syncdaemon/conf.py.in b/geo-replication/syncdaemon/conf.py.in -new file mode 100644 -index 0000000..8807278 ---- /dev/null -+++ b/geo-replication/syncdaemon/conf.py.in -@@ -0,0 +1,14 @@ -+# -+# Copyright (c) 2016 Red Hat, Inc. -+# This file is part of GlusterFS. -+ -+# This file is licensed to you under your choice of the GNU Lesser -+# General Public License, version 3 or any later version (LGPLv3 or -+# later), or the GNU General Public License, version 2 (GPLv2), in all -+# cases as published by the Free Software Foundation. -+# -+ -+GLUSTERFS_LIBEXECDIR = '@GLUSTERFS_LIBEXECDIR@' -+GLUSTERD_WORKDIR = "@GLUSTERD_WORKDIR@" -+ -+LOCALSTATEDIR = "@localstatedir@" -diff --git a/geo-replication/syncdaemon/configinterface.py.in b/geo-replication/syncdaemon/configinterface.py -similarity index 95% -rename from geo-replication/syncdaemon/configinterface.py.in -rename to geo-replication/syncdaemon/configinterface.py -index e1cf007..adcefb8 100644 ---- a/geo-replication/syncdaemon/configinterface.py.in -+++ b/geo-replication/syncdaemon/configinterface.py -@@ -23,6 +23,7 @@ import tempfile - import shutil - - from syncdutils import escape, unescape, norm, update_file, GsyncdError -+from conf import GLUSTERD_WORKDIR, LOCALSTATEDIR - - SECT_ORD = '__section_order__' - SECT_META = '__meta__' -@@ -30,14 +31,14 @@ config_version = 2.0 - - re_type = type(re.compile('')) - --TMPL_CONFIG_FILE = "@GLUSTERD_WORKDIR@/geo-replication/gsyncd_template.conf" -+TMPL_CONFIG_FILE = GLUSTERD_WORKDIR + "/geo-replication/gsyncd_template.conf" - - # (SECTION, OPTION, OLD VALUE, NEW VALUE) - CONFIGS = ( - ("peersrx . .", - "georep_session_working_dir", - "", -- "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" -+ GLUSTERD_WORKDIR + "/geo-replication/${mastervol}_${remotehost}_" - "${slavevol}/"), - ("peersrx .", - "gluster_params", -@@ -51,7 +52,7 @@ CONFIGS = ( - "ssh_command_tar", - "", - "ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no " -- "-i @GLUSTERD_WORKDIR@/geo-replication/tar_ssh.pem"), -+ "-i " + GLUSTERD_WORKDIR + "/geo-replication/tar_ssh.pem"), - ("peersrx . .", - "changelog_log_file", - "", -@@ -59,7 +60,7 @@ CONFIGS = ( - "/${eSlave}${local_id}-changes.log"), - ("peersrx . .", - "working_dir", -- "@localstatedir@/run/gluster/${mastervol}/${eSlave}", -+ LOCALSTATEDIR + "/run/gluster/${mastervol}/${eSlave}", - "${iprefix}/lib/misc/glusterfsd/${mastervol}/${eSlave}"), - ("peersrx . .", - "ignore_deletes", -@@ -67,15 +68,15 @@ CONFIGS = ( - "false"), - ("peersrx . .", - "pid-file", -- "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" -+ GLUSTERD_WORKDIR + "/geo-replication/${mastervol}_${remotehost}_" - "${slavevol}/${eSlave}.pid", -- "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" -+ GLUSTERD_WORKDIR + "/geo-replication/${mastervol}_${remotehost}_" - "${slavevol}/monitor.pid"), - ("peersrx . .", - "state-file", -- "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" -+ GLUSTERD_WORKDIR + "/geo-replication/${mastervol}_${remotehost}_" - "${slavevol}/${eSlave}.status", -- "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_" -+ GLUSTERD_WORKDIR + "/geo-replication/${mastervol}_${remotehost}_" - "${slavevol}/monitor.status"), - ) - -diff --git a/geo-replication/syncdaemon/monitor.py b/geo-replication/syncdaemon/monitor.py -index a26de0c..a624fe4 100644 ---- a/geo-replication/syncdaemon/monitor.py -+++ b/geo-replication/syncdaemon/monitor.py -@@ -25,6 +25,7 @@ from gconf import gconf - from syncdutils import select, waitpid, errno_wrap - from syncdutils import set_term_handler, is_host_local, GsyncdError - from syncdutils import escape, Thread, finalize, memoize -+from syncdutils import gf_event, eventtypes - - from gsyncdstatus import GeorepStatus, set_monitor_status - -@@ -209,11 +210,12 @@ class Monitor(object): - blown worker blows up on EPIPE if the net goes down, - due to the keep-alive thread) - """ -- if not self.status.get(w[0], None): -- self.status[w[0]] = GeorepStatus(gconf.state_file, w[0]) -+ if not self.status.get(w[0]['dir'], None): -+ self.status[w[0]['dir']] = GeorepStatus(gconf.state_file, -+ w[0]['dir']) - - set_monitor_status(gconf.state_file, self.ST_STARTED) -- self.status[w[0]].set_worker_status(self.ST_INIT) -+ self.status[w[0]['dir']].set_worker_status(self.ST_INIT) - - ret = 0 - -@@ -280,7 +282,7 @@ class Monitor(object): - if apid == 0: - os.close(rw) - os.close(ww) -- os.execv(sys.executable, argv + ['--local-path', w[0], -+ os.execv(sys.executable, argv + ['--local-path', w[0]['dir'], - '--agent', - '--rpc-fd', - ','.join([str(ra), str(wa), -@@ -292,9 +294,9 @@ class Monitor(object): - os.close(ra) - os.close(wa) - os.execv(sys.executable, argv + ['--feedback-fd', str(pw), -- '--local-path', w[0], -+ '--local-path', w[0]['dir'], - '--local-id', -- '.' + escape(w[0]), -+ '.' + escape(w[0]['dir']), - '--rpc-fd', - ','.join([str(rw), str(ww), - str(ra), str(wa)]), -@@ -324,31 +326,31 @@ class Monitor(object): - if ret_agent is not None: - # Agent is died Kill Worker - logging.info("Changelog Agent died, " -- "Aborting Worker(%s)" % w[0]) -+ "Aborting Worker(%s)" % w[0]['dir']) - errno_wrap(os.kill, [cpid, signal.SIGKILL], [ESRCH]) - nwait(cpid) - nwait(apid) - - if ret is not None: - logging.info("worker(%s) died before establishing " -- "connection" % w[0]) -+ "connection" % w[0]['dir']) - nwait(apid) # wait for agent - else: -- logging.debug("worker(%s) connected" % w[0]) -+ logging.debug("worker(%s) connected" % w[0]['dir']) - while time.time() < t0 + conn_timeout: - ret = nwait(cpid, os.WNOHANG) - ret_agent = nwait(apid, os.WNOHANG) - - if ret is not None: - logging.info("worker(%s) died in startup " -- "phase" % w[0]) -+ "phase" % w[0]['dir']) - nwait(apid) # wait for agent - break - - if ret_agent is not None: - # Agent is died Kill Worker - logging.info("Changelog Agent died, Aborting " -- "Worker(%s)" % w[0]) -+ "Worker(%s)" % w[0]['dir']) - errno_wrap(os.kill, [cpid, signal.SIGKILL], [ESRCH]) - nwait(cpid) - nwait(apid) -@@ -357,12 +359,12 @@ class Monitor(object): - time.sleep(1) - else: - logging.info("worker(%s) not confirmed in %d sec, " -- "aborting it" % (w[0], conn_timeout)) -+ "aborting it" % (w[0]['dir'], conn_timeout)) - errno_wrap(os.kill, [cpid, signal.SIGKILL], [ESRCH]) - nwait(apid) # wait for agent - ret = nwait(cpid) - if ret is None: -- self.status[w[0]].set_worker_status(self.ST_STABLE) -+ self.status[w[0]['dir']].set_worker_status(self.ST_STABLE) - # If worker dies, agent terminates on EOF. - # So lets wait for agent first. - nwait(apid) -@@ -372,9 +374,16 @@ class Monitor(object): - else: - ret = exit_status(ret) - if ret in (0, 1): -- self.status[w[0]].set_worker_status(self.ST_FAULTY) -+ self.status[w[0]['dir']].set_worker_status(self.ST_FAULTY) -+ gf_event(eventtypes.GEOREP_FAULTY, -+ master_volume=master.volume, -+ master_node=w[0]['host'], -+ slave_host=slave_host, -+ slave_volume=slave_vol, -+ current_slave_host=current_slave_host, -+ brick_path=w[0]['dir']) - time.sleep(10) -- self.status[w[0]].set_worker_status(self.ST_INCON) -+ self.status[w[0]['dir']].set_worker_status(self.ST_INCON) - return ret - - def multiplex(self, wspx, suuid, slave_vol, slave_host, master): -@@ -461,7 +470,7 @@ def distribute(*resources): - for idx, brick in enumerate(mvol.bricks): - if is_host_local(brick['host']): - is_hot = mvol.is_hot(":".join([brick['host'], brick['dir']])) -- workerspex.append((brick['dir'], -+ workerspex.append((brick, - slaves[idx % len(slaves)], - get_subvol_num(idx, mvol, is_hot), - is_hot)) -diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py -index 987e1bf..f5d3c51 100644 ---- a/geo-replication/syncdaemon/syncdutils.py -+++ b/geo-replication/syncdaemon/syncdutils.py -@@ -23,6 +23,10 @@ from signal import signal, SIGTERM - import select as oselect - from os import waitpid as owaitpid - -+from conf import GLUSTERFS_LIBEXECDIR -+sys.path.insert(1, GLUSTERFS_LIBEXECDIR) -+from events import eventtypes -+ - try: - from cPickle import PickleError - except ImportError: -@@ -523,3 +527,8 @@ class GlusterLogLevel(object): - - def get_changelog_log_level(lvl): - return getattr(GlusterLogLevel, lvl, GlusterLogLevel.INFO) -+ -+ -+def gf_event(event_type, **kwargs): -+ from events.gf_event import gf_event as gfevent -+ gfevent(event_type, **kwargs) --- -1.7.1 - diff --git a/SOURCES/0074-build-make-var-run-available-on-RHEL-6.patch b/SOURCES/0074-build-make-var-run-available-on-RHEL-6.patch new file mode 100644 index 0000000..91a44a8 --- /dev/null +++ b/SOURCES/0074-build-make-var-run-available-on-RHEL-6.patch @@ -0,0 +1,31 @@ +From c59e78a5e8b7a1802f1f7caa1eab480a3395ba91 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Wed, 15 Nov 2017 12:18:57 +0530 +Subject: [PATCH 74/74] build: make /var/run available on RHEL-6 + +make /var/run available on RHEL-6 as well + +Label: DOWNSTREAM ONLY + +Change-Id: Iec79478e2233bd3194030a2c75273fc2ba3d17bb +Signed-off-by: Milind Changire +--- + glusterfs.spec.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index b6ba91c..da8a3e5 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -118,7 +118,7 @@ + %endif + + # From https://fedoraproject.org/wiki/Packaging:Python#Macros +-%if ( 0%{?rhel} && 0%{?rhel} <= 5 ) ++%if ( 0%{?rhel} && 0%{?rhel} <= 6 ) + %{!?python2_sitelib: %global python2_sitelib %(python2 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} + %{!?python2_sitearch: %global python2_sitearch %(python2 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} + %global _rundir %{_localstatedir}/run +-- +1.8.3.1 + diff --git a/SOURCES/0074-cluster-dht-Skip-layout-overlap-maximization-on-weig.patch b/SOURCES/0074-cluster-dht-Skip-layout-overlap-maximization-on-weig.patch deleted file mode 100644 index 427ad1a..0000000 --- a/SOURCES/0074-cluster-dht-Skip-layout-overlap-maximization-on-weig.patch +++ /dev/null @@ -1,104 +0,0 @@ -From bf4003ca869d951ff173d908885be89ef63ba28e Mon Sep 17 00:00:00 2001 -From: N Balachandran -Date: Thu, 8 Sep 2016 09:34:46 +0530 -Subject: [PATCH 74/86] cluster/dht: Skip layout overlap maximization on weighted rebalance - -During a fix-layout, dht_selfheal_layout_maximize_overlap () does not -consider chunk sizes while calculating layout overlaps, causing smaller -bricks to sometimes get larger ranges than larger bricks. Temporarily -enabling this operation if only if weighted rebalance is disabled -or all bricks are the same size. - -> Change-Id: I5ed16cdff2551b826a1759ca8338921640bfc7b3 -> BUG: 1366494 -> Signed-off-by: N Balachandran -> Reviewed-on: http://review.gluster.org/15403 -> Smoke: Gluster Build System -> CentOS-regression: Gluster Build System -> Reviewed-by: Raghavendra G -> NetBSD-regression: NetBSD Build System - ->Reviewed-on: http://review.gluster.org/15422 ->NetBSD-regression: NetBSD Build System ->CentOS-regression: Gluster Build System ->Smoke: Gluster Build System ->Reviewed-by: Niels de Vos - -Change-Id: Icf0dd83f36912e721982bcf818a06c4b339dc974 -BUG: 1257182 -Signed-off-by: N Balachandran -Reviewed-on: https://code.engineering.redhat.com/gerrit/84881 -Reviewed-by: Atin Mukherjee -Tested-by: Atin Mukherjee ---- - tests/bugs/distribute/bug-853258.t | 1 + - xlators/cluster/dht/src/dht-selfheal.c | 25 +++++++++++++++++++++---- - 2 files changed, 22 insertions(+), 4 deletions(-) - -diff --git a/tests/bugs/distribute/bug-853258.t b/tests/bugs/distribute/bug-853258.t -index 2f0e1b8..e39f507 100755 ---- a/tests/bugs/distribute/bug-853258.t -+++ b/tests/bugs/distribute/bug-853258.t -@@ -17,6 +17,7 @@ mkdir -p $H0:$B0/${V0}3 - TEST $CLI volume create $V0 $H0:$B0/${V0}0 $H0:$B0/${V0}1 $H0:$B0/${V0}2 - TEST $CLI volume start $V0 - EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'Started' volinfo_field $V0 'Status'; -+TEST $CLI volume set $V0 cluster.weighted-rebalance off - - # Force assignment of initial ranges. - TEST $CLI volume rebalance $V0 fix-layout start -diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c -index f43a235..fd90e54 100644 ---- a/xlators/cluster/dht/src/dht-selfheal.c -+++ b/xlators/cluster/dht/src/dht-selfheal.c -@@ -1706,6 +1706,7 @@ dht_fix_layout_of_directory (call_frame_t *frame, loc_t *loc, - dht_local_t *local = NULL; - uint32_t subvol_down = 0; - int ret = 0; -+ gf_boolean_t maximize_overlap = _gf_true; - - this = frame->this; - priv = this->private; -@@ -1752,9 +1753,18 @@ dht_fix_layout_of_directory (call_frame_t *frame, loc_t *loc, - "subvolume %d (%s): %u chunks", i, - priv->subvolumes[i]->name, - priv->du_stats[i].chunks); -+ -+ /* Maximize overlap if the bricks are all the same -+ * size. -+ * This is probably not going to be very common on -+ * live setups but will benefit our regression tests -+ */ -+ if (i && (priv->du_stats[i].chunks -+ != priv->du_stats[0].chunks)) { -+ maximize_overlap = _gf_false; -+ } - } -- } -- else { -+ } else { - gf_msg (this->name, GF_LOG_WARNING, 0, - DHT_MSG_NO_DISK_USAGE_STATUS, "no du stats ?!?"); - } -@@ -1764,9 +1774,16 @@ dht_fix_layout_of_directory (call_frame_t *frame, loc_t *loc, - dht_layout_sort_volname (new_layout); - dht_selfheal_layout_new_directory (frame, loc, new_layout); - -- /* Now selectively re-assign ranges only when it helps */ -- dht_selfheal_layout_maximize_overlap (frame, loc, new_layout, layout); - -+ /* Maximize overlap if weighted-rebalance is disabled */ -+ if (!priv->do_weighting) -+ maximize_overlap = _gf_true; -+ -+ /* Now selectively re-assign ranges only when it helps */ -+ if (maximize_overlap) { -+ dht_selfheal_layout_maximize_overlap (frame, loc, new_layout, -+ layout); -+ } - done: - if (new_layout) { - /* Now that the new layout has all the proper layout, change the --- -1.7.1 - diff --git a/SOURCES/0075-cli-gluster-help-changes.patch b/SOURCES/0075-cli-gluster-help-changes.patch new file mode 100644 index 0000000..98d47a5 --- /dev/null +++ b/SOURCES/0075-cli-gluster-help-changes.patch @@ -0,0 +1,749 @@ +From fb84f6c69385e35f3a62504dfebc11b21ff4082a Mon Sep 17 00:00:00 2001 +From: N Balachandran +Date: Mon, 6 Nov 2017 09:30:54 +0530 +Subject: [PATCH 075/128] cli: gluster help changes + +gluster cli help now shows only the top level +help commands. gluster help will now show +help commands for . + +> BUG: 1474768 +> Signed-off-by: N Balachandran +> BUG: 1509786 +> https://review.gluster.org/#/c/18666/ +> Signed-off-by: N Balachandran + +(cherry picked from commit 89dc54f50c9f800ca4446ea8fe736e4860588845) +Change-Id: I263f53a0870d80ef4cfaad455fdaa47e2ac4423b +BUG: 1498730 +Signed-off-by: N Balachandran +Reviewed-on: https://code.engineering.redhat.com/gerrit/123525 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + cli/src/cli-cmd-global.c | 3 + + cli/src/cli-cmd-misc.c | 77 ++++++++-- + cli/src/cli-cmd-parser.c | 20 ++- + cli/src/cli-cmd-peer.c | 9 +- + cli/src/cli-cmd-snapshot.c | 5 + + cli/src/cli-cmd-volume.c | 347 ++++++++++++++++++++++++++++++++++++++------- + cli/src/cli.c | 2 +- + 7 files changed, 387 insertions(+), 76 deletions(-) + +diff --git a/cli/src/cli-cmd-global.c b/cli/src/cli-cmd-global.c +index 881506b..1f9cb54 100644 +--- a/cli/src/cli-cmd-global.c ++++ b/cli/src/cli-cmd-global.c +@@ -68,11 +68,14 @@ cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, + count = (sizeof (global_cmds) / sizeof (struct cli_cmd)); + cli_cmd_sort (cmd, count); + ++ cli_out ("\ngluster global commands"); ++ cli_out ("========================\n"); + for (global_cmd = cmd; global_cmd->pattern; global_cmd++) + if (_gf_false == global_cmd->disable) + cli_out ("%s - %s", global_cmd->pattern, + global_cmd->desc); + ++ cli_out ("\n"); + GF_FREE (cmd); + return 0; + } +diff --git a/cli/src/cli-cmd-misc.c b/cli/src/cli-cmd-misc.c +index 9f8c159..c887515 100644 +--- a/cli/src/cli-cmd-misc.c ++++ b/cli/src/cli-cmd-misc.c +@@ -23,6 +23,9 @@ extern struct rpc_clnt *global_rpc; + extern rpc_clnt_prog_t *cli_rpc_prog; + + extern struct cli_cmd volume_cmds[]; ++extern struct cli_cmd bitrot_cmds[]; ++extern struct cli_cmd quota_cmds[]; ++extern struct cli_cmd tier_cmds[]; + extern struct cli_cmd cli_probe_cmds[]; + extern struct cli_cmd cli_log_cmds[]; + extern struct cli_cmd cli_system_cmds[]; +@@ -38,37 +41,76 @@ cli_cmd_quit_cbk (struct cli_state *state, struct cli_cmd_word *word, + exit (0); + } + ++ ++static gf_boolean_t ++cli_is_help_command (const char *pattern) ++{ ++ /* FixFixFix ++ * This is not the best way to determine whether ++ * this is a help command ++ */ ++ if (strstr (pattern, "help")) ++ return _gf_true; ++ ++ return _gf_false; ++} ++ ++ + int + cli_cmd_display_help (struct cli_state *state, struct cli_cmd_word *in_word, + const char **words, int wordcount) + { +- struct cli_cmd *cmd[] = {volume_cmds, cli_probe_cmds, +- cli_misc_cmds, snapshot_cmds, +- global_cmds, NULL}; +- struct cli_cmd *cmd_ind = NULL; +- int i = 0; ++ struct cli_cmd *cmd[] = {cli_misc_cmds, cli_probe_cmds, ++ volume_cmds, bitrot_cmds, quota_cmds, ++#if !defined(__NetBSD__) ++ tier_cmds, ++#endif ++ snapshot_cmds, global_cmds, NULL}; ++ struct cli_cmd *cmd_ind = NULL; ++ int i = 0; ++ gf_boolean_t list_all = _gf_false; + + /* cli_system_cmds commands for internal usage + they are not exposed + */ +- for (i=0; cmd[i]!=NULL; i++) +- for (cmd_ind = cmd[i]; cmd_ind->pattern; cmd_ind++) +- if (_gf_false == cmd_ind->disable) +- cli_out ("%s - %s", cmd_ind->pattern, +- cmd_ind->desc); + ++ /* If "help all" */ ++ if (wordcount == 2) ++ list_all = _gf_true; ++ ++ for (i = 0; cmd[i] != NULL; i++) { ++ for (cmd_ind = cmd[i]; cmd_ind->pattern; cmd_ind++) { ++ if ((_gf_false == cmd_ind->disable) && ++ cli_is_help_command (cmd_ind->pattern)) { ++ if (list_all && (cmd_ind->cbk)) { ++ cmd_ind->cbk (state, in_word, words, ++ wordcount); ++ } else { ++ cli_out (" %-25s- %s", cmd_ind->pattern, ++ cmd_ind->desc); ++ } ++ } ++ } ++ } ++ ++ cli_out ("\n"); + return 0; + } + ++ ++struct cli_cmd cli_help_cmds[] = { ++ { "help [all]", ++ cli_cmd_display_help, ++ "display help for command classes"}, ++ ++ { NULL, NULL, NULL } ++}; ++ ++ + struct cli_cmd cli_misc_cmds[] = { + { "quit", + cli_cmd_quit_cbk, + "quit"}, +- +- { "help", +- cli_cmd_display_help, +- "display command options"}, +- + { "exit", + cli_cmd_quit_cbk, + "exit"}, +@@ -84,7 +126,12 @@ cli_cmd_misc_register (struct cli_state *state) + struct cli_cmd *cmd = NULL; + + for (cmd = cli_misc_cmds; cmd->pattern; cmd++) { ++ ret = cli_cmd_register (&state->tree, cmd); ++ if (ret) ++ goto out; ++ } + ++ for (cmd = cli_help_cmds; cmd->pattern; cmd++) { + ret = cli_cmd_register (&state->tree, cmd); + if (ret) + goto out; +diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c +index a35fc74..c95b262 100644 +--- a/cli/src/cli-cmd-parser.c ++++ b/cli/src/cli-cmd-parser.c +@@ -1189,8 +1189,13 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) + goto out; + } + +- if (wordcount < 4) ++ if (wordcount < 4) { ++ ++ if ((wordcount == 3) && !(strcmp (words[2], "help"))) { ++ ret = 1; ++ } + goto out; ++ } + + volname = (char *)words[2]; + if (!volname) { +@@ -5588,15 +5593,22 @@ cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options) + GF_ASSERT (words); + GF_ASSERT (options); + +- dict = dict_new (); +- if (!dict) +- goto out; ++ ++ /* Hack to print out bitrot help properly */ ++ if ((wordcount == 3) && !(strcmp (words[2], "help"))) { ++ ret = 1; ++ return ret; ++ } + + if (wordcount < 4 || wordcount > 5) { + gf_log ("cli", GF_LOG_ERROR, "Invalid syntax"); + goto out; + } + ++ dict = dict_new (); ++ if (!dict) ++ goto out; ++ + volname = (char *)words[2]; + if (!volname) { + ret = -1; +diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c +index 4802f71..7df60bc 100644 +--- a/cli/src/cli-cmd-peer.c ++++ b/cli/src/cli-cmd-peer.c +@@ -264,7 +264,7 @@ struct cli_cmd cli_probe_cmds[] = { + + { "peer help", + cli_cmd_peer_help_cbk, +- "Help command for peer "}, ++ "display help for peer commands"}, + + { "pool list", + cli_cmd_pool_list_cbk, +@@ -281,17 +281,20 @@ cli_cmd_peer_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, + struct cli_cmd *probe_cmd = NULL; + int count = 0; + ++ cli_out ("\ngluster peer commands"); ++ cli_out ("======================\n"); ++ + cmd = GF_CALLOC (1, sizeof (cli_probe_cmds), cli_mt_cli_cmd); + memcpy (cmd, cli_probe_cmds, sizeof (cli_probe_cmds)); + count = (sizeof (cli_probe_cmds) / sizeof (struct cli_cmd)); + cli_cmd_sort (cmd, count); + +- +- + for (probe_cmd = cmd; probe_cmd->pattern; probe_cmd++) + cli_out ("%s - %s", probe_cmd->pattern, probe_cmd->desc); + + GF_FREE (cmd); ++ ++ cli_out ("\n"); + return 0; + } + +diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c +index e79128c..88b4737 100644 +--- a/cli/src/cli-cmd-snapshot.c ++++ b/cli/src/cli-cmd-snapshot.c +@@ -140,9 +140,14 @@ cli_cmd_snapshot_help_cbk (struct cli_state *state, + count = (sizeof (snapshot_cmds) / sizeof (struct cli_cmd)); + cli_cmd_sort (cmd, count); + ++ cli_out ("\ngluster snapshot commands"); ++ cli_out ("=========================\n"); ++ + for (snap_cmd = cmd; snap_cmd->pattern; snap_cmd++) + if (_gf_false == snap_cmd->disable) + cli_out ("%s - %s", snap_cmd->pattern, snap_cmd->desc); ++ cli_out ("\n"); ++ + GF_FREE (cmd); + return 0; + } +diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c +index ca9da0a..a1e5c51 100644 +--- a/cli/src/cli-cmd-volume.c ++++ b/cli/src/cli-cmd-volume.c +@@ -36,7 +36,19 @@ extern rpc_clnt_prog_t cli_quotad_clnt; + + int + cli_cmd_volume_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, +- const char **words, int wordcount); ++ const char **words, int wordcount); ++ ++int ++cli_cmd_bitrot_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, ++ const char **words, int wordcount); ++ ++int ++cli_cmd_quota_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, ++ const char **words, int wordcount); ++ ++int ++cli_cmd_tier_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, ++ const char **words, int wordcount); + + int + cli_cmd_volume_info_cbk (struct cli_state *state, struct cli_cmd_word *word, +@@ -1293,9 +1305,12 @@ cli_cmd_volume_tier_cbk (struct cli_state *state, + + + if (wordcount < 4) { +- cli_usage_out (word->pattern); +- if (wordcount == 3 && !strcmp(words[2], "help")) ++ if (wordcount == 3 && !strcmp(words[2], "help")) { ++ cli_cmd_tier_help_cbk (state, word, words, wordcount); + ret = 0; ++ } else { ++ cli_usage_out (word->pattern); ++ } + goto out; + } + +@@ -1719,6 +1734,8 @@ out: + return ret; + } + ++ ++ + int + cli_cmd_bitrot_cbk (struct cli_state *state, struct cli_cmd_word *word, + const char **words, int wordcount) +@@ -1746,6 +1763,13 @@ cli_cmd_bitrot_cbk (struct cli_state *state, struct cli_cmd_word *word, + goto out; + } + ++ if (ret == 1) { ++ /* this is 'volume bitrot help' */ ++ cli_cmd_bitrot_help_cbk (state, word, words, wordcount); ++ ret = 0; ++ goto out2; ++ } ++ + frame = create_frame (THIS, THIS->ctx->pool); + if (!frame) { + ret = -1; +@@ -1834,7 +1858,7 @@ out: + #endif + + CLI_STACK_DESTROY (frame); +- ++out2: + return ret; + } + +@@ -1866,6 +1890,12 @@ cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word, + } + } else { + ret = cli_cmd_quota_parse (words, wordcount, &options); ++ ++ if (ret == 1) { ++ cli_cmd_quota_help_cbk (state, word, words, wordcount); ++ ret = 0; ++ goto out; ++ } + if (ret < 0) { + cli_usage_out (word->pattern); + parse_err = 1; +@@ -3157,7 +3187,159 @@ out: + return ret; + } + ++ ++/* This is a bit of a hack to display the help. The current bitrot cmd ++ * format does not work well when registering the cmds. ++ * Ideally the should have been of the form ++ * gluster volume bitrot ... ++ */ ++ ++struct cli_cmd bitrot_cmds[] = { ++ ++ {"volume bitrot help", ++ cli_cmd_bitrot_help_cbk, ++ "display help for volume bitrot commands" ++ }, ++ ++ {"volume bitrot {enable|disable}", ++ NULL, /*cli_cmd_bitrot_cbk,*/ ++ "Enable/disable bitrot for volume " ++ }, ++ ++ {"volume bitrot scrub-throttle {lazy|normal|aggressive}", ++ NULL, /*cli_cmd_bitrot_cbk,*/ ++ "Set the speed of the scrubber for volume " ++ }, ++ ++ {"volume bitrot scrub-frequency {hourly|daily|weekly|biweekly" ++ "|monthly}", ++ NULL, /*cli_cmd_bitrot_cbk,*/ ++ "Set the frequency of the scrubber for volume " ++ }, ++ ++ {"volume bitrot scrub {pause|resume|status|ondemand}", ++ NULL, /*cli_cmd_bitrot_cbk,*/ ++ "Pause/resume the scrubber for . Status displays the status of " ++ "the scrubber. ondemand starts the scrubber immediately." ++ }, ++ ++ {"volume bitrot {enable|disable}\n" ++ "volume bitrot scrub-throttle {lazy|normal|aggressive}\n" ++ "volume bitrot scrub-frequency {hourly|daily|weekly|biweekly" ++ "|monthly}\n" ++ "volume bitrot scrub {pause|resume|status|ondemand}", ++ cli_cmd_bitrot_cbk, ++ NULL ++ }, ++ ++ { NULL, NULL, NULL } ++}; ++ ++ ++struct cli_cmd quota_cmds[] = { ++ ++ /* Quota commands */ ++ {"volume quota help", ++ cli_cmd_quota_help_cbk, ++ "display help for volume quota commands" ++ }, ++ ++ {"volume quota {enable|disable|list [ ...]| " ++ "list-objects [ ...] | remove | remove-objects | " ++ "default-soft-limit }", ++ cli_cmd_quota_cbk, ++ "Enable/disable and configure quota for " ++ }, ++ ++ {"volume quota {limit-usage []}", ++ cli_cmd_quota_cbk, ++ "Set maximum size for for " ++ }, ++ ++ {"volume quota {limit-objects []}", ++ cli_cmd_quota_cbk, ++ "Set the maximum number of entries allowed in for " ++ }, ++ ++ {"volume quota {alert-time|soft-timeout|hard-timeout} {