summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd
diff options
context:
space:
mode:
authorAtin Mukherjee <amukherj@redhat.com>2018-11-20 12:32:32 +0530
committerAmar Tumballi <amarts@redhat.com>2018-12-05 21:36:25 +0000
commitd4723bdd30f0955ca68fec8c01bc87229c6a24c0 (patch)
tree378ba7553b0f43e9de5d9a7139420e53fca48f47 /xlators/mgmt/glusterd
parentafc3006b46bf9d6eb05e39af68bcd81041761a9c (diff)
glusterd: glusterd to regenerate volfiles when GD_OP_VERSION_MAX changes
While glusterd has an infra to allow post install of spec to bring it up in the interim upgrade mode to allow all the volfiles to be regenerated with the latest executable, in container world the same methodology is not followed as container image always point to the specific gluster rpm and gluster rpm doesn't go through an upgrade process. This fix does the following: 1. If glusterd.upgrade file doesn't exist, regenerate the volfiles 2. If maximum-operating-version read from glusterd.upgrade doesn't match with GD_OP_VERSION_MAX, glusterd detects it to be a version where new options are introduced and regenerate the volfiles. Tests done: 1. Bring up glusterd, check if glusterd.upgrade file has been created with GD_OP_VERSION_MAX value. 2. Post 1, restart glusterd and check glusterd hasn't regenerated the volfiles as there's is no change in the GD_OP_VERSION_MAX vs the op_version read from the file. 3. Bump up the GD_OP_VERSION_MAX in the code by 1 and post compilation restart glusterd where the volfiles should be again regenerated. Note: The old way of having volfiles regenerated during an rpm upgrade is kept as it is for now but eventually this can be sunset later. Change-Id: I75b49a1601c71e99f6a6bc360dd12dd03a96414b Fixes: bz#1651463 Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
Diffstat (limited to 'xlators/mgmt/glusterd')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c132
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c27
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h7
4 files changed, 160 insertions, 12 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index be5f072de66..4a967ae7494 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -2087,7 +2087,7 @@ glusterd_store_global_info(xlator_t *this)
}
handle->fd = gf_store_mkstemp(handle);
- if (handle->fd <= 0) {
+ if (handle->fd < 0) {
ret = -1;
goto out;
}
@@ -2103,7 +2103,7 @@ glusterd_store_global_info(xlator_t *this)
goto out;
}
- snprintf(op_version_str, 15, "%d", conf->op_version);
+ snprintf(op_version_str, sizeof(op_version_str), "%d", conf->op_version);
ret = gf_store_save_value(handle->fd, GD_OP_VERSION_KEY, op_version_str);
if (ret) {
gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_VERS_STORE_FAIL,
@@ -2114,12 +2114,8 @@ glusterd_store_global_info(xlator_t *this)
ret = gf_store_rename_tmppath(handle);
out:
if (handle) {
- if (ret && (handle->fd > 0))
+ if (ret && (handle->fd >= 0))
gf_store_unlink_tmppath(handle);
-
- if (handle->fd > 0) {
- handle->fd = 0;
- }
}
if (uuid_str)
@@ -2134,6 +2130,128 @@ out:
}
int
+glusterd_store_max_op_version(xlator_t *this)
+{
+ int ret = -1;
+ glusterd_conf_t *conf = NULL;
+ char op_version_str[15] = {
+ 0,
+ };
+ char path[PATH_MAX] = {
+ 0,
+ };
+ gf_store_handle_t *handle = NULL;
+ int32_t len = 0;
+
+ conf = this->private;
+
+ len = snprintf(path, PATH_MAX, "%s/%s", conf->workdir,
+ GLUSTERD_UPGRADE_FILE);
+ if ((len < 0) || (len >= PATH_MAX)) {
+ goto out;
+ }
+ ret = gf_store_handle_new(path, &handle);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_STORE_HANDLE_GET_FAIL,
+ "Unable to get store handle");
+ goto out;
+ }
+
+ /* These options need to be available for all users */
+ ret = sys_chmod(handle->path, 0644);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
+ "chmod error for %s", GLUSTERD_UPGRADE_FILE);
+ goto out;
+ }
+
+ handle->fd = gf_store_mkstemp(handle);
+ if (handle->fd < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ snprintf(op_version_str, sizeof(op_version_str), "%d", GD_OP_VERSION_MAX);
+ ret = gf_store_save_value(handle->fd, GD_MAX_OP_VERSION_KEY,
+ op_version_str);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_VERS_STORE_FAIL,
+ "Storing op-version failed ret = %d", ret);
+ goto out;
+ }
+
+ ret = gf_store_rename_tmppath(handle);
+out:
+ if (handle) {
+ if (ret && (handle->fd >= 0))
+ gf_store_unlink_tmppath(handle);
+ }
+
+ if (ret)
+ gf_msg(this->name, GF_LOG_ERROR, 0,
+ GD_MSG_GLUSTERD_GLOBAL_INFO_STORE_FAIL,
+ "Failed to store max op-version");
+ if (handle)
+ gf_store_handle_destroy(handle);
+ return ret;
+}
+
+int
+glusterd_retrieve_max_op_version(xlator_t *this, int *op_version)
+{
+ char *op_version_str = NULL;
+ glusterd_conf_t *priv = NULL;
+ int ret = -1;
+ int tmp_version = 0;
+ char *tmp = NULL;
+ char path[PATH_MAX] = {
+ 0,
+ };
+ gf_store_handle_t *handle = NULL;
+ int32_t len = 0;
+
+ priv = this->private;
+
+ len = snprintf(path, PATH_MAX, "%s/%s", priv->workdir,
+ GLUSTERD_UPGRADE_FILE);
+ if ((len < 0) || (len >= PATH_MAX)) {
+ goto out;
+ }
+ ret = gf_store_handle_retrieve(path, &handle);
+
+ if (ret) {
+ gf_msg_debug(this->name, 0,
+ "Unable to get store "
+ "handle!");
+ goto out;
+ }
+
+ ret = gf_store_retrieve_value(handle, GD_MAX_OP_VERSION_KEY,
+ &op_version_str);
+ if (ret) {
+ gf_msg_debug(this->name, 0, "No previous op_version present");
+ goto out;
+ }
+
+ tmp_version = strtol(op_version_str, &tmp, 10);
+ if ((tmp_version <= 0) || (tmp && strlen(tmp) > 1)) {
+ gf_msg(this->name, GF_LOG_WARNING, EINVAL, GD_MSG_UNSUPPORTED_VERSION,
+ "invalid version number");
+ goto out;
+ }
+
+ *op_version = tmp_version;
+
+ ret = 0;
+out:
+ if (op_version_str)
+ GF_FREE(op_version_str);
+ if (handle)
+ gf_store_handle_destroy(handle);
+ return ret;
+}
+
+int
glusterd_retrieve_op_version(xlator_t *this, int *op_version)
{
char *op_version_str = NULL;
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index 5db77703482..63e7617b1dc 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -156,6 +156,12 @@ int
glusterd_retrieve_op_version(xlator_t *this, int *op_version);
int
+glusterd_retrieve_max_op_version(xlator_t *this, int *op_version);
+
+int
+glusterd_store_max_op_version(xlator_t *this);
+
+int
glusterd_store_global_info(xlator_t *this);
int32_t
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index b1fa6247ee1..a3082717c27 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -1404,6 +1404,7 @@ init(xlator_t *this)
gf_boolean_t downgrade = _gf_false;
char *localtime_logging = NULL;
int32_t len = 0;
+ int op_version = 0;
#ifndef GF_DARWIN_HOST_OS
{
@@ -1979,17 +1980,33 @@ init(xlator_t *this)
}
GF_ATOMIC_INIT(conf->blockers, 0);
+ ret = glusterd_handle_upgrade_downgrade(this->options, conf, upgrade,
+ downgrade);
+ if (ret)
+ goto out;
+
+ ret = glusterd_retrieve_max_op_version(this, &op_version);
+ /* first condition indicates file isn't present which means this code
+ * change is hitting for the first time or someone has deleted it from the
+ * backend.second condition is when max op_version differs, in both cases
+ * volfiles should be regenerated
+ */
+ if (op_version == 0 || op_version != GD_OP_VERSION_MAX) {
+ gf_log(this->name, GF_LOG_INFO,
+ "Regenerating volfiles due to a max op-version mismatch or "
+ "glusterd.upgrade file not being present, op_version retrieved:"
+ "%d, max op_version: %d",
+ op_version, GD_OP_VERSION_MAX);
+ glusterd_recreate_volfiles(conf);
+ ret = glusterd_store_max_op_version(this);
+ }
+
/* If the peer count is less than 2 then this would be the best time to
* spawn process/bricks that may need (re)starting since last time
* (this) glusterd was up. */
if (glusterd_get_peers_count() < 2)
glusterd_launch_synctask(glusterd_spawn_daemons, NULL);
- ret = glusterd_handle_upgrade_downgrade(this->options, conf, upgrade,
- downgrade);
- if (ret)
- goto out;
-
ret = glusterd_hooks_spawn_worker(this);
if (ret)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index be1eed04a68..bbe1c7b535f 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -599,6 +599,9 @@ typedef enum {
#define GLUSTERD_DEFAULT_PORT GF_DEFAULT_BASE_PORT
#define GLUSTERD_INFO_FILE "glusterd.info"
+#define GLUSTERD_UPGRADE_FILE \
+ "glusterd.upgrade" /* zero byte file to detect a need for regenerating \
+ volfiles in container mode */
#define GLUSTERD_VOLUME_QUOTA_CONFIG "quota.conf"
#define GLUSTERD_VOLUME_DIR_PREFIX "vols"
#define GLUSTERD_PEER_DIR_PREFIX "peers"
@@ -1507,4 +1510,8 @@ glusterd_tier_prevalidate(dict_t *dict, char **op_errstr, dict_t *rsp_dict,
int
glusterd_options_init(xlator_t *this);
+
+int32_t
+glusterd_recreate_volfiles(glusterd_conf_t *conf);
+
#endif