summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src
diff options
context:
space:
mode:
authorVarun Shastry <vshastry@redhat.com>2014-05-06 12:39:20 +0000
committerKrishnan Parthasarathi <kparthas@redhat.com>2014-06-03 00:08:29 -0700
commit0fe5ab5b9215b8f0ecfb8bc4ba15a5370850654a (patch)
tree713e00bd047e1703848a0e8529b5592e35638101 /xlators/mgmt/glusterd/src
parent15f7b4de1124a37a53c7ddb5635b005322b23025 (diff)
glusterd: Changes to provide interface for USS
The changes which consists of the translators for the USS (User Servicable Snapshots) is submitted as a separate patch. Current patch provides the CLI access to the feature. Change-Id: I6b98a42fcfa82f0870d8048fe0bb53141565e9c6 BUG: 1094815 Signed-off-by: Varun Shastry <vshastry@redhat.com> Reviewed-on: http://review.gluster.org/7705 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com> Tested-by: Krishnan Parthasarathi <kparthas@redhat.com>
Diffstat (limited to 'xlators/mgmt/glusterd/src')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c59
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c14
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c463
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h54
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c456
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c9
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c9
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h12
10 files changed, 913 insertions, 174 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index e203e5af01f..733bea236ed 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -4138,6 +4138,65 @@ glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
}
int
+__glusterd_snapd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
+ rpc_clnt_event_t event, void *data)
+{
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+ conf = this->private;
+ GF_ASSERT (conf);
+
+ volinfo = mydata;
+ if (!volinfo)
+ return 0;
+
+ switch (event) {
+ case RPC_CLNT_CONNECT:
+ gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
+
+ (void) glusterd_snapd_set_online_status (volinfo, _gf_true);
+
+ break;
+
+ case RPC_CLNT_DISCONNECT:
+ if (glusterd_is_snapd_online (volinfo)) {
+ gf_msg (this->name, GF_LOG_INFO, 0,
+ GD_MSG_NODE_DISCONNECTED,
+ "snapd for volume %s has disconnected from "
+ "glusterd.", volinfo->volname);
+
+ (void) glusterd_snapd_set_online_status
+ (volinfo, _gf_false);
+ }
+ break;
+
+ case RPC_CLNT_DESTROY:
+ glusterd_volinfo_unref (volinfo);
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_TRACE,
+ "got some other RPC event %d", event);
+ break;
+ }
+
+ return ret;
+}
+
+int
+glusterd_snapd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
+ rpc_clnt_event_t event, void *data)
+{
+ return glusterd_big_locked_notify (rpc, mydata, event, data,
+ __glusterd_snapd_rpc_notify);
+}
+
+int
__glusterd_nodesvc_rpc_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event, void *data)
{
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 2901b98d847..115dd8bd145 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -162,6 +162,7 @@ build_volfile_path (const char *volname, char *path,
const char *volname_ptr = NULL;
char path_prefix [PATH_MAX] = {0,};
xlator_t *this = NULL;
+ char *volname_tmp = NULL;
this = THIS;
GF_ASSERT (this);
@@ -170,7 +171,18 @@ build_volfile_path (const char *volname, char *path,
GF_ASSERT (volname);
GF_ASSERT (path);
- if (strstr (volname, "gluster/")) {
+ if (strstr (volname, "snapd/")) {
+ volname_tmp = strchr (volname, '/') + 1;
+ ret = glusterd_volinfo_find (volname_tmp, &volinfo);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Couldn't find volinfo");
+ goto out;
+ }
+ glusterd_get_snapd_volfile (volinfo, path, path_len);
+ ret = 1;
+ goto out;
+ } else if (strstr (volname, "gluster/")) {
server = strchr (volname, '/') + 1;
glusterd_get_nodesvc_volfile (server, priv->workdir,
path, path_len);
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 4ad53c126e6..73f4c152460 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -2072,6 +2072,11 @@ glusterd_op_set_volume (dict_t *dict)
if (!global_opts_set) {
gd_update_volume_op_versions (volinfo);
+
+ ret = glusterd_handle_snapd_option (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_create_volfiles_and_notify_services (volinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
@@ -2098,6 +2103,11 @@ glusterd_op_set_volume (dict_t *dict)
list_for_each_entry (voliter, &priv->volumes, vol_list) {
volinfo = voliter;
gd_update_volume_op_versions (volinfo);
+
+ ret = glusterd_handle_snapd_option (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_create_volfiles_and_notify_services (volinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
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;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 91a4c3c2418..4b6e2b0cdbc 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -204,7 +204,7 @@ glusterd_is_nodesvc_running ();
void
glusterd_get_nodesvc_dir (char *server, char *workdir,
- char *path, size_t len);
+ char *path, size_t len);
int32_t
glusterd_nfs_server_start ();
@@ -839,4 +839,56 @@ glusterd_snapshot_restore_cleanup (dict_t *rsp_dict,
glusterd_volinfo_t *volinfo,
glusterd_snap_t *snap);
+int
+glusterd_unlink_file (char *sock_file_path);
+
+/* Snapd functions */
+int
+glusterd_handle_snapd_option (glusterd_volinfo_t *volinfo);
+
+int32_t
+glusterd_snapd_disconnect (glusterd_volinfo_t *volinfo);
+
+void
+glusterd_get_snapd_dir (glusterd_volinfo_t *volinfo,
+ char *path, int path_len);
+
+void
+glusterd_get_snapd_rundir (glusterd_volinfo_t *volinfo,
+ char *path, int path_len);
+
+void
+glusterd_get_snapd_volfile (glusterd_volinfo_t *volinfo,
+ char *path, int path_len);
+
+void
+glusterd_get_snapd_pidfile (glusterd_volinfo_t *volinfo,
+ char *path, int path_len);
+
+void
+glusterd_set_snapd_socket_filepath (glusterd_volinfo_t *volinfo,
+ char *path, int path_len);
+
+gf_boolean_t
+glusterd_is_snapd_running (glusterd_volinfo_t *volinfo);
+
+int
+glusterd_snapd_stop (glusterd_volinfo_t *volinfo);
+
+int
+glusterd_snapd_start (glusterd_volinfo_t *volinfo, gf_boolean_t wait);
+
+int
+glusterd_is_snapd_enabled (glusterd_volinfo_t *volinfo);
+
+gf_boolean_t
+glusterd_is_snapd_online (glusterd_volinfo_t *volinfo);
+
+void
+glusterd_snapd_set_online_status (glusterd_volinfo_t *volinfo,
+ gf_boolean_t status);
+
+int
+glusterd_restart_snapds (glusterd_conf_t *priv);
+/* End snapd functions */
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 165fdd882b1..fa4f88f9a06 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -961,54 +961,54 @@ out:
static void
volgen_apply_filters (char *orig_volfile)
{
- DIR *filterdir = NULL;
- struct dirent entry = {0,};
- struct dirent *next = NULL;
- char *filterpath = NULL;
- struct stat statbuf = {0,};
-
- filterdir = opendir(FILTERDIR);
- if (!filterdir) {
- return;
- }
-
- while ((readdir_r(filterdir,&entry,&next) == 0) && next) {
- if (!strncmp(entry.d_name,".",sizeof(entry.d_name))) {
- continue;
- }
- if (!strncmp(entry.d_name,"..",sizeof(entry.d_name))) {
- continue;
- }
- /*
- * d_type isn't guaranteed to be present/valid on all systems,
- * so do an explicit stat instead.
- */
- if (gf_asprintf(&filterpath,"%s/%.*s",FILTERDIR,
- sizeof(entry.d_name), entry.d_name) == (-1)) {
- continue;
- }
- /* Deliberately use stat instead of lstat to allow symlinks. */
- if (stat(filterpath,&statbuf) == (-1)) {
- goto free_fp;
- }
- if (!S_ISREG(statbuf.st_mode)) {
- goto free_fp;
- }
- /*
- * We could check the mode in statbuf directly, or just skip
- * this entirely and check for EPERM after exec fails, but this
- * is cleaner.
- */
- if (access(filterpath,X_OK) != 0) {
- goto free_fp;
- }
- if (runcmd(filterpath,orig_volfile,NULL)) {
- gf_log("",GF_LOG_ERROR,"failed to run filter %.*s",
- (int)sizeof(entry.d_name), entry.d_name);
- }
+ DIR *filterdir = NULL;
+ struct dirent entry = {0,};
+ struct dirent *next = NULL;
+ char *filterpath = NULL;
+ struct stat statbuf = {0,};
+
+ filterdir = opendir(FILTERDIR);
+ if (!filterdir) {
+ return;
+ }
+
+ while ((readdir_r(filterdir,&entry,&next) == 0) && next) {
+ if (!strncmp(entry.d_name,".",sizeof(entry.d_name))) {
+ continue;
+ }
+ if (!strncmp(entry.d_name,"..",sizeof(entry.d_name))) {
+ continue;
+ }
+ /*
+ * d_type isn't guaranteed to be present/valid on all systems,
+ * so do an explicit stat instead.
+ */
+ if (gf_asprintf(&filterpath,"%s/%.*s",FILTERDIR,
+ sizeof(entry.d_name), entry.d_name) == (-1)) {
+ continue;
+ }
+ /* Deliberately use stat instead of lstat to allow symlinks. */
+ if (stat(filterpath,&statbuf) == (-1)) {
+ goto free_fp;
+ }
+ if (!S_ISREG(statbuf.st_mode)) {
+ goto free_fp;
+ }
+ /*
+ * We could check the mode in statbuf directly, or just skip
+ * this entirely and check for EPERM after exec fails, but this
+ * is cleaner.
+ */
+ if (access(filterpath,X_OK) != 0) {
+ goto free_fp;
+ }
+ if (runcmd(filterpath,orig_volfile,NULL)) {
+ gf_log("",GF_LOG_ERROR,"failed to run filter %.*s",
+ (int)sizeof(entry.d_name), entry.d_name);
+ }
free_fp:
- GF_FREE(filterpath);
- }
+ GF_FREE(filterpath);
+ }
}
static int
@@ -1063,7 +1063,7 @@ volgen_write_volfile (volgen_graph_t *graph, char *filename)
GF_FREE (ftmp);
- volgen_apply_filters(filename);
+ volgen_apply_filters(filename);
return 0;
@@ -1656,9 +1656,9 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
if (!rbxl)
return -1;
- ptranst = glusterd_get_trans_type_rb (volinfo->transport_type);
- if (NULL == ptranst)
- return -1;
+ ptranst = glusterd_get_trans_type_rb (volinfo->transport_type);
+ if (NULL == ptranst)
+ return -1;
if (username) {
ret = xlator_set_option (rbxl, "username", username);
@@ -2203,20 +2203,97 @@ out:
}
+
+static xlator_t *
+volgen_graph_build_client (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
+ char *hostname, char *subvol, char *xl_id,
+ char *transt, dict_t *set_dict)
+{
+ xlator_t *xl = NULL;
+ int ret = -2;
+ uint32_t client_type = GF_CLIENT_OTHER;
+ char *str = NULL;
+ char *ssl_str = NULL;
+ gf_boolean_t ssl_bool = _gf_false;
+
+ GF_ASSERT (graph);
+ GF_ASSERT (subvol);
+ GF_ASSERT (xl_id);
+ GF_ASSERT (transt);
+
+ xl = volgen_graph_add_nolink (graph, "protocol/client",
+ "%s", xl_id);
+ if (!xl)
+ goto err;
+
+ ret = xlator_set_option (xl, "ping-timeout", "42");
+ if (ret)
+ goto err;
+
+ if (hostname) {
+ ret = xlator_set_option (xl, "remote-host", hostname);
+ if (ret)
+ goto err;
+ }
+
+ ret = xlator_set_option (xl, "remote-subvolume", subvol);
+ if (ret)
+ goto err;
+
+ ret = xlator_set_option (xl, "transport-type", transt);
+ if (ret)
+ goto err;
+
+ ret = dict_get_uint32 (set_dict, "trusted-client",
+ &client_type);
+
+ if (!ret && client_type == GF_CLIENT_TRUSTED) {
+ str = NULL;
+ str = glusterd_auth_get_username (volinfo);
+ if (str) {
+ ret = xlator_set_option (xl, "username",
+ str);
+ if (ret)
+ goto err;
+ }
+
+ str = glusterd_auth_get_password (volinfo);
+ if (str) {
+ ret = xlator_set_option (xl, "password",
+ str);
+ if (ret)
+ goto err;
+ }
+ }
+
+ if (dict_get_str(set_dict,"client.ssl",&ssl_str) == 0) {
+ if (gf_string2boolean(ssl_str,&ssl_bool) == 0) {
+ if (ssl_bool) {
+ ret = xlator_set_option(xl,
+ "transport.socket.ssl-enabled",
+ "true");
+ if (ret) {
+ goto err;
+ }
+ }
+ }
+ }
+
+ return xl;
+err:
+ return NULL;
+}
+
static int
volgen_graph_build_clients (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
dict_t *set_dict, void *param)
{
int i = 0;
int ret = -1;
- uint32_t client_type = GF_CLIENT_OTHER;
char transt[16] = {0,};
char *volname = NULL;
- char *str = NULL;
glusterd_brickinfo_t *brick = NULL;
xlator_t *xl = NULL;
- char *ssl_str = NULL;
- gf_boolean_t ssl_bool;
volname = volinfo->volname;
@@ -2243,59 +2320,14 @@ volgen_graph_build_clients (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
strcpy (transt, "tcp");
i = 0;
- ret = -1;
list_for_each_entry (brick, &volinfo->bricks, brick_list) {
- ret = -1;
- xl = volgen_graph_add_nolink (graph, "protocol/client",
- "%s", brick->brick_id);
- if (!xl)
- goto out;
- ret = xlator_set_option (xl, "ping-timeout", "42");
- if (ret)
- goto out;
- ret = xlator_set_option (xl, "remote-host", brick->hostname);
- if (ret)
- goto out;
- ret = xlator_set_option (xl, "remote-subvolume", brick->path);
- if (ret)
- goto out;
- ret = xlator_set_option (xl, "transport-type", transt);
- if (ret)
+ xl = volgen_graph_build_client (graph, volinfo,
+ brick->hostname, brick->path,
+ brick->brick_id,
+ transt, set_dict);
+ if (!xl) {
+ ret = -1;
goto out;
-
- ret = dict_get_uint32 (set_dict, "trusted-client",
- &client_type);
-
- if (!ret && client_type == GF_CLIENT_TRUSTED) {
- str = NULL;
- str = glusterd_auth_get_username (volinfo);
- if (str) {
- ret = xlator_set_option (xl, "username",
- str);
- if (ret)
- goto out;
- }
-
- str = glusterd_auth_get_password (volinfo);
- if (str) {
- ret = xlator_set_option (xl, "password",
- str);
- if (ret)
- goto out;
- }
- }
-
- if (dict_get_str(set_dict,"client.ssl",&ssl_str) == 0) {
- if (gf_string2boolean(ssl_str,&ssl_bool) == 0) {
- if (ssl_bool) {
- ret = xlator_set_option(xl,
- "transport.socket.ssl-enabled",
- "true");
- if (ret) {
- goto out;
- }
- }
- }
}
i++;
@@ -2360,6 +2392,70 @@ out:
return ret;
}
+/**
+ * This is the build graph function for user-serviceable snapshots.
+ * Generates snapview-client
+ */
+static int
+volgen_graph_build_snapview_client (volgen_graph_t *graph,
+ glusterd_volinfo_t *volinfo,
+ char *volname, dict_t *set_dict)
+{
+ int ret = 0;
+ xlator_t *prev_top = NULL;
+ xlator_t *prot_clnt = NULL;
+ xlator_t *svc = NULL;
+ char transt [16] = {0,};
+ char *svc_args[] = {"features/snapview-client",
+ "%s-snapview-client"};
+ char subvol [1024] = {0,};
+ char xl_id [1024] = {0,};
+
+ prev_top = (xlator_t *)(graph->graph.first);
+
+ snprintf (subvol, sizeof (subvol), "snapd-%s", volinfo->volname);
+ snprintf (xl_id, sizeof (xl_id), "%s-snapd-client", volinfo->volname);
+
+ get_transport_type (volinfo, set_dict, transt, _gf_false);
+
+ prot_clnt = volgen_graph_build_client (graph, volinfo, NULL, subvol,
+ xl_id, transt, set_dict);
+ if (!prot_clnt) {
+ ret = -1;
+ goto out;
+ }
+
+ svc = volgen_graph_add_nolink (graph, svc_args[0], svc_args[1],
+ volname);
+ if (!svc) {
+ ret = -1;
+ goto out;
+ }
+
+ /**
+ * Ordering the below two traslators (cur_top & prot_clnt) is important
+ * as snapview client implementation is built on the policy that
+ * normal volume path goes to FIRST_CHILD and snap world operations
+ * goes to SECOND_CHILD
+ **/
+ ret = volgen_xlator_link (graph->graph.first, prev_top);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to link the "
+ "snapview-client to distribute");
+ goto out;
+ }
+
+ ret = volgen_xlator_link (graph->graph.first, prot_clnt);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "failed to link the "
+ "snapview-client to snapview-server");
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
gf_boolean_t
_xl_is_client_decommissioned (xlator_t *xl, glusterd_volinfo_t *volinfo)
{
@@ -2599,26 +2695,26 @@ out:
}
static int client_graph_set_perf_options(volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo,
- dict_t *set_dict)
+ glusterd_volinfo_t *volinfo,
+ dict_t *set_dict)
{
- data_t *tmp_data = NULL;
- char *volname = NULL;
-
- /*
- * Logic to make sure NFS doesn't have performance translators by
- * default for a volume
- */
- volname = volinfo->volname;
- tmp_data = dict_get (set_dict, "nfs-volume-file");
- if (!tmp_data)
- return volgen_graph_set_options_generic(graph, set_dict,
- volinfo,
- &perfxl_option_handler);
- else
- return volgen_graph_set_options_generic(graph, set_dict,
- volname,
- &nfsperfxl_option_handler);
+ data_t *tmp_data = NULL;
+ char *volname = NULL;
+
+ /*
+ * Logic to make sure NFS doesn't have performance translators by
+ * default for a volume
+ */
+ volname = volinfo->volname;
+ tmp_data = dict_get (set_dict, "nfs-volume-file");
+ if (!tmp_data)
+ return volgen_graph_set_options_generic(graph, set_dict,
+ volinfo,
+ &perfxl_option_handler);
+ else
+ return volgen_graph_set_options_generic(graph, set_dict,
+ volname,
+ &nfsperfxl_option_handler);
}
static int
@@ -2815,6 +2911,13 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
if (ret)
goto out;
+ if (!volinfo->is_snap_volume && glusterd_is_snapd_enabled (volinfo)) {
+ ret = volgen_graph_build_snapview_client
+ (graph, volinfo, volname, set_dict);
+ if (ret == -1)
+ goto out;
+ }
+
/* add debug translators depending on the options */
ret = check_and_add_debug_xl (graph, set_dict, volname,
"client");
@@ -3534,7 +3637,7 @@ build_quotad_graph (volgen_graph_t *graph, dict_t *mod_dict)
dict_t *set_dict = NULL;
int ret = 0;
xlator_t *quotad_xl = NULL;
- char *skey = NULL;
+ char *skey = NULL;
this = THIS;
priv = this->private;
@@ -4000,13 +4103,110 @@ out:
}
int
-glusterd_create_quotad_volfile ()
+glusterd_generate_snapd_volfile (volgen_graph_t *graph,
+ glusterd_volinfo_t *volinfo)
+{
+ xlator_t *xl = NULL;
+ char *username = NULL;
+ char *passwd = NULL;
+ int ret = 0;
+ char key [PATH_MAX] = {0, };
+ dict_t *set_dict = NULL;
+ char *loglevel = NULL;
+ char *xlator = NULL;
+
+ set_dict = dict_copy (volinfo->dict, NULL);
+ if (!set_dict)
+ return -1;
+
+ ret = dict_get_str (set_dict, "xlator", &xlator);
+ if (!ret) {
+ ret = dict_get_str (set_dict, "loglevel", &loglevel);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "could not get both"
+ " translator name and loglevel for log level "
+ "request");
+ return -1;
+ }
+ }
+
+ xl = volgen_graph_add (graph, "features/snapview-server",
+ volinfo->volname);
+ if (!xl)
+ return -1;
+
+ ret = xlator_set_option (xl, "volname", volinfo->volname);
+ if (ret)
+ return -1;
+
+ xl = volgen_graph_add (graph, "performance/io-threads",
+ volinfo->volname);
+ if (!xl)
+ return -1;
+
+ snprintf (key, sizeof (key), "snapd-%s", volinfo->volname);
+ xl = volgen_graph_add_as (graph, "debug/io-stats", key);
+ if (!xl)
+ return -1;
+
+ xl = volgen_graph_add (graph, "protocol/server", volinfo->volname);
+ if (!xl)
+ return -1;
+
+ ret = xlator_set_option (xl, "transport-type", "tcp");
+ if (ret)
+ return -1;
+
+ username = glusterd_auth_get_username (volinfo);
+ passwd = glusterd_auth_get_password (volinfo);
+
+ snprintf (key, sizeof (key), "auth.login.snapd-%s.allow",
+ volinfo->volname);
+ ret = xlator_set_option (xl, key, username);
+ if (ret)
+ return -1;
+
+ snprintf (key, sizeof (key), "auth.login.%s.password", username);
+ ret = xlator_set_option (xl, key, passwd);
+ if (ret)
+ return -1;
+
+ ret = volgen_graph_set_options_generic
+ (graph, set_dict,
+ (xlator && loglevel)? (void *)set_dict: volinfo,
+ (xlator && loglevel) ?
+ &server_spec_extended_option_handler:
+ &server_spec_option_handler);
+
+ return ret;
+}
+
+int
+glusterd_create_snapd_volfile (glusterd_volinfo_t *volinfo)
+{
+ volgen_graph_t graph = {0,};
+ int ret = -1;
+ char filename [PATH_MAX] = {0,};
+
+ glusterd_get_snapd_volfile (volinfo, filename, PATH_MAX);
+
+ ret = glusterd_generate_snapd_volfile (&graph, volinfo);
+ if (!ret)
+ ret = volgen_write_volfile (&graph, filename);
+
+ volgen_graph_free (&graph);
+
+ return ret;
+}
+
+int
+glusterd_create_quotad_volfile (void *data)
{
char filepath[PATH_MAX] = {0,};
glusterd_conf_t *conf = THIS->private;
glusterd_get_nodesvc_volfile ("quotad", conf->workdir,
- filepath, sizeof (filepath));
+ filepath, sizeof (filepath));
return glusterd_create_global_volfile (build_quotad_graph,
filepath, NULL);
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h
index dab5e1ff03d..f4959f1e6c2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.h
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h
@@ -125,6 +125,7 @@ void glusterd_get_shd_filepath (char *filename);
int glusterd_create_nfs_volfile ();
int glusterd_create_shd_volfile ();
int glusterd_create_quotad_volfile ();
+int glusterd_create_snapd_volfile (glusterd_volinfo_t *volinfo);
int glusterd_delete_volfile (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo);
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index 1eff081516e..9b390321087 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -1941,6 +1941,10 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr)
if (ret)
goto out;
+ ret = glusterd_handle_snapd_option (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_nodesvcs_handle_graph_change (volinfo);
out:
@@ -2006,10 +2010,15 @@ glusterd_stop_volume (glusterd_volinfo_t *volinfo)
runner_end (&runner);
}
+ ret = glusterd_handle_snapd_option (volinfo);
+ if (ret)
+ goto out;
+
ret = glusterd_nodesvcs_handle_graph_change (volinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to notify graph "
"change for %s volume", volinfo->volname);
+
goto out;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index ffac2f4ac82..26e86209007 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1095,6 +1095,15 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT
},
+ { .key = "features.uss",
+ .voltype = "features/snapview-server",
+ .op_version = 4,
+ .value = "uss",
+ .flags = OPT_FLAG_CLIENT_OPT | OPT_FLAG_XLATOR_OPT,
+ .description = "Enable/Disable User Servicable Snapshots on the "
+ "volume."
+ },
+
#ifdef HAVE_LIB_Z
/* Compressor-decompressor xlator options
* defaults used from xlator/features/compress/src/cdc.h
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 02441c9148b..57a5862a368 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -123,6 +123,12 @@ typedef struct {
} nodesrv_t;
typedef struct {
+ struct rpc_clnt *rpc;
+ int port;
+ gf_boolean_t online;
+} glusterd_snapd_t;
+
+typedef struct {
struct _volfile_ctx *volfile;
pthread_mutex_t mutex;
struct list_head peers;
@@ -372,6 +378,8 @@ struct glusterd_volinfo_ {
pthread_mutex_t reflock;
int refcnt;
gd_quorum_status_t quorum_status;
+
+ glusterd_snapd_t snapd;
};
typedef enum gd_snap_status_ {
@@ -856,6 +864,10 @@ glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event, void *data);
int
+glusterd_snapd_rpc_notify (struct rpc_clnt *rpc, void *mydata,
+ rpc_clnt_event_t event, void *data);
+
+int
glusterd_nodesvc_rpc_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event, void *data);