diff options
-rw-r--r-- | libglusterfs/src/globals.h | 4 | ||||
-rw-r--r-- | libglusterfs/src/glusterfs.h | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 86 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 81 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 141 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 10 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 52 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.h | 3 |
8 files changed, 280 insertions, 98 deletions
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h index 9bc12f74eaa..cf9ae9a417b 100644 --- a/libglusterfs/src/globals.h +++ b/libglusterfs/src/globals.h @@ -62,11 +62,9 @@ #define GD_OP_VERSION_3_7_7 30707 /* Op-version for GlusterFS 3.7.7 */ -/* Op-version was not bumped up for 3.7.8 */ - #define GD_OP_VERSION_3_7_9 30709 /* Op-version for GlusterFS 3.7.9 */ -#define GD_OP_VERSION_3_7_10 30710 /* Op-version for GlusterFS 3.7.10 */ +#define GD_OP_VERSION_3_7_10 30710 /* Op-version for GlusterFS 3.7.10 */ #define GD_OP_VERSION_4_0_0 40000 /* Op-version for GlusterFS 4.0.0 */ diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 9dcaadfa645..a037cb5cbbd 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -171,6 +171,7 @@ #define GF_AFR_SBRAIN_CHOICE "replica.split-brain-choice" #define GF_AFR_SPB_CHOICE_TIMEOUT "replica.split-brain-choice-timeout" #define GF_AFR_SBRAIN_RESOLVE "replica.split-brain-heal-finalize" +#define GF_AFR_ADD_BRICK "trusted.add-brick" #define GF_AFR_REPLACE_BRICK "trusted.replace-brick" #define GF_AFR_DIRTY "trusted.afr.dirty" diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index d77626d3457..920f7f05623 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -21,6 +21,7 @@ #include "glusterd-messages.h" #include "glusterd-server-quorum.h" #include "run.h" +#include "glusterd-volgen.h" #include <sys/signal.h> /* misc */ @@ -1233,6 +1234,7 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, char *brick_mount_dir = NULL; xlator_t *this = NULL; glusterd_conf_t *conf = NULL; + gf_boolean_t is_valid_add_brick = _gf_false; this = THIS; GF_ASSERT (this); @@ -1320,6 +1322,7 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, /* Gets changed only if the options are given in add-brick cli */ if (type) volinfo->type = type; + if (replica_count) { volinfo->replica_count = replica_count; } @@ -1355,6 +1358,27 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, CAPS_OFFLOAD_COPY | CAPS_OFFLOAD_SNAPSHOT; #endif + /* This check needs to be added to distinguish between + * attach-tier commands and add-brick commands. + * When a tier is attached, adding is done via add-brick + * and setting of pending xattrs shouldn't be done for + * attach-tiers as they are virtually new volumes. + */ + if (glusterd_is_volume_replicate (volinfo)) { + if (replica_count && + !dict_get (dict, "attach-tier") && + conf->op_version >= GD_OP_VERSION_3_7_10) { + is_valid_add_brick = _gf_true; + ret = generate_dummy_client_volfiles (volinfo); + if (ret) { + gf_msg (THIS->name, GF_LOG_ERROR, 0, + GD_MSG_VOLFILE_CREATE_FAIL, + "Failed to create volfile."); + goto out; + } + } + } + while (i <= count) { ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo, &brickinfo); @@ -1386,6 +1410,16 @@ glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count, } } + /* if the volume is a replicate volume, do: */ + if (is_valid_add_brick) { + if (!gf_uuid_compare (brickinfo->uuid, MY_UUID)) { + ret = glusterd_handle_replicate_brick_ops ( + volinfo, brickinfo, + GD_OP_ADD_BRICK); + if (ret < 0) + goto out; + } + } ret = glusterd_brick_start (volinfo, brickinfo, _gf_true); if (ret) @@ -1514,22 +1548,6 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict) conf = this->private; GF_ASSERT (conf); - ret = dict_get_int32 (dict, "replica-count", &replica_count); - if (ret) { - gf_msg_debug (THIS->name, 0, - "Unable to get replica count"); - } - - if (replica_count > 0) { - ret = op_version_check (this, GD_OP_VER_PERSISTENT_AFR_XATTRS, - msg, sizeof(msg)); - if (ret) { - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_OP_VERSION_MISMATCH, "%s", msg); - *op_errstr = gf_strdup (msg); - goto out; - } - } ret = dict_get_str (dict, "volname", &volname); if (ret) { gf_msg (THIS->name, GF_LOG_ERROR, errno, @@ -1550,6 +1568,42 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict) if (ret) goto out; + ret = dict_get_int32 (dict, "replica-count", &replica_count); + if (ret) { + gf_msg_debug (THIS->name, 0, + "Unable to get replica count"); + } + + if (replica_count > 0) { + ret = op_version_check (this, GD_OP_VER_PERSISTENT_AFR_XATTRS, + msg, sizeof(msg)); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_OP_VERSION_MISMATCH, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + } + + /* Do not allow add-brick for stopped volumes when replica-count + * is being increased. + */ + if (glusterd_is_volume_replicate (volinfo)) { + if (conf->op_version >= GD_OP_VERSION_3_7_10 && + !dict_get (dict, "attach-tier") && + replica_count && + GLUSTERD_STATUS_STOPPED == volinfo->status) { + ret = -1; + snprintf (msg, sizeof (msg), " Volume must not be in" + " stopped state when replica-count needs to " + " be increased."); + gf_msg (THIS->name, GF_LOG_ERROR, 0, + GD_MSG_BRICK_ADD_FAIL, "%s", msg); + *op_errstr = gf_strdup (msg); + goto out; + } + } + if (conf->op_version > GD_OP_VERSION_3_7_5 && is_origin_glusterd (dict)) { ret = glusterd_validate_quorum (this, GD_OP_ADD_BRICK, dict, diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c index 093548de712..535f1256baf 100644 --- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c @@ -39,83 +39,6 @@ glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (rpcsvc_request_t *req, glusterd_op_t op, dict_t *dict); int -glusterd_handle_replicate_replace_brick (glusterd_volinfo_t *volinfo, - glusterd_brickinfo_t *brickinfo) -{ - int32_t ret = -1; - char tmpmount[] = "/tmp/mntXXXXXX"; - char logfile[PATH_MAX] = {0,}; - int dirty[3] = {0,}; - runner_t runner = {0}; - glusterd_conf_t *priv = NULL; - char *pid = NULL; - char *volfileserver = NULL; - - priv = THIS->private; - - dirty[2] = hton32(1); - - ret = sys_lsetxattr (brickinfo->path, GF_AFR_DIRTY, dirty, - sizeof (dirty), 0); - if (ret == -1) { - gf_msg (THIS->name, GF_LOG_ERROR, errno, - GD_MSG_SETXATTR_FAIL, "Failed to set extended" - " attribute %s : %s.", GF_AFR_DIRTY, strerror (errno)); - goto out; - } - - if (mkdtemp (tmpmount) == NULL) { - gf_msg (THIS->name, GF_LOG_ERROR, errno, - GD_MSG_DIR_OP_FAILED, - "failed to create a temporary mount directory."); - ret = -1; - goto out; - } - snprintf (logfile, sizeof (logfile), - DEFAULT_LOG_FILE_DIRECTORY"/%s-replace-brick-mount.log", - volinfo->volname); - - ret = gf_asprintf (&pid, "%d", GF_CLIENT_PID_SELF_HEALD); - if (ret < 0) - goto out; - - if (dict_get_str (THIS->options, "transport.socket.bind-address", - &volfileserver) != 0) - volfileserver = "localhost"; - - runinit (&runner); - runner_add_args (&runner, SBIN_DIR"/glusterfs", - "-s", volfileserver, - "--volfile-id", volinfo->volname, - "--client-pid", pid, - "-l", logfile, tmpmount, NULL); - synclock_unlock (&priv->big_lock); - ret = runner_run (&runner); - - if (ret) { - runner_log (&runner, THIS->name, GF_LOG_ERROR, "mount command" - "failed."); - goto lock; - } - ret = sys_lsetxattr (tmpmount, GF_AFR_REPLACE_BRICK, - brickinfo->brick_id, sizeof (brickinfo->brick_id), - 0); - if (ret == -1) - gf_msg (THIS->name, GF_LOG_ERROR, errno, - GD_MSG_SETXATTR_FAIL, "Failed to set extended" - " attribute %s : %s", GF_AFR_REPLACE_BRICK, - strerror (errno)); - gf_umount_lazy (THIS->name, tmpmount, 1); -lock: - synclock_lock (&priv->big_lock); -out: - if (pid) - GF_FREE (pid); - gf_msg_debug ("glusterd", 0, "Returning with ret"); - return ret; -} - -int __glusterd_handle_replace_brick (rpcsvc_request_t *req) { int32_t ret = -1; @@ -670,8 +593,8 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo, /* if the volume is a replicate volume, do: */ if (glusterd_is_volume_replicate (volinfo)) { if (!gf_uuid_compare (new_brickinfo->uuid, MY_UUID)) { - ret = glusterd_handle_replicate_replace_brick - (volinfo, new_brickinfo); + ret = glusterd_handle_replicate_brick_ops (volinfo, + new_brickinfo, GD_OP_REPLACE_BRICK); if (ret < 0) goto out; } diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 50cc4476fad..a0cc5d409c8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -7100,6 +7100,33 @@ void glusterd_update_tier_status (glusterd_volinfo_t *volinfo) { } int +glusterd_get_dummy_client_filepath (char *filepath, + glusterd_volinfo_t *volinfo, + gf_transport_type type) +{ + int ret = 0; + char path[PATH_MAX] = {0,}; + + switch (type) { + case GF_TRANSPORT_TCP: + case GF_TRANSPORT_BOTH_TCP_RDMA: + snprintf (filepath, PATH_MAX, + "/tmp/%s.tcp-fuse.vol", volinfo->volname); + break; + + case GF_TRANSPORT_RDMA: + snprintf (filepath, PATH_MAX, + "/tmp/%s.rdma-fuse.vol", volinfo->volname); + break; + default: + ret = -1; + break; + } + + return ret; +} + +int glusterd_volume_defrag_restart (glusterd_volinfo_t *volinfo, char *op_errstr, size_t len, int cmd, defrag_cbk_fn_t cbk) { @@ -11074,3 +11101,117 @@ gd_get_shd_key (int type) } return key; } + +int +glusterd_handle_replicate_brick_ops (glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t *brickinfo, + glusterd_op_t op) +{ + int32_t ret = -1; + char tmpmount[] = "/tmp/mntXXXXXX"; + char logfile[PATH_MAX] = {0,}; + int dirty[3] = {0,}; + runner_t runner = {0}; + glusterd_conf_t *priv = NULL; + char *pid = NULL; + char vpath[PATH_MAX] = {0,}; + char *volfileserver = NULL; + + priv = THIS->private; + GF_VALIDATE_OR_GOTO (THIS->name, priv, out); + + dirty[2] = hton32(1); + + ret = sys_lsetxattr (brickinfo->path, GF_AFR_DIRTY, dirty, + sizeof (dirty), 0); + if (ret == -1) { + gf_msg (THIS->name, GF_LOG_ERROR, errno, + GD_MSG_SETXATTR_FAIL, "Failed to set extended" + " attribute %s : %s.", GF_AFR_DIRTY, strerror (errno)); + goto out; + } + + if (mkdtemp (tmpmount) == NULL) { + gf_msg (THIS->name, GF_LOG_ERROR, errno, + GD_MSG_DIR_OP_FAILED, + "failed to create a temporary mount directory."); + ret = -1; + goto out; + } + + ret = gf_asprintf (&pid, "%d", GF_CLIENT_PID_SELF_HEALD); + if (ret < 0) + goto out; + + switch (op) { + case GD_OP_REPLACE_BRICK: + if (dict_get_str (THIS->options, "transport.socket.bind-address", + &volfileserver) != 0) + volfileserver = "localhost"; + + snprintf (logfile, sizeof (logfile), + DEFAULT_LOG_FILE_DIRECTORY"/%s-replace-brick-mount.log", + volinfo->volname); + if (!*logfile) { + ret = -1; + goto out; + } + runinit (&runner); + runner_add_args (&runner, SBIN_DIR"/glusterfs", + "-s", volfileserver, + "--volfile-id", volinfo->volname, + "--client-pid", pid, + "-l", logfile, tmpmount, NULL); + break; + + case GD_OP_ADD_BRICK: + snprintf (logfile, sizeof (logfile), + DEFAULT_LOG_FILE_DIRECTORY"/%s-add-brick-mount.log", + volinfo->volname); + if (!*logfile) { + ret = -1; + goto out; + } + ret = glusterd_get_dummy_client_filepath (vpath, volinfo, + volinfo->transport_type); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Failed to get " + "volfile path"); + goto out; + } + runinit (&runner); + runner_add_args (&runner, SBIN_DIR"/glusterfs", + "--volfile", vpath, + "--client-pid", pid, + "-l", logfile, tmpmount, NULL); + break; + default: + break; + } + synclock_unlock (&priv->big_lock); + ret = runner_run (&runner); + + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "mount command" + " failed."); + goto lock; + } + ret = sys_lsetxattr (tmpmount, (op == GD_OP_REPLACE_BRICK) ? + GF_AFR_REPLACE_BRICK : GF_AFR_ADD_BRICK, + brickinfo->brick_id, sizeof (brickinfo->brick_id), + 0); + if (ret == -1) + gf_msg (THIS->name, GF_LOG_ERROR, errno, + GD_MSG_SETXATTR_FAIL, "Failed to set extended" + " attribute %s : %s", (op == GD_OP_REPLACE_BRICK) ? + GF_AFR_REPLACE_BRICK : GF_AFR_ADD_BRICK, + strerror (errno)); + gf_umount_lazy (THIS->name, tmpmount, 1); +lock: + synclock_lock (&priv->big_lock); +out: + if (pid) + GF_FREE (pid); + gf_msg_debug ("glusterd", 0, "Returning with ret"); + return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 7195fe30658..50d691acad5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -690,4 +690,14 @@ int glusterd_volume_brick_for_each (glusterd_volinfo_t *volinfo, void *data, int (*fn) (glusterd_volinfo_t *, glusterd_brickinfo_t *, dict_t *mod_dict, void *)); + +int +glusterd_get_dummy_client_filepath (char *filepath, + glusterd_volinfo_t *volinfo, + gf_transport_type type); + +int +glusterd_handle_replicate_brick_ops (glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t *brickinfo, + glusterd_op_t op); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index cc599846bb9..b61c056507b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -5451,6 +5451,58 @@ enumerate_transport_reqs (gf_transport_type type, char **types) } int +generate_dummy_client_volfiles (glusterd_volinfo_t *volinfo) +{ + int i = 0; + int ret = -1; + char filepath[PATH_MAX] = {0,}; + char *types[] = {NULL, NULL, NULL}; + dict_t *dict = NULL; + xlator_t *this = NULL; + gf_transport_type type = GF_TRANSPORT_TCP; + + this = THIS; + + enumerate_transport_reqs (volinfo->transport_type, types); + dict = dict_new (); + if (!dict) + goto out; + for (i = 0; types[i]; i++) { + memset (filepath, 0, sizeof (filepath)); + ret = dict_set_str (dict, "client-transport-type", types[i]); + if (ret) + goto out; + type = transport_str_to_type (types[i]); + + ret = dict_set_uint32 (dict, "trusted-client", GF_CLIENT_OTHER); + if (ret) + goto out; + + ret = glusterd_get_dummy_client_filepath (filepath, + volinfo, type); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, EINVAL, + GD_MSG_INVALID_ENTRY, + "Received invalid transport-type."); + goto out; + } + + ret = generate_single_transport_client_volfile (volinfo, + filepath, + dict); + if (ret) + goto out; + } + +out: + if (dict) + dict_unref (dict); + + gf_msg_trace ("glusterd", 0, "Returning %d", ret); + return ret; +} + +int generate_client_volfiles (glusterd_volinfo_t *volinfo, glusterd_client_type_t client_type) { diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h index 36a50919d3c..9d206f692c1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -288,4 +288,7 @@ glusterd_volopt_validate (glusterd_volinfo_t *volinfo, dict_t *dict, char *key, gf_boolean_t gd_is_self_heal_enabled (glusterd_volinfo_t *volinfo, dict_t *dict); +int +generate_dummy_client_volfiles (glusterd_volinfo_t *volinfo); + #endif |