diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-utils.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 463 |
1 files changed, 419 insertions, 44 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index bd9f7ba39af..6f48767b8a3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -230,10 +230,10 @@ glusterd_get_uuid (uuid_t *uuid) int glusterd_submit_request_unlocked (struct rpc_clnt *rpc, void *req, - call_frame_t *frame, rpc_clnt_prog_t *prog, - int procnum, struct iobref *iobref, - xlator_t *this, fop_cbk_fn_t cbkfn, - xdrproc_t xdrproc) + call_frame_t *frame, rpc_clnt_prog_t *prog, + int procnum, struct iobref *iobref, + xlator_t *this, fop_cbk_fn_t cbkfn, + xdrproc_t xdrproc) { int ret = -1; struct iobuf *iobuf = NULL; @@ -312,17 +312,17 @@ glusterd_submit_request (struct rpc_clnt *rpc, void *req, xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) { glusterd_conf_t *priv = THIS->private; - int ret = -1; + int ret = -1; - synclock_unlock (&priv->big_lock); - { - ret = glusterd_submit_request_unlocked (rpc, req, frame, prog, - procnum, iobref, this, - cbkfn, xdrproc); - } - synclock_lock (&priv->big_lock); + synclock_unlock (&priv->big_lock); + { + ret = glusterd_submit_request_unlocked (rpc, req, frame, prog, + procnum, iobref, this, + cbkfn, xdrproc); + } + synclock_lock (&priv->big_lock); - return ret; + return ret; } @@ -1919,7 +1919,6 @@ glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo, char socketpath[PATH_MAX] = {0}; xlator_t *this = NULL; glusterd_conf_t *priv = NULL; - int ret = 0; GF_ASSERT (volinfo); GF_ASSERT (brickinfo); @@ -1931,15 +1930,8 @@ glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo, GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); glusterd_set_brick_socket_filepath (volinfo, brickinfo, socketpath, sizeof (socketpath)); - ret = unlink (socketpath); - if (ret && (ENOENT == errno)) { - ret = 0; - } else { - gf_log (this->name, GF_LOG_ERROR, "Failed to remove %s" - " error: %s", socketpath, strerror (errno)); - } - return ret; + return glusterd_unlink_file (socketpath); } int32_t @@ -3124,9 +3116,9 @@ glusterd_compare_friend_volume (dict_t *peer_data, int32_t count, *status = GLUSTERD_VOL_COMP_UPDATE_REQ; goto out; } else if (version < volinfo->version) { - *status = GLUSTERD_VOL_COMP_SCS; - goto out; - } + *status = GLUSTERD_VOL_COMP_SCS; + goto out; + } //Now, versions are same, compare cksums. // @@ -3443,6 +3435,7 @@ glusterd_spawn_daemons (void *opaque) { glusterd_conf_t *conf = THIS->private; gf_boolean_t start_bricks = !conf->restart_done; + int ret = -1; if (start_bricks) { glusterd_restart_bricks (conf); @@ -3450,7 +3443,9 @@ glusterd_spawn_daemons (void *opaque) } glusterd_restart_gsyncds (conf); glusterd_restart_rebalance (conf); - return 0; + ret = glusterd_restart_snapds (conf); + + return ret; } void @@ -5526,7 +5521,7 @@ out: void glusterd_get_nodesvc_dir (char *server, char *workdir, - char *path, size_t len) + char *path, size_t len) { GF_ASSERT (len == PATH_MAX); snprintf (path, len, "%s/%s", workdir, server); @@ -5534,7 +5529,7 @@ glusterd_get_nodesvc_dir (char *server, char *workdir, void glusterd_get_nodesvc_rundir (char *server, char *workdir, - char *path, size_t len) + char *path, size_t len) { char dir[PATH_MAX] = {0}; GF_ASSERT (len == PATH_MAX); @@ -5545,7 +5540,7 @@ glusterd_get_nodesvc_rundir (char *server, char *workdir, void glusterd_get_nodesvc_pidfile (char *server, char *workdir, - char *path, size_t len) + char *path, size_t len) { char dir[PATH_MAX] = {0}; GF_ASSERT (len == PATH_MAX); @@ -5556,7 +5551,7 @@ glusterd_get_nodesvc_pidfile (char *server, char *workdir, void glusterd_get_nodesvc_volfile (char *server, char *workdir, - char *volfile, size_t len) + char *volfile, size_t len) { char dir[PATH_MAX] = {0,}; GF_ASSERT (len == PATH_MAX); @@ -5666,6 +5661,12 @@ out: return rpc; } +inline struct rpc_clnt* +glusterd_snapd_get_rpc (glusterd_volinfo_t *volinfo) +{ + return volinfo->snapd.rpc; +} + struct rpc_clnt* glusterd_nodesvc_get_rpc (char *server) { @@ -5715,7 +5716,8 @@ glusterd_nodesvc_set_rpc (char *server, struct rpc_clnt *rpc) } int32_t -glusterd_nodesvc_connect (char *server, char *socketpath) { +glusterd_nodesvc_connect (char *server, char *socketpath) +{ int ret = 0; dict_t *options = NULL; struct rpc_clnt *rpc = NULL; @@ -5899,9 +5901,25 @@ glusterd_is_nodesvc_running (char *server) } int32_t -glusterd_nodesvc_unlink_socket_file (char *server) +glusterd_unlink_file (char *sockfpath) { int ret = 0; + + ret = unlink (sockfpath); + if (ret) { + if (ENOENT == errno) + ret = 0; + else + gf_log (THIS->name, GF_LOG_ERROR, "Failed to remove %s" + " error: %s", sockfpath, strerror (errno)); + } + + return ret; +} + +int32_t +glusterd_nodesvc_unlink_socket_file (char *server) +{ char sockfpath[PATH_MAX] = {0,}; char rundir[PATH_MAX] = {0,}; glusterd_conf_t *priv = THIS->private; @@ -5912,15 +5930,7 @@ glusterd_nodesvc_unlink_socket_file (char *server) glusterd_nodesvc_set_socket_filepath (rundir, MY_UUID, sockfpath, sizeof (sockfpath)); - ret = unlink (sockfpath); - if (ret && (ENOENT == errno)) { - ret = 0; - } else { - gf_log (THIS->name, GF_LOG_ERROR, "Failed to remove %s" - " error: %s", sockfpath, strerror (errno)); - } - - return ret; + return glusterd_unlink_file (sockfpath); } int32_t @@ -5936,7 +5946,7 @@ glusterd_nodesvc_stop (char *server, int sig) (void)glusterd_nodesvc_disconnect (server); glusterd_get_nodesvc_pidfile (server, priv->workdir, - pidfile, sizeof (pidfile)); + pidfile, sizeof (pidfile)); ret = glusterd_service_stop (server, pidfile, sig, _gf_true); if (ret == 0) { @@ -6218,7 +6228,6 @@ out: return ret; } - int glusterd_check_generate_start_nfs () { @@ -7876,7 +7885,7 @@ glusterd_sm_tr_log_transition_add_to_dict (dict_t *dict, { int ret = -1; char key[512] = {0}; - char timestr[64] = {0,}; + char timestr[64] = {0,}; char *str = NULL; GF_ASSERT (dict); @@ -12890,3 +12899,369 @@ glusterd_enable_default_options (glusterd_volinfo_t *volinfo, char *option) out: return ret; } + +/* Snapd functions */ +int +glusterd_is_snapd_enabled (glusterd_volinfo_t *volinfo) +{ + int ret = 0; + xlator_t *this = THIS; + + ret = dict_get_str_boolean (volinfo->dict, "features.uss", -2); + if (ret == -2) { + gf_log (this->name, GF_LOG_DEBUG, "Key features.uss not " + "present in the volinfo dict"); + ret = 0; + + } else if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, "Failed to get " + "'features.uss' from %s volume dict", + volinfo->volname); + ret = 0; + } + + return ret; +} + +void +glusterd_get_snapd_rundir (glusterd_volinfo_t *volinfo, + char *path, int path_len) +{ + char workdir [PATH_MAX] = {0,}; + glusterd_conf_t *priv = THIS->private; + + GLUSTERD_GET_VOLUME_DIR (workdir, volinfo, priv); + + snprintf (path, path_len, "%s/run", workdir); +} + +void +glusterd_get_snapd_volfile (glusterd_volinfo_t *volinfo, + char *path, int path_len) +{ + char workdir [PATH_MAX] = {0,}; + glusterd_conf_t *priv = THIS->private; + + GLUSTERD_GET_VOLUME_DIR (workdir, volinfo, priv); + + snprintf (path, path_len, "%s/%s-snapd.vol", workdir, + volinfo->volname); +} + +void +glusterd_get_snapd_pidfile (glusterd_volinfo_t *volinfo, + char *path, int path_len) +{ + char rundir [PATH_MAX] = {0,}; + + glusterd_get_snapd_rundir (volinfo, rundir, sizeof (rundir)); + + snprintf (path, path_len, "%s/%s-snapd.pid", rundir, volinfo->volname); +} + +void +glusterd_set_snapd_socket_filepath (glusterd_volinfo_t *volinfo, + char *path, int path_len) +{ + char sockfilepath[PATH_MAX] = {0,}; + char rundir[PATH_MAX] = {0,}; + + glusterd_get_snapd_rundir (volinfo, rundir, sizeof (rundir)); + snprintf (sockfilepath, sizeof (sockfilepath), "%s/run-%s", + rundir, uuid_utoa (MY_UUID)); + + glusterd_set_socket_filepath (sockfilepath, path, path_len); +} + +gf_boolean_t +glusterd_is_snapd_running (glusterd_volinfo_t *volinfo) +{ + char pidfile [PATH_MAX] = {0,}; + int pid = -1; + glusterd_conf_t *priv = THIS->private; + + glusterd_get_snapd_pidfile (volinfo, pidfile, + sizeof (pidfile)); + + return gf_is_service_running (pidfile, &pid); +} + +int +glusterd_restart_snapds (glusterd_conf_t *priv) +{ + glusterd_volinfo_t *volinfo = NULL; + int ret = 0; + xlator_t *this = THIS; + + list_for_each_entry (volinfo, &priv->volumes, vol_list) { + if (volinfo->status == GLUSTERD_STATUS_STARTED && + glusterd_is_snapd_enabled (volinfo)) { + ret = glusterd_snapd_start (volinfo, _gf_false); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Couldn't start snapd for vol: %s", + volinfo->volname); + goto out; + } + } + } +out: + return ret; +} + +gf_boolean_t +glusterd_is_snapd_online (glusterd_volinfo_t *volinfo) +{ + return volinfo->snapd.online; +} + +void +glusterd_snapd_set_online_status (glusterd_volinfo_t *volinfo, + gf_boolean_t status) +{ + volinfo->snapd.online = status; +} + +inline void +glusterd_snapd_set_rpc (glusterd_volinfo_t *volinfo, struct rpc_clnt *rpc) +{ + volinfo->snapd.rpc = rpc; +} + +int32_t +glusterd_snapd_connect (glusterd_volinfo_t *volinfo, char *socketpath) +{ + int ret = 0; + dict_t *options = NULL; + struct rpc_clnt *rpc = NULL; + glusterd_conf_t *priv = THIS->private; + + rpc = glusterd_snapd_get_rpc (volinfo); + + if (rpc == NULL) { + /* Setting frame-timeout to 10mins (600seconds). + * Unix domain sockets ensures that the connection is reliable. + * The default timeout of 30mins used for unreliable network + * connections is too long for unix domain socket connections. + */ + ret = rpc_transport_unix_options_build (&options, socketpath, + 600); + if (ret) + goto out; + + glusterd_volinfo_ref (volinfo); + + synclock_unlock (&priv->big_lock); + ret = glusterd_rpc_create (&rpc, options, + glusterd_snapd_rpc_notify, + volinfo); + synclock_lock (&priv->big_lock); + if (ret) + goto out; + + (void) glusterd_snapd_set_rpc (volinfo, rpc); + } +out: + return ret; +} + +int32_t +glusterd_snapd_disconnect (glusterd_volinfo_t *volinfo) +{ + struct rpc_clnt *rpc = NULL; + glusterd_conf_t *priv = THIS->private; + + rpc = glusterd_snapd_get_rpc (volinfo); + (void)glusterd_snapd_set_rpc (volinfo, NULL); + + if (rpc) + glusterd_rpc_clnt_unref (priv, rpc); + + return 0; +} + +int32_t +glusterd_snapd_start (glusterd_volinfo_t *volinfo, gf_boolean_t wait) +{ + int32_t ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *priv = NULL; + runner_t runner = {0,}; + char pidfile[PATH_MAX] = {0,}; + char logfile[PATH_MAX] = {0,}; + char volfile[PATH_MAX] = {0,}; + char glusterd_uuid [1024] = {0,}; + char rundir[PATH_MAX] = {0,}; + char sockfpath[PATH_MAX] = {0,}; + char volfileid[256] = {0}; + char valgrind_logfile[PATH_MAX] = {0}; + int snapd_port = 0; + char *volname = volinfo->volname; + char snapd_id [PATH_MAX] = {0,}; + char msg [1024] = {0,}; + + this = THIS; + GF_ASSERT(this); + + if (glusterd_is_snapd_running (volinfo)) { + ret = 0; + goto connect; + } + + priv = this->private; + + glusterd_get_snapd_rundir (volinfo, rundir, sizeof (rundir)); + ret = mkdir (rundir, 0777); + + if ((ret == -1) && (EEXIST != errno)) { + gf_log (this->name, GF_LOG_ERROR, "Unable to create rundir %s", + rundir); + goto out; + } + + glusterd_get_snapd_pidfile (volinfo, pidfile, sizeof (pidfile)); + glusterd_get_snapd_volfile (volinfo, volfile, sizeof (volfile)); + + ret = sys_access (volfile, F_OK); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "snapd Volfile %s is not present", volfile); + goto out; + } + + snprintf (logfile, PATH_MAX, "%s/%s-snapd.log", + DEFAULT_LOG_FILE_DIRECTORY, volname); + + snprintf (volfileid, sizeof (volfileid), "snapd/%s", volname); + glusterd_set_snapd_socket_filepath (volinfo, sockfpath, + sizeof (sockfpath)); + + runinit (&runner); + + if (priv->valgrind) { + snprintf (valgrind_logfile, PATH_MAX, + "%s/valgrind-%s-snapd.log", + DEFAULT_LOG_FILE_DIRECTORY, volname); + + runner_add_args (&runner, "valgrind", "--leak-check=full", + "--trace-children=yes", "--track-origins=yes", + NULL); + runner_argprintf (&runner, "--log-file=%s", valgrind_logfile); + } + + snprintf (snapd_id, sizeof (snapd_id), "snapd-%s", volname); + runner_add_args (&runner, SBIN_DIR"/glusterfsd", + "-s", "localhost", + "--volfile-id", volfileid, + "-p", pidfile, + "-l", logfile, + "--brick-name", snapd_id, + "-S", sockfpath, NULL); + + snapd_port = volinfo->snapd.port; + if (!snapd_port) { + snapd_port = pmap_registry_alloc (THIS); + if (!snapd_port) { + snprintf (msg, sizeof (msg), "Could not allocate port " + "for snapd service for volume %s", volname); + + runner_log (&runner, this->name, GF_LOG_DEBUG, msg); + ret = -1; + goto out; + } + } + + runner_add_arg (&runner, "--brick-port"); + runner_argprintf (&runner, "%d", snapd_port); + runner_add_arg (&runner, "--xlator-option"); + runner_argprintf (&runner, "%s-server.listen-port=%d", + volname, snapd_port); + + snprintf (msg, sizeof (msg), + "Starting the snapd service for volume %s", volname); + runner_log (&runner, this->name, GF_LOG_DEBUG, msg); + + if (!wait) { + ret = runner_run_nowait (&runner); + } else { + synclock_unlock (&priv->big_lock); + { + ret = runner_run (&runner); + } + synclock_lock (&priv->big_lock); + } + +connect: + if (ret == 0) + glusterd_snapd_connect (volinfo, sockfpath); + +out: + return ret; +} + +int +glusterd_snapd_stop (glusterd_volinfo_t *volinfo) +{ + char pidfile [PATH_MAX] = {0,}; + char sockfpath [PATH_MAX] = {0,}; + glusterd_conf_t *priv = THIS->private; + int ret = 0; + + (void)glusterd_snapd_disconnect (volinfo); + + if (!glusterd_is_snapd_running (volinfo)) + goto out; + + glusterd_get_snapd_pidfile (volinfo, pidfile, sizeof (pidfile)); + ret = glusterd_service_stop ("snapd", pidfile, SIGTERM, _gf_true); + + if (ret == 0) { + glusterd_set_snapd_socket_filepath (volinfo, sockfpath, + sizeof (sockfpath)); + (void)glusterd_unlink_file (sockfpath); + } +out: + return ret; +} + +int +glusterd_handle_snapd_option (glusterd_volinfo_t *volinfo) +{ + int ret = 0; + xlator_t *this = THIS; + + if (volinfo->is_snap_volume) + return 0; + + if (glusterd_is_snapd_enabled (volinfo)) { + if (!glusterd_is_volume_started (volinfo)) + goto out; + + ret = glusterd_create_snapd_volfile (volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Couldn't create " + "snapd volfile for volume: %s", + volinfo->volname); + goto out; + } + + ret = glusterd_snapd_start (volinfo, _gf_false); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Couldn't start " + "snapd for volume: %s", volinfo->volname); + goto out; + } + + } else if (glusterd_is_snapd_running (volinfo)) { + ret = glusterd_snapd_stop (volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Couldn't stop snapd for volume: %s", + volinfo->volname); + goto out; + } + } + +out: + return ret; +} |