e7a346
From 647b4d4e8edefd256de2a9f3916763b8cfa8429b Mon Sep 17 00:00:00 2001
e7a346
From: Atin Mukherjee <amukherj@redhat.com>
e7a346
Date: Tue, 20 Nov 2018 12:32:32 +0530
e7a346
Subject: [PATCH 467/493] glusterd: glusterd to regenerate volfiles when
e7a346
 GD_OP_VERSION_MAX changes
e7a346
e7a346
While glusterd has an infra to allow post install of spec to bring it up
e7a346
in the interim upgrade mode to allow all the volfiles to be regenerated
e7a346
with the latest executable, in container world the same methodology is
e7a346
not followed as container image always point to the specific gluster rpm
e7a346
and gluster rpm doesn't go through an upgrade process.
e7a346
e7a346
This fix does the following:
e7a346
1. If glusterd.upgrade file doesn't exist, regenerate the volfiles
e7a346
2. If maximum-operating-version read from glusterd.upgrade doesn't match
e7a346
with GD_OP_VERSION_MAX, glusterd detects it to be a version where new
e7a346
options are introduced and regenerate the volfiles.
e7a346
e7a346
Tests done:
e7a346
e7a346
1. Bring up glusterd, check if glusterd.upgrade file has been created
e7a346
with GD_OP_VERSION_MAX value.
e7a346
2. Post 1, restart glusterd and check glusterd hasn't regenerated the
e7a346
volfiles as there's is no change in the GD_OP_VERSION_MAX vs the
e7a346
op_version read from the file.
e7a346
3. Bump up the GD_OP_VERSION_MAX in the code by 1 and post compilation
e7a346
restart glusterd where the volfiles should be again regenerated.
e7a346
e7a346
Note: The old way of having volfiles regenerated during an rpm upgrade
e7a346
is kept as it is for now but eventually this can be sunset later.
e7a346
e7a346
> Change-Id: I75b49a1601c71e99f6a6bc360dd12dd03a96414b
e7a346
> Fixes: bz#1651463
e7a346
> Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
e7a346
upstream patch: https://review.gluster.org/#/c/glusterfs/+/21687/
e7a346
e7a346
Change-Id: I75b49a1601c71e99f6a6bc360dd12dd03a96414b
e7a346
BUG: 1651460
e7a346
Signed-off-by: Sanju Rakonde <srakonde@redhat.com>
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/158645
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
---
e7a346
 xlators/mgmt/glusterd/src/glusterd-store.c | 126 +++++++++++++++++++++++++++--
e7a346
 xlators/mgmt/glusterd/src/glusterd-store.h |   6 ++
e7a346
 xlators/mgmt/glusterd/src/glusterd.c       |  27 +++++--
e7a346
 xlators/mgmt/glusterd/src/glusterd.h       |   7 ++
e7a346
 4 files changed, 154 insertions(+), 12 deletions(-)
e7a346
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
e7a346
index 37542e7..f276fef 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
e7a346
@@ -2063,7 +2063,7 @@ glusterd_store_global_info (xlator_t *this)
e7a346
         }
e7a346
 
e7a346
         handle->fd = gf_store_mkstemp (handle);
e7a346
-        if (handle->fd <= 0) {
e7a346
+        if (handle->fd < 0) {
e7a346
                 ret = -1;
e7a346
                 goto out;
e7a346
         }
e7a346
@@ -2081,7 +2081,7 @@ glusterd_store_global_info (xlator_t *this)
e7a346
                 goto out;
e7a346
         }
e7a346
 
e7a346
-        snprintf (op_version_str, 15, "%d", conf->op_version);
e7a346
+        snprintf (op_version_str, sizeof(op_version_str), "%d", conf->op_version);
e7a346
         ret = gf_store_save_value (handle->fd, GD_OP_VERSION_KEY,
e7a346
                                    op_version_str);
e7a346
         if (ret) {
e7a346
@@ -2094,12 +2094,8 @@ glusterd_store_global_info (xlator_t *this)
e7a346
         ret = gf_store_rename_tmppath (handle);
e7a346
 out:
e7a346
         if (handle) {
e7a346
-                if (ret && (handle->fd > 0))
e7a346
+                if (ret && (handle->fd >= 0))
e7a346
                         gf_store_unlink_tmppath (handle);
e7a346
-
e7a346
-                if (handle->fd > 0) {
e7a346
-                        handle->fd = 0;
e7a346
-                }
e7a346
         }
e7a346
 
e7a346
         if (uuid_str)
e7a346
@@ -2114,6 +2110,122 @@ out:
e7a346
 }
e7a346
 
e7a346
 int
e7a346
+glusterd_store_max_op_version(xlator_t *this)
e7a346
+{
e7a346
+        int ret = -1;
e7a346
+        glusterd_conf_t *conf = NULL;
e7a346
+        char op_version_str[15] = {0,};
e7a346
+        char path[PATH_MAX] = {0,};
e7a346
+        gf_store_handle_t *handle = NULL;
e7a346
+        int32_t len = 0;
e7a346
+
e7a346
+        conf = this->private;
e7a346
+
e7a346
+        len = snprintf(path, PATH_MAX, "%s/%s", conf->workdir,
e7a346
+                       GLUSTERD_UPGRADE_FILE);
e7a346
+        if ((len < 0) || (len >= PATH_MAX)) {
e7a346
+                goto out;
e7a346
+        }
e7a346
+        ret = gf_store_handle_new(path, &handle);
e7a346
+        if (ret) {
e7a346
+                gf_msg(this->name, GF_LOG_ERROR, 0,
e7a346
+                       GD_MSG_STORE_HANDLE_GET_FAIL, "Unable to get store "
e7a346
+                       "handle");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        /* These options need to be available for all users */
e7a346
+        ret = sys_chmod(handle->path, 0644);
e7a346
+        if (ret) {
e7a346
+                gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED,
e7a346
+                       "chmod error for %s", GLUSTERD_UPGRADE_FILE);
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        handle->fd = gf_store_mkstemp(handle);
e7a346
+        if (handle->fd < 0) {
e7a346
+                ret = -1;
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        snprintf(op_version_str, sizeof(op_version_str), "%d",
e7a346
+                 GD_OP_VERSION_MAX);
e7a346
+        ret = gf_store_save_value(handle->fd, GD_MAX_OP_VERSION_KEY,
e7a346
+                                  op_version_str);
e7a346
+        if (ret) {
e7a346
+                gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_VERS_STORE_FAIL,
e7a346
+                       "Storing op-version failed ret = %d", ret);
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = gf_store_rename_tmppath(handle);
e7a346
+out:
e7a346
+        if (handle) {
e7a346
+                if (ret && (handle->fd >= 0))
e7a346
+                        gf_store_unlink_tmppath(handle);
e7a346
+        }
e7a346
+
e7a346
+        if (ret)
e7a346
+                gf_msg(this->name, GF_LOG_ERROR, 0,
e7a346
+                       GD_MSG_GLUSTERD_GLOBAL_INFO_STORE_FAIL,
e7a346
+                       "Failed to store max op-version");
e7a346
+        if (handle)
e7a346
+                gf_store_handle_destroy(handle);
e7a346
+        return ret;
e7a346
+}
e7a346
+
e7a346
+int
e7a346
+glusterd_retrieve_max_op_version(xlator_t *this, int *op_version)
e7a346
+{
e7a346
+        char *op_version_str = NULL;
e7a346
+        glusterd_conf_t *priv = NULL;
e7a346
+        int ret = -1;
e7a346
+        int tmp_version = 0;
e7a346
+        char *tmp = NULL;
e7a346
+        char path[PATH_MAX] = {0,};
e7a346
+        gf_store_handle_t *handle = NULL;
e7a346
+        int32_t len = 0;
e7a346
+
e7a346
+        priv = this->private;
e7a346
+
e7a346
+        len = snprintf(path, PATH_MAX, "%s/%s", priv->workdir,
e7a346
+                       GLUSTERD_UPGRADE_FILE);
e7a346
+        if ((len < 0) || (len >= PATH_MAX)) {
e7a346
+                goto out;
e7a346
+        }
e7a346
+        ret = gf_store_handle_retrieve(path, &handle);
e7a346
+
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "Unable to get store handle!");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = gf_store_retrieve_value(handle, GD_MAX_OP_VERSION_KEY,
e7a346
+                                      &op_version_str);
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "No previous op_version present");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        tmp_version = strtol(op_version_str, &tmp, 10);
e7a346
+        if ((tmp_version <= 0) || (tmp && strlen(tmp) > 1)) {
e7a346
+                gf_msg(this->name, GF_LOG_WARNING, EINVAL,
e7a346
+                       GD_MSG_UNSUPPORTED_VERSION, "invalid version number");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        *op_version = tmp_version;
e7a346
+
e7a346
+        ret = 0;
e7a346
+out:
e7a346
+        if (op_version_str)
e7a346
+                GF_FREE(op_version_str);
e7a346
+        if (handle)
e7a346
+                gf_store_handle_destroy(handle);
e7a346
+        return ret;
e7a346
+}
e7a346
+
e7a346
+int
e7a346
 glusterd_retrieve_op_version (xlator_t *this, int *op_version)
e7a346
 {
e7a346
         char                    *op_version_str = NULL;
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
e7a346
index 383a475..76c5500 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
e7a346
@@ -161,6 +161,12 @@ glusterd_retrieve_op_version (xlator_t *this, int *op_version);
e7a346
 int
e7a346
 glusterd_store_global_info (xlator_t *this);
e7a346
 
e7a346
+int
e7a346
+glusterd_retrieve_max_op_version(xlator_t *this, int *op_version);
e7a346
+
e7a346
+int
e7a346
+glusterd_store_max_op_version(xlator_t *this);
e7a346
+
e7a346
 int32_t
e7a346
 glusterd_store_retrieve_options (xlator_t *this);
e7a346
 
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
e7a346
index ca17526..29d5de1 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd.c
e7a346
@@ -1428,6 +1428,7 @@ init (xlator_t *this)
e7a346
         gf_boolean_t       upgrade                    = _gf_false;
e7a346
         gf_boolean_t       downgrade                  = _gf_false;
e7a346
         char              *localtime_logging          = NULL;
e7a346
+        int                op_version                 = 0;
e7a346
 
e7a346
 #ifndef GF_DARWIN_HOST_OS
e7a346
         {
e7a346
@@ -1976,6 +1977,27 @@ init (xlator_t *this)
e7a346
         }
e7a346
 
e7a346
         GF_ATOMIC_INIT(conf->blockers, 0);
e7a346
+        ret = glusterd_handle_upgrade_downgrade(this->options, conf, upgrade,
e7a346
+                                                downgrade);
e7a346
+        if (ret)
e7a346
+                goto out;
e7a346
+
e7a346
+        ret = glusterd_retrieve_max_op_version(this, &op_version);
e7a346
+        /* first condition indicates file isn't present which means this code
e7a346
+         * change is hitting for the first time or someone has deleted it from
e7a346
+         * the backend.second condition is when max op_version differs, in both
e7a346
+         * cases volfiles should be regenerated
e7a346
+         */
e7a346
+        if (op_version == 0 || op_version != GD_OP_VERSION_MAX) {
e7a346
+                gf_log(this->name, GF_LOG_INFO,
e7a346
+                       "Regenerating volfiles due to a max op-version mismatch "
e7a346
+                       "or glusterd.upgrade file not being present, op_version "
e7a346
+                       "retrieved: %d, max op_version: %d", op_version,
e7a346
+                       GD_OP_VERSION_MAX);
e7a346
+                glusterd_recreate_volfiles(conf);
e7a346
+                ret = glusterd_store_max_op_version(this);
e7a346
+        }
e7a346
+
e7a346
         /* If the peer count is less than 2 then this would be the best time to
e7a346
          * spawn process/bricks that may need (re)starting since last time
e7a346
          * (this) glusterd was up. */
e7a346
@@ -1983,11 +2005,6 @@ init (xlator_t *this)
e7a346
                 glusterd_launch_synctask (glusterd_spawn_daemons, NULL);
e7a346
 
e7a346
 
e7a346
-        ret = glusterd_handle_upgrade_downgrade (this->options, conf, upgrade,
e7a346
-                                                 downgrade);
e7a346
-        if (ret)
e7a346
-                goto out;
e7a346
-
e7a346
         ret = glusterd_hooks_spawn_worker (this);
e7a346
         if (ret)
e7a346
                 goto out;
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
e7a346
index bfa8310..cbdca52 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd.h
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd.h
e7a346
@@ -582,6 +582,9 @@ typedef enum {
e7a346
 
e7a346
 #define GLUSTERD_DEFAULT_PORT    GF_DEFAULT_BASE_PORT
e7a346
 #define GLUSTERD_INFO_FILE      "glusterd.info"
e7a346
+#define GLUSTERD_UPGRADE_FILE                                                  \
e7a346
+    "glusterd.upgrade" /* zero byte file to detect a need for regenerating     \
e7a346
+                          volfiles in container mode */
e7a346
 #define GLUSTERD_VOLUME_QUOTA_CONFIG "quota.conf"
e7a346
 #define GLUSTERD_VOLUME_DIR_PREFIX "vols"
e7a346
 #define GLUSTERD_PEER_DIR_PREFIX "peers"
e7a346
@@ -1333,4 +1336,8 @@ glusterd_tier_prevalidate (dict_t *dict, char **op_errstr,
e7a346
 
e7a346
 int
e7a346
 glusterd_options_init (xlator_t *this);
e7a346
+
e7a346
+int32_t
e7a346
+glusterd_recreate_volfiles(glusterd_conf_t *conf);
e7a346
+
e7a346
 #endif
e7a346
-- 
e7a346
1.8.3.1
e7a346