From 2f499e85a4ae0ac1e84785daa60a5bbfe979cc7f Mon Sep 17 00:00:00 2001 From: Kotresh H R Date: Wed, 8 Jan 2014 10:52:28 +0530 Subject: glusterd/geo-rep : Allow volume to stop if geo-rep is not active. In staging phase of volume stop, code is added to read the state_file for each slave of the master to which the volume belongs. If any of the geo-rep session is active with at least one slave, volume is not allowed to stop else it is allowed. Change-Id: I4a01a357fc86b872e9635b3d19998cdbd9545114 BUG: 1049727 Signed-off-by: Kotresh H R Reviewed-on: http://review.gluster.org/6663 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 152 ++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-op-sm.h | 5 + xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 20 +++- 3 files changed, 176 insertions(+), 1 deletion(-) (limited to 'xlators/mgmt/glusterd') diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index c5c76e11a..849480a28 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -1295,6 +1295,158 @@ glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag) return 0; } +/* + * is_geo_rep_active: + * This function reads the state_file and sets is_active to 1 if the + * monitor status is neither "Stopped" or "Not Started" + * + * RETURN VALUE: + * 0: On successful read of state_file. + * -1: error. + */ + +static int +is_geo_rep_active (glusterd_volinfo_t *volinfo, char *slave, + char *conf_path, int *is_active) +{ + dict_t *confd = NULL; + char *statefile = NULL; + char *master = NULL; + char monitor_status[PATH_MAX] = ""; + int ret = -1; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + master = volinfo->volname; + + confd = dict_new (); + if (!confd) { + gf_log ("", GF_LOG_ERROR, "Not able to create dict."); + goto out; + } + + ret = glusterd_gsync_get_config (master, slave, conf_path, + confd); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get configuration data " + "for %s(master), %s(slave)", master, slave); + ret = -1; + goto out; + } + + ret = dict_get_param (confd, "state_file", &statefile); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Unable to get state_file's name " + "for %s(master), %s(slave). Please check gsync " + "config file.", master, slave); + ret = -1; + goto out; + } + + ret = glusterd_gsync_read_frm_status (statefile, monitor_status, + sizeof (monitor_status)); + if (ret <= 0) { + gf_log ("", GF_LOG_ERROR, "Unable to read the status " + "file for %s(master), %s(slave)", master, slave); + strncpy (monitor_status, "defunct", sizeof (monitor_status)); + } + + if ((!strcmp(monitor_status, "Stopped")) || + (!strcmp(monitor_status, "Not Started"))) { + *is_active = 0; + } else { + *is_active = 1; + } + ret = 0; +out: + if (confd) + dict_destroy (confd); + return ret; +} + +/* + * _get_slave_status: + * Called for each slave in the volume from dict_foreach. + * It calls is_geo_rep_active to get the monitor status. + * + * RETURN VALUE: + * 0: On successful read of state_file from is_geo_rep_active. + * When it is found geo-rep is already active from previous calls. + * When there is no slave. + * -1: On error. + */ + +int +_get_slave_status (dict_t *dict, char *key, data_t *value, void *data) +{ + gsync_status_param_t *param = NULL; + char *slave = NULL; + char *slave_ip = NULL; + char *slave_vol = NULL; + char *errmsg = NULL; + char conf_path[PATH_MAX] = ""; + int ret = -1; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + + param = (gsync_status_param_t *)data; + + GF_ASSERT (param); + GF_ASSERT (param->volinfo); + + if (param->is_active) { + ret = 0; + goto out; + } + + this = THIS; + GF_ASSERT (this); + + if (this) + priv = this->private; + if (priv == NULL) { + gf_log ("", GF_LOG_ERROR, "priv of glusterd not present"); + goto out; + } + + slave = strchr(value->data, ':'); + if (!slave) { + ret = 0; + goto out; + } + slave++; + + ret = glusterd_get_slave_info (slave, &slave_ip, &slave_vol, &errmsg); + if (ret) { + if (errmsg) + gf_log ("", GF_LOG_ERROR, "Unable to fetch " + "slave details. Error: %s", errmsg); + else + gf_log ("", GF_LOG_ERROR, + "Unable to fetch slave details."); + ret = -1; + goto out; + } + + ret = snprintf (conf_path, sizeof(conf_path) - 1, + "%s/"GEOREP"/%s_%s_%s/gsyncd.conf", + priv->workdir, param->volinfo->volname, + slave_ip, slave_vol); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "Unable to assign conf_path."); + ret = -1; + goto out; + } + conf_path[ret] = '\0'; + + ret = is_geo_rep_active (param->volinfo,slave, conf_path, + ¶m->is_active); +out: + return ret; +} + static int glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo, char *slave, char *conf_path, diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 62f991933..1125368ce 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -165,6 +165,11 @@ typedef struct glusterd_gsync_status_temp { char *node; }glusterd_gsync_status_temp_t; +typedef struct gsync_status_param { + int is_active; + glusterd_volinfo_t *volinfo; +}gsync_status_param_t; + typedef enum cli_cmd_type_ { PER_REPLICA, ALL_REPLICA, diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index df2562ba6..db9f39c7c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -30,6 +30,8 @@ #define glusterd_op_start_volume_args_get(dict, volname, flags) \ glusterd_op_stop_volume_args_get (dict, volname, flags) +extern int +_get_slave_status (dict_t *this, char *key, data_t *value, void *data); int __glusterd_handle_create_volume (rpcsvc_request_t *req) @@ -1059,6 +1061,7 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) glusterd_volinfo_t *volinfo = NULL; char msg[2048] = {0}; xlator_t *this = NULL; + gsync_status_param_t param = {0,}; this = THIS; GF_ASSERT (this); @@ -1102,7 +1105,22 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) if (ret && (is_run == _gf_false)) gf_log (this->name, GF_LOG_WARNING, "Unable to get the status" " of active "GEOREP" session"); - if (is_run) { + + param.volinfo = volinfo; + ret = dict_foreach (volinfo->gsync_slaves, _get_slave_status, ¶m); + + if (ret) { + gf_log (this->name, GF_LOG_WARNING, "_get_slave_satus failed"); + snprintf (msg, sizeof(msg), GEOREP" Unable to get the status " + "of active "GEOREP" session for the volume '%s'.\n" + "Please check the log file for more info. Use " + "'force' option to ignore and stop the volume.", + volname); + ret = -1; + goto out; + } + + if (is_run && param.is_active) { gf_log (this->name, GF_LOG_WARNING, GEOREP" sessions active" "for the volume %s ", volname); snprintf (msg, sizeof(msg), GEOREP" sessions are active " -- cgit From f3e227d525ee04a3ea0196f7a15aa9b1a8f8cae1 Mon Sep 17 00:00:00 2001 From: Lalatendu Mohanty Date: Tue, 14 Jan 2014 23:24:50 +0530 Subject: geo-rep: Fixing null pointer dereference of "op_value" Change-Id: Id39743eaa5a52cc7fd4e2a1378a23384f5ef1fed BUG: 789278 Signed-off-by: Lalatendu Mohanty Reviewed-on: http://review.gluster.org/6700 Reviewed-by: Avra Sengupta Tested-by: Avra Sengupta --- xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xlators/mgmt/glusterd') diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 849480a28..3969db17c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -2614,7 +2614,7 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave, goto out; } - if (!strcmp (op_name, "state_file")) { + if ((!strcmp (op_name, "state_file")) && (op_value)) { ret = lstat (op_value, &stbuf); if (ret) { -- cgit From 39968c09626074b34b62541af5940f44ba70cc06 Mon Sep 17 00:00:00 2001 From: Varun Shastry Date: Tue, 22 Oct 2013 16:12:58 +0530 Subject: features/quota: Metadata cleanup Quota and marker uses 'trusted.glusterfs.quota*' and 'trusted.pgfid*' xattrs to store its configurations and accounting information and also to build the parent inode chain in case of absense of path. Problem: After disabling and then enabling quota back, the xattrs may contain stale data leading to impaired accounting and thus improper enforcement. Solution: Clean up all the quota related xattrs after quota disable. Marker xlator implements a virtual xattr to cleanup quota and pgfid xattrs. In this approach glusterd mounts an auxiliary mount and sends the below command to all the files by crawling the mountpoint. #setfattr -n "glusterfs.quota-xattr-cleanup" -v 1 Credit: Krishnan Parthasarathi Varun Shastry Change-Id: I9380eca58a285dc27dd572de1767aac8f2cd8049 BUG: 969461 Signed-off-by: Varun Shastry Reviewed-on: http://review.gluster.org/6369 Reviewed-by: Raghavendra G Tested-by: Gluster Build System Reviewed-by: Krishnan Parthasarathi Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-quota.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'xlators/mgmt/glusterd') diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 3c8dcf8dd..ffde532bd 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -28,6 +28,8 @@ #include #include +/* Any negative pid to make it special client */ +#define QUOTA_CRAWL_PID "-100" const char *gd_quota_op_list[GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT+1] = { [GF_QUOTA_OPTION_TYPE_NONE] = "none", @@ -158,7 +160,8 @@ out: } int32_t -glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname) +glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname, + int type) { pid_t pid; int32_t ret = 0; @@ -178,6 +181,7 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname) "-s", "localhost", "--volfile-id", volname, "--use-readdirp=no", + "--client-pid", QUOTA_CRAWL_PID, "-l", DEFAULT_LOG_FILE_DIRECTORY"/quota-crawl.log", mountdir, NULL); @@ -210,7 +214,19 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname) exit (EXIT_FAILURE); } runinit (&runner); - runner_add_args (&runner, "/usr/bin/find", "find", ".", NULL); + + if (type == GF_QUOTA_OPTION_TYPE_ENABLE) + + runner_add_args (&runner, "/usr/bin/find", "find", ".", + NULL); + + else if (type == GF_QUOTA_OPTION_TYPE_DISABLE) + + runner_add_args (&runner, "/usr/bin/find", ".", + "-exec", "/usr/bin/setfattr", "-n", + VIRTUAL_QUOTA_XATTR_CLEANUP_KEY, "-v", + "1", "{}", "\\", ";", NULL); + if (runner_start (&runner) == -1) _exit (EXIT_FAILURE); @@ -325,7 +341,8 @@ out: } int32_t -glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr) +glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr, + gf_boolean_t *crawl) { int32_t ret = -1; int i = 0; @@ -381,6 +398,8 @@ glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr) if (ret) goto out; + *crawl = _gf_true; + (void) glusterd_clean_up_quota_store (volinfo); ret = 0; @@ -1045,7 +1064,8 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) break; case GF_QUOTA_OPTION_TYPE_DISABLE: - ret = glusterd_quota_disable (volinfo, op_errstr); + ret = glusterd_quota_disable (volinfo, op_errstr, + &start_crawl); if (ret < 0) goto out; @@ -1129,7 +1149,7 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) } if (rsp_dict && start_crawl == _gf_true) - glusterd_quota_initiate_fs_crawl (priv, volname); + glusterd_quota_initiate_fs_crawl (priv, volname, type); if (priv->op_version > GD_OP_VERSION_MIN) { ret = glusterd_quotad_op (type); -- cgit From 1ffc3ac9639e25c91ac26488b648d5523becb08e Mon Sep 17 00:00:00 2001 From: Lalatendu Mohanty Date: Tue, 14 Jan 2014 23:50:51 +0530 Subject: core: Coverity issue "Use of uninitialized scalar variable" Issue: 1. In "unlink (export_path)" "export_path" might contain an arbitrary value left from earlier computations. 2. In "(msg[0] != '\0')" msg might contain an arbitrary value Change-Id: Icca8f557fd6b5e046dff1d5a84a72061975868d0 BUG: 789278 Signed-off-by: Lalatendu Mohanty Reviewed-on: http://review.gluster.org/6701 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xlators/mgmt/glusterd') diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index db9f39c7c..85a537306 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -923,7 +923,7 @@ glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr) gf_boolean_t exists = _gf_false; glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; - char msg[2048]; + char msg[2048] = {0,}; glusterd_conf_t *priv = NULL; xlator_t *this = NULL; uuid_t volume_id = {0,}; -- cgit From b2ef4e3d11af79a765406672bb6ca070b40c9b64 Mon Sep 17 00:00:00 2001 From: Susant Palai Date: Mon, 6 Jan 2014 12:38:08 +0000 Subject: quota: unmount quota aux mount for volume stop Previously df -h used to display "Transport end point not connected" for quota auxiliary mount after volume is stopped. This patch unmounts the auxiliary mount when the volume is stopped in all peer nodes for that volume. Change-Id: I78abb44386cd8242a532f92c13df8bdb57c78e31 BUG: 1049323 Signed-off-by: Susant Palai Reviewed-on: http://review.gluster.org/6656 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'xlators/mgmt/glusterd') diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 85a537306..051e7d756 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -1774,6 +1774,9 @@ glusterd_op_stop_volume (dict_t *dict) glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; xlator_t *this = NULL; + char mountdir[PATH_MAX] = {0,}; + runner_t runner = {0,}; + char pidfile[PATH_MAX] = {0,}; this = THIS; GF_ASSERT (this); @@ -1801,6 +1804,30 @@ glusterd_op_stop_volume (dict_t *dict) if (ret) goto out; + /* If quota auxiliary mount is present, unmount it */ + GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile, volname); + + if (!gf_is_service_running (pidfile, NULL)) { + gf_log (this->name, GF_LOG_DEBUG, "Aux mount of volume %s " + "absent", volname); + } else { + GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/"); + + runinit (&runner); + runner_add_args (&runner, "umount", + + #if GF_LINUX_HOST_OS + "-l", + #endif + mountdir, NULL); + ret = runner_run_reuse (&runner); + if (ret) + gf_log (this->name, GF_LOG_ERROR, "umount on %s failed, " + "reason : %s", mountdir, strerror (errno)); + + runner_end (&runner); + } + ret = glusterd_nodesvcs_handle_graph_change (volinfo); out: return ret; -- cgit