diff options
| author | Pranith Kumar K <pranithk@gluster.com> | 2010-09-20 09:54:12 +0000 | 
|---|---|---|
| committer | Vijay Bellur <vijay@dev.gluster.com> | 2010-09-20 10:33:38 -0700 | 
| commit | ad234382336a6f2dafb4cb698dfabbf7957b498b (patch) | |
| tree | 8cb8c47abb63ea4a5647a5524b688f298017aae9 | |
| parent | e71b50e49612af4e76510b0c2a6f0519adfd852d (diff) | |
cli, mgmt/glusterd: volume sync command
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 1310 ()
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1310
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 50 | ||||
| -rw-r--r-- | cli/src/cli3_1-cops.c | 54 | ||||
| -rw-r--r-- | glusterfsd/src/glusterfsd-mgmt.c | 8 | ||||
| -rw-r--r-- | glusterfsd/src/glusterfsd.c | 2 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 2 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.c | 39 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 25 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1.c | 28 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1.h | 10 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1.x | 18 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 142 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 430 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 3 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-sm.c | 77 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 71 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 15 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 12 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd3_1-mops.c | 49 | 
18 files changed, 810 insertions, 225 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index fc7fda9df..28104c187 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -131,6 +131,52 @@ out:  } + +void +cli_cmd_sync_volume_usage () +{ +        cli_out ("Usage: volume sync <HOSTNAME> [all|<VOLNAME>]"); +} + +int +cli_cmd_sync_volume_cbk (struct cli_state *state, struct cli_cmd_word *word, +                         const char **words, int wordcount) +{ +        int                     ret = -1; +        rpc_clnt_procedure_t    *proc = NULL; +        call_frame_t            *frame = NULL; +        gf1_cli_sync_volume_req req = {0,}; + +        if ((wordcount < 3) || (wordcount > 4)) { +               cli_cmd_sync_volume_usage (); +               goto out; +        } + +        if ((wordcount == 3) || !strcmp(words[3], "all")) { +                req.flags = GF_CLI_SYNC_ALL; +                req.volname = ""; +        } else { +                req.volname = (char *)words[3]; +        } + +        req.hostname = (char *)words[2]; + +        proc = &cli_rpc_prog->proctable[GF1_CLI_SYNC_VOLUME]; + +        frame = create_frame (THIS, THIS->ctx->pool); +        if (!frame) +                goto out; + +        if (proc->fn) { +                ret = proc->fn (frame, THIS, &req); +        } + +out: +        if (ret) +                cli_out ("Volume sync failed"); + +        return ret; +}  void  cli_cmd_volume_create_usage ()  { @@ -826,6 +872,10 @@ struct cli_cmd volume_cmds[] = {            cli_cmd_log_rotate_cbk,           "rotate the log file for corresponding volume/brick"}, +        { "volume sync <HOSTNAME> [all|<VOLNAME>]", +          cli_cmd_sync_volume_cbk, +         "sync the volume information from a peer"}, +          { NULL, NULL, NULL }  }; diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c index 0898f2b94..832618c24 100644 --- a/cli/src/cli3_1-cops.c +++ b/cli/src/cli3_1-cops.c @@ -1032,6 +1032,36 @@ out:          return ret;  } +static int +gf_cli3_1_sync_volume_cbk (struct rpc_req *req, struct iovec *iov, +                           int count, void *myframe) +{ +        gf1_cli_sync_volume_rsp        rsp   = {0,}; +        int                            ret   = -1; + +        if (-1 == req->rpc_status) { +                goto out; +        } + +        ret = gf_xdr_to_cli_sync_volume_rsp (*iov, &rsp); +        if (ret < 0) { +                gf_log ("", GF_LOG_ERROR, "error"); +                goto out; +        } + +        gf_log ("cli", GF_LOG_DEBUG, "Received resp to sync"); +        cli_out ("volume sync: %s", +                 (rsp.op_ret) ? "unsuccessful": "successful"); + +        if (rsp.op_ret && rsp.op_errstr) +                cli_out (rsp.op_errstr); +        ret = rsp.op_ret; + +out: +        cli_cmd_broadcast_response (ret); +        return ret; +} +  int  gf_cli3_1_getspec_cbk (struct rpc_req *req, struct iovec *iov,                         int count, void *myframe) @@ -1881,6 +1911,28 @@ out:  }  int32_t +gf_cli3_1_sync_volume (call_frame_t *frame, xlator_t *this, +                       void *data) +{ +        int               ret = 0; + +        if (!frame || !this || !data) { +                ret = -1; +                goto out; +        } + +        ret = cli_cmd_submit ((gf1_cli_sync_volume_req*)data, frame, +                              cli_rpc_prog, GD_MGMT_CLI_SYNC_VOLUME, +                              NULL, gf_xdr_from_cli_sync_volume_req, +                              this, gf_cli3_1_sync_volume_cbk); + +out: +        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +int32_t  gf_cli3_1_getspec (call_frame_t *frame, xlator_t *this,                           void *data)  { @@ -1939,7 +1991,6 @@ out:          return ret;  } -  struct rpc_clnt_procedure gluster3_1_cli_actors[GF1_CLI_MAXVALUE] = {          [GF1_CLI_NULL]        = {"NULL", NULL },          [GF1_CLI_PROBE]  = { "PROBE_QUERY",  gf_cli3_1_probe}, @@ -1962,6 +2013,7 @@ struct rpc_clnt_procedure gluster3_1_cli_actors[GF1_CLI_MAXVALUE] = {          [GF1_CLI_LOG_ROTATE] = {"LOG ROTATE", gf_cli3_1_log_rotate},          [GF1_CLI_GETSPEC] = {"GETSPEC", gf_cli3_1_getspec},          [GF1_CLI_PMAP_PORTBYBRICK] = {"PMAP PORTBYBRICK", gf_cli3_1_pmap_b2p}, +        [GF1_CLI_SYNC_VOLUME] = {"SYNC_VOLUME", gf_cli3_1_sync_volume},  };  struct rpc_clnt_program cli3_1_prog = { diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c index 6e3cda951..d9cc83a81 100644 --- a/glusterfsd/src/glusterfsd-mgmt.c +++ b/glusterfsd/src/glusterfsd-mgmt.c @@ -603,20 +603,20 @@ mgmt_pmap_signout_cbk (struct rpc_req *req, struct iovec *iov, int count,          ret = xdr_to_pmap_signout_rsp (*iov, &rsp);          if (ret < 0) { -                gf_log (frame->this->name, GF_LOG_ERROR, "error"); +                gf_log ("", GF_LOG_ERROR, "error");                  rsp.op_ret   = -1;                  rsp.op_errno = EINVAL;                  goto out;          }          if (-1 == rsp.op_ret) { -                gf_log (frame->this->name, GF_LOG_ERROR, +                gf_log ("", GF_LOG_ERROR,                          "failed to register the port with glusterd");                  goto out;          }  out: -        if (frame) -                STACK_DESTROY (frame->root); +//        if (frame) +//                STACK_DESTROY (frame->root);          return 0;  } diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c index 0fd739cb4..c0cb8a0db 100644 --- a/glusterfsd/src/glusterfsd.c +++ b/glusterfsd/src/glusterfsd.c @@ -642,7 +642,7 @@ cleanup_and_exit (int signum)          ctx = glusterfs_ctx_get ();          /* TODO: is this the right place? */ -        // glusterfs_mgmt_pmap_signout (ctx); +        glusterfs_mgmt_pmap_signout (ctx);          gf_log ("glusterfsd", GF_LOG_NORMAL, "shutting down"); diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 4b8f113d0..632c1d42d 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -102,6 +102,7 @@ enum gf_mgmt_procnum_ {          GD_MGMT_CLI_LOG_FILENAME,          GD_MGMT_CLI_LOG_LOCATE,          GD_MGMT_CLI_LOG_ROTATE, +        GD_MGMT_CLI_SYNC_VOLUME,          GD_MGMT_MAXVALUE,  }; @@ -129,6 +130,7 @@ enum gf_cli_procnum {          GF1_CLI_LOG_ROTATE,          GF1_CLI_GETSPEC,          GF1_CLI_PMAP_PORTBYBRICK, +        GF1_CLI_SYNC_VOLUME,          GF1_CLI_MAXVALUE,  }; diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c index 95c27e99f..93f7e7681 100644 --- a/rpc/xdr/src/cli1-xdr.c +++ b/rpc/xdr/src/cli1-xdr.c @@ -62,6 +62,15 @@ xdr_gf1_cli_get_volume (XDR *xdrs, gf1_cli_get_volume *objp)  }  bool_t +xdr_gf1_cli_sync_volume (XDR *xdrs, gf1_cli_sync_volume *objp) +{ + +	 if (!xdr_enum (xdrs, (enum_t *) objp)) +		 return FALSE; +	return TRUE; +} + +bool_t  xdr_gf1_cli_op_flags (XDR *xdrs, gf1_cli_op_flags *objp)  { @@ -279,8 +288,8 @@ xdr_gf1_cli_start_vol_rsp (XDR *xdrs, gf1_cli_start_vol_rsp *objp)  		 return FALSE;  	 if (!xdr_string (xdrs, &objp->volname, ~0))  		 return FALSE; -         if (!xdr_string (xdrs, &objp->op_errstr, ~0)) -                 return FALSE; +	 if (!xdr_string (xdrs, &objp->op_errstr, ~0)) +		 return FALSE;  	return TRUE;  } @@ -512,6 +521,19 @@ xdr_gf1_cli_log_locate_req (XDR *xdrs, gf1_cli_log_locate_req *objp)  }  bool_t +xdr_gf1_cli_sync_volume_req (XDR *xdrs, gf1_cli_sync_volume_req *objp) +{ + +	 if (!xdr_int (xdrs, &objp->flags)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->volname, ~0)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->hostname, ~0)) +		 return FALSE; +	return TRUE; +} + +bool_t  xdr_gf1_cli_log_locate_rsp (XDR *xdrs, gf1_cli_log_locate_rsp *objp)  { @@ -547,3 +569,16 @@ xdr_gf1_cli_log_rotate_rsp (XDR *xdrs, gf1_cli_log_rotate_rsp *objp)  		 return FALSE;  	return TRUE;  } + +bool_t +xdr_gf1_cli_sync_volume_rsp (XDR *xdrs, gf1_cli_sync_volume_rsp *objp) +{ + +	 if (!xdr_int (xdrs, &objp->op_ret)) +		 return FALSE; +	 if (!xdr_int (xdrs, &objp->op_errno)) +		 return FALSE; +	 if (!xdr_string (xdrs, &objp->op_errstr, ~0)) +		 return FALSE; +	return TRUE; +} diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 1b6145a67..c6d8e8bf5 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -63,6 +63,11 @@ enum gf1_cli_get_volume {  };  typedef enum gf1_cli_get_volume gf1_cli_get_volume; +enum gf1_cli_sync_volume { +	GF_CLI_SYNC_ALL = 1, +}; +typedef enum gf1_cli_sync_volume gf1_cli_sync_volume; +  enum gf1_cli_op_flags {  	GF_CLI_FLAG_OP_FORCE = 1,  }; @@ -311,6 +316,13 @@ struct gf1_cli_log_locate_req {  };  typedef struct gf1_cli_log_locate_req gf1_cli_log_locate_req; +struct gf1_cli_sync_volume_req { +	int flags; +	char *volname; +	char *hostname; +}; +typedef struct gf1_cli_sync_volume_req gf1_cli_sync_volume_req; +  struct gf1_cli_log_locate_rsp {  	int op_ret;  	int op_errno; @@ -331,6 +343,13 @@ struct gf1_cli_log_rotate_rsp {  };  typedef struct gf1_cli_log_rotate_rsp gf1_cli_log_rotate_rsp; +struct gf1_cli_sync_volume_rsp { +	int op_ret; +	int op_errno; +	char *op_errstr; +}; +typedef struct gf1_cli_sync_volume_rsp gf1_cli_sync_volume_rsp; +  /* the xdr functions */  #if defined(__STDC__) || defined(__cplusplus) @@ -338,6 +357,7 @@ extern  bool_t xdr_gf1_cluster_type (XDR *, gf1_cluster_type*);  extern  bool_t xdr_gf1_cli_replace_op (XDR *, gf1_cli_replace_op*);  extern  bool_t xdr_gf1_cli_friends_list (XDR *, gf1_cli_friends_list*);  extern  bool_t xdr_gf1_cli_get_volume (XDR *, gf1_cli_get_volume*); +extern  bool_t xdr_gf1_cli_sync_volume (XDR *, gf1_cli_sync_volume*);  extern  bool_t xdr_gf1_cli_op_flags (XDR *, gf1_cli_op_flags*);  extern  bool_t xdr_gf1_cli_probe_req (XDR *, gf1_cli_probe_req*);  extern  bool_t xdr_gf1_cli_probe_rsp (XDR *, gf1_cli_probe_rsp*); @@ -370,15 +390,18 @@ extern  bool_t xdr_gf1_cli_set_vol_rsp (XDR *, gf1_cli_set_vol_rsp*);  extern  bool_t xdr_gf1_cli_log_filename_req (XDR *, gf1_cli_log_filename_req*);  extern  bool_t xdr_gf1_cli_log_filename_rsp (XDR *, gf1_cli_log_filename_rsp*);  extern  bool_t xdr_gf1_cli_log_locate_req (XDR *, gf1_cli_log_locate_req*); +extern  bool_t xdr_gf1_cli_sync_volume_req (XDR *, gf1_cli_sync_volume_req*);  extern  bool_t xdr_gf1_cli_log_locate_rsp (XDR *, gf1_cli_log_locate_rsp*);  extern  bool_t xdr_gf1_cli_log_rotate_req (XDR *, gf1_cli_log_rotate_req*);  extern  bool_t xdr_gf1_cli_log_rotate_rsp (XDR *, gf1_cli_log_rotate_rsp*); +extern  bool_t xdr_gf1_cli_sync_volume_rsp (XDR *, gf1_cli_sync_volume_rsp*);  #else /* K&R C */  extern bool_t xdr_gf1_cluster_type ();  extern bool_t xdr_gf1_cli_replace_op ();  extern bool_t xdr_gf1_cli_friends_list ();  extern bool_t xdr_gf1_cli_get_volume (); +extern bool_t xdr_gf1_cli_sync_volume ();  extern bool_t xdr_gf1_cli_op_flags ();  extern bool_t xdr_gf1_cli_probe_req ();  extern bool_t xdr_gf1_cli_probe_rsp (); @@ -411,9 +434,11 @@ extern bool_t xdr_gf1_cli_set_vol_rsp ();  extern bool_t xdr_gf1_cli_log_filename_req ();  extern bool_t xdr_gf1_cli_log_filename_rsp ();  extern bool_t xdr_gf1_cli_log_locate_req (); +extern bool_t xdr_gf1_cli_sync_volume_req ();  extern bool_t xdr_gf1_cli_log_locate_rsp ();  extern bool_t xdr_gf1_cli_log_rotate_req ();  extern bool_t xdr_gf1_cli_log_rotate_rsp (); +extern bool_t xdr_gf1_cli_sync_volume_rsp ();  #endif /* K&R C */ diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c index d7ba91aea..22b74fd7d 100644 --- a/rpc/xdr/src/cli1.c +++ b/rpc/xdr/src/cli1.c @@ -523,3 +523,31 @@ gf_xdr_from_cli_log_rotate_req (struct iovec outmsg, void *req)          return xdr_serialize_generic (outmsg, (void *)req,                                        (xdrproc_t)xdr_gf1_cli_log_rotate_req);  } + +ssize_t +gf_xdr_to_cli_sync_volume_req (struct iovec inmsg, void *args) +{ +        return xdr_to_generic (inmsg, (void *)args, +                               (xdrproc_t)xdr_gf1_cli_sync_volume_req); +} + +ssize_t +gf_xdr_from_cli_sync_volume_req (struct iovec outmsg, void *args) +{ +        return xdr_serialize_generic (outmsg, (void *)args, +                                     (xdrproc_t)xdr_gf1_cli_sync_volume_req); +} + +ssize_t +gf_xdr_to_cli_sync_volume_rsp (struct iovec inmsg, void *args) +{ +        return xdr_to_generic (inmsg, (void *)args, +                               (xdrproc_t)xdr_gf1_cli_sync_volume_rsp); +} + +ssize_t +gf_xdr_from_cli_sync_volume_rsp (struct iovec outmsg, void *args) +{ +        return xdr_serialize_generic (outmsg, (void *)args, +                                      (xdrproc_t)xdr_gf1_cli_sync_volume_rsp); +} diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h index 31b2c9b75..ee2254001 100644 --- a/rpc/xdr/src/cli1.h +++ b/rpc/xdr/src/cli1.h @@ -234,6 +234,16 @@ gf_xdr_to_cli_log_rotate_rsp (struct iovec inmsg, void *args);  ssize_t  gf_xdr_from_cli_log_rotate_req (struct iovec outmsg, void *req); +ssize_t +gf_xdr_to_cli_sync_volume_req (struct iovec inmsg, void *args); + +ssize_t +gf_xdr_from_cli_sync_volume_req (struct iovec outmsg, void *args); +ssize_t +gf_xdr_to_cli_sync_volume_rsp (struct iovec inmsg, void *args); + +ssize_t +gf_xdr_from_cli_sync_volume_rsp (struct iovec outmsg, void *args);  #endif /* !_CLI1_H */ diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x index 03c175e63..3f37f6d75 100644 --- a/rpc/xdr/src/cli1.x +++ b/rpc/xdr/src/cli1.x @@ -23,6 +23,10 @@ enum gf1_cli_get_volume {          GF_CLI_GET_NEXT_VOLUME  } ; +enum gf1_cli_sync_volume { +        GF_CLI_SYNC_ALL = 1 +} ; +  enum gf1_cli_op_flags {          GF_CLI_FLAG_OP_FORCE = 1  }; @@ -218,6 +222,12 @@ struct gf1_cli_log_locate_req {          string brick<>;  }; +struct gf1_cli_sync_volume_req { +        int    flags; +        string volname<>; +        string hostname<>; +}; +  struct gf1_cli_log_locate_rsp {  	int op_ret;  	int op_errno; @@ -230,7 +240,13 @@ struct gf1_cli_log_rotate_req {  };  struct gf1_cli_log_rotate_rsp { +        int op_ret; +        int op_errno; +        string errstr<>; +}; + +struct gf1_cli_sync_volume_rsp {  	int op_ret;  	int op_errno; -        string errstr<>; +        string op_errstr<>;  }; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index bc015293f..da9eca021 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -297,7 +297,7 @@ out:          return ret;  } -static int +int  glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,                                      dict_t  *volumes, int   count)  { @@ -2013,6 +2013,108 @@ out:          return ret;  } +int +glusterd_handle_sync_volume (rpcsvc_request_t *req) +{ +        int32_t                          ret     = -1; +        gf1_cli_sync_volume_req          cli_req = {0,}; +        dict_t                           *dict = NULL; +        gf1_cli_sync_volume_rsp          cli_rsp = {0.}; +        char                             msg[2048] = {0,}; +        gf_boolean_t                     free_hostname = _gf_true; +        gf_boolean_t                     free_volname = _gf_true; +        glusterd_volinfo_t               *volinfo = NULL; + +        GF_ASSERT (req); + +        if (!gf_xdr_to_cli_sync_volume_req (req->msg[0], &cli_req)) { +                //failed to decode msg; +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } +        gf_log ("glusterd", GF_LOG_NORMAL, "Received volume sync req " +                "for volume %s", +                (cli_req.flags & GF_CLI_SYNC_ALL) ? "all" : cli_req.volname); + +        dict = dict_new (); +        if (!dict) { +                gf_log ("", GF_LOG_ERROR, "Can't allocate sync vol dict"); +                goto out; +        } + +        if (!glusterd_is_local_addr (cli_req.hostname)) { +                ret = -1; +                snprintf (msg, sizeof (msg), "sync from localhost" +                          " not allowed"); +                goto out; +        } + +        ret = dict_set_dynmstr (dict, "hostname", cli_req.hostname); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "hostname set failed"); +                snprintf (msg, sizeof (msg), "hostname set failed"); +                goto out; +        } else { +                free_hostname = _gf_false; +        } + +        ret = dict_set_int32 (dict, "flags", cli_req.flags); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "volume flags set failed"); +                snprintf (msg, sizeof (msg), "volume flags set failed"); +                goto out; +        } + +        if (!cli_req.flags) { +                ret = glusterd_volinfo_find (cli_req.volname, &volinfo); +                if (!ret) { +                        snprintf (msg, sizeof (msg), "please delete the " +                                 "volume: %s before sync", cli_req.volname); +                        ret = -1; +                        goto out; +                } + +                ret = dict_set_dynmstr (dict, "volname", cli_req.volname); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "volume name set failed"); +                        snprintf (msg, sizeof (msg), "volume name set failed"); +                        goto out; +                } else { +                        free_volname = _gf_false; +                } +        } else { +                free_volname = _gf_false; +                if (glusterd_volume_count_get ()) { +                        snprintf (msg, sizeof (msg), "please delete all the " +                                 "volumes before full sync"); +                        ret = -1; +                        goto out; +                } +        } + +        ret = glusterd_sync_volume (req, dict); + +out: +        if (ret) { +                cli_rsp.op_ret = -1; +                cli_rsp.op_errstr = msg; +                glusterd_submit_reply(req, &cli_rsp, NULL, 0, NULL, +                                      gf_xdr_from_cli_sync_volume_rsp); +                if (free_hostname && cli_req.hostname) +                        free (cli_req.hostname); +                if (free_volname && cli_req.volname) +                        free (cli_req.volname); +                if (dict) +                        dict_unref (dict); +                if (!glusterd_opinfo_unlock()) +                        gf_log ("glusterd", GF_LOG_ERROR, "Unlock on " +                               "opinfo failed"); + +                ret = 0; //sent error to cli, prevent second reply +        } + +        return ret; +}  int  glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status) @@ -2156,9 +2258,9 @@ out:  int  glusterd_op_commit_send_resp (rpcsvc_request_t *req, -                               int32_t op, int32_t status, char *op_errstr) +                               int32_t op, int32_t status, char *op_errstr, +                               dict_t *rsp_dict)  { -        dict_t                         *rsp_dict = NULL;          gd1_mgmt_commit_op_rsp          rsp      = {{0}, };          int                             ret      = -1; @@ -2172,18 +2274,14 @@ glusterd_op_commit_send_resp (rpcsvc_request_t *req,          else                  rsp.op_errstr = ""; -        rsp_dict = dict_new (); -        if (!rsp_dict) { -                gf_log ("", GF_LOG_DEBUG, -                        "Out of memory"); -                ret = -1; -                goto out; -        } - -        if (op == GD_OP_REPLACE_BRICK) { +        switch (op) { +        case GD_OP_REPLACE_BRICK:                  ret = glusterd_fill_rb_commit_rsp (rsp_dict);                  if (ret)                          goto out; +                break; +        default: +                break;          }          ret = dict_allocate_and_serialize (rsp_dict, @@ -2203,8 +2301,6 @@ glusterd_op_commit_send_resp (rpcsvc_request_t *req,                  "Responded to commit, ret: %d", ret);  out: -        if (rsp_dict) -                dict_unref (rsp_dict);          if (rsp.dict.dict_val)                  GF_FREE (rsp.dict.dict_val);          return ret; @@ -3084,6 +3180,24 @@ glusterd_log_rotate (rpcsvc_request_t *req, dict_t *dict)          return ret;  } +int32_t +glusterd_sync_volume (rpcsvc_request_t *req, dict_t *ctx) +{ +        int32_t      ret       = -1; + +        GF_ASSERT (req); +        GF_ASSERT (ctx); + +        glusterd_op_set_op (GD_OP_SYNC_VOLUME); +        glusterd_op_set_ctx (GD_OP_SYNC_VOLUME, ctx); +        glusterd_op_set_ctx_free (GD_OP_SYNC_VOLUME, _gf_true); +        glusterd_op_set_req (req); + +        ret = glusterd_op_txn_begin (); + +        return ret; +} +  int32_t  glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags) diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 651cb22e0..a6c1c779a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -84,7 +84,7 @@ glusterd_destroy_commit_ctx (glusterd_op_commit_ctx_t *ctx)          GF_FREE (ctx);  } -static void +void  glusterd_set_volume_status (glusterd_volinfo_t  *volinfo,                              glusterd_volume_status status)  { @@ -99,6 +99,27 @@ glusterd_is_volume_started (glusterd_volinfo_t  *volinfo)          return (!(volinfo->status == GLUSTERD_STATUS_STARTED));  } +gf_boolean_t +glusterd_are_all_volumes_stopped () +{ +        glusterd_conf_t                         *priv = NULL; +        xlator_t                                *this = NULL; +        glusterd_volinfo_t                      *voliter = NULL; + +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); + +        list_for_each_entry (voliter, &priv->volumes, vol_list) { +                if (voliter->status == GLUSTERD_STATUS_STARTED) +                        return _gf_false; +        } + +        return _gf_true; + +} +  static int  glusterd_op_get_len (glusterd_op_t op)  { @@ -158,6 +179,7 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req)          int                     len = 0;          int                     ret = -1;          gd1_mgmt_stage_op_req   *stage_req = NULL; +        void                    *ctx = NULL;          GF_ASSERT (op < GD_OP_MAX);          GF_ASSERT (op > GD_OP_NONE); @@ -178,12 +200,18 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req)          stage_req->op = op;          //stage_req->buf.buf_len = len; +        ctx = (void*)glusterd_op_get_ctx (op); +        if (!ctx) { +                gf_log ("", GF_LOG_ERROR, "Null Context for " +                        "op %d", op); +                ret = -1; +                goto out; +        } +          switch (op) {                  case GD_OP_CREATE_VOLUME:                          { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                GF_ASSERT (dict); +                                dict_t  *dict = ctx;                                  ++glusterfs_port;                                  ret = dict_set_int32 (dict, "port", glusterfs_port);                                  ret = dict_allocate_and_serialize (dict, @@ -197,124 +225,36 @@ glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req)                  case GD_OP_START_VOLUME:                          { -                                glusterd_op_start_volume_ctx_t *ctx = NULL; -                                ctx = glusterd_op_get_ctx (op); -                                GF_ASSERT (ctx); +                                glusterd_op_start_volume_ctx_t *ctx1 = ctx;                                  stage_req->buf.buf_len  = -                                        strlen (ctx->volume_name); +                                        strlen (ctx1->volume_name);                                  stage_req->buf.buf_val = -                                        gf_strdup (ctx->volume_name); -                        } -                        break; - -                case GD_OP_STOP_VOLUME: -                        { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                if (!dict) { -                                        gf_log ("", GF_LOG_ERROR, "Null Context for " -                                                "stop volume"); -                                        ret = -1; -                                        goto out; -                                } -                                ret = dict_allocate_and_serialize (dict, -                                                &stage_req->buf.buf_val, -                                        (size_t *)&stage_req->buf.buf_len); -                                if (ret) { -                                        goto out; -                                } +                                        gf_strdup (ctx1->volume_name);                          }                          break;                  case GD_OP_DELETE_VOLUME:                          { -                                glusterd_op_delete_volume_ctx_t *ctx = NULL; -                                ctx = glusterd_op_get_ctx (op); -                                GF_ASSERT (ctx); +                                glusterd_op_delete_volume_ctx_t *ctx1 = ctx;                                  stage_req->buf.buf_len  = -                                        strlen (ctx->volume_name); +                                        strlen (ctx1->volume_name);                                  stage_req->buf.buf_val = -                                        gf_strdup (ctx->volume_name); +                                        gf_strdup (ctx1->volume_name);                          }                          break; +                case GD_OP_STOP_VOLUME:                  case GD_OP_ADD_BRICK: -                        { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                GF_ASSERT (dict); -                                ret = dict_allocate_and_serialize (dict, -                                                &stage_req->buf.buf_val, -                                        (size_t *)&stage_req->buf.buf_len); -                                if (ret) { -                                        goto out; -                                } -                        } -                        break; -                  case GD_OP_REPLACE_BRICK: -                        { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                GF_ASSERT (dict); -                                ret = dict_allocate_and_serialize (dict, -                                                &stage_req->buf.buf_val, -                                        (size_t *)&stage_req->buf.buf_len); -                                if (ret) { -                                        goto out; -                                } -                        } -                        break; -                  case GD_OP_SET_VOLUME: -                        { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                GF_ASSERT (dict); -                                ret = dict_allocate_and_serialize (dict, -                                                &stage_req->buf.buf_val, -                                        (size_t *)&stage_req->buf.buf_len); -                                if (ret) { -                                        goto out; -                                } -                        } -                        break; -                  case GD_OP_REMOVE_BRICK: -                        { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                GF_ASSERT (dict); -                                ret = dict_allocate_and_serialize (dict, -                                                &stage_req->buf.buf_val, -                                        (size_t *)&stage_req->buf.buf_len); -                                if (ret) { -                                        goto out; -                                } -                        } -                        break; -                  case GD_OP_LOG_FILENAME: -                        { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                GF_ASSERT (dict); -                                ret = dict_allocate_and_serialize (dict, -                                        &stage_req->buf.buf_val, -                                        (size_t *)&stage_req->buf.buf_len); -                                if (ret) { -                                        goto out; -                                } -                        } -                        break; -                  case GD_OP_LOG_ROTATE: +                case GD_OP_SYNC_VOLUME:                          { -                                dict_t  *dict = NULL; -                                dict = glusterd_op_get_ctx (op); -                                GF_ASSERT (dict); +                                dict_t  *dict = ctx;                                  ret = dict_allocate_and_serialize (dict, -                                        &stage_req->buf.buf_val, +                                                &stage_req->buf.buf_val,                                          (size_t *)&stage_req->buf.buf_len);                                  if (ret) {                                          goto out; @@ -334,31 +274,6 @@ out:  }  static int -glusterd_check_generate_start_nfs (glusterd_volinfo_t *volinfo) -{ -        int ret = -1; - -        if (!volinfo) { -                gf_log ("", GF_LOG_ERROR, "Invalid Arguments"); -                goto out; -        } - -        ret = volgen_generate_nfs_volfile (volinfo); -        if (ret) -                goto out; - -        if (glusterd_is_nfs_started ()) { -                ret = glusterd_nfs_server_stop (); -                if (ret) -                        goto out; -        } - -        ret = glusterd_nfs_server_start (); -out: -        return ret; -} - -static int  glusterd_op_stage_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)  {          int                                     ret = 0; @@ -455,8 +370,9 @@ glusterd_op_stage_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)                  snprintf (cmd_str, 1024, "%s", brick_info->path);                  ret = glusterd_resolve_brick (brick_info);                  if (ret) { -                        gf_log ("glusterd", GF_LOG_ERROR, -                                "cannot resolve brick"); +                        gf_log ("glusterd", GF_LOG_ERROR, "cannot resolve " +                                "brick: %s:%s", brick_info->hostname, +                                brick_info->path);                          goto out;                  } @@ -466,7 +382,7 @@ glusterd_op_stage_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)                                  snprintf (msg, 2048,"Volume name %s, brick"                                          ": %s:%s, path %s not present", volname,                                            brick_info->hostname, brick_info->path, brick_info->path); -                                gf_log ("glusterd",GF_LOG_ERROR, "%s", msg);  +                                gf_log ("glusterd",GF_LOG_ERROR, "%s", msg);                                  *op_errstr = gf_strdup (msg);                                  goto out;                          } @@ -722,7 +638,7 @@ glusterd_op_stage_add_brick (gd1_mgmt_stage_op_req *req, char **op_errstr)          struct stat                             st_buf = {0,};          char                                    cmd_str[1024];          glusterd_conf_t                         *priv = NULL; -        char                                    msg[2048]; +        char                                    msg[2048] = {0,};          GF_ASSERT (req); @@ -928,7 +844,7 @@ out:  static int  glusterd_op_stage_log_filename (gd1_mgmt_stage_op_req *req)  { -        int                                     ret = 0; +        int                                     ret = -1;          dict_t                                  *dict = NULL;          char                                    *volname = NULL;          gf_boolean_t                            exists = _gf_false; @@ -970,7 +886,7 @@ out:  static int  glusterd_op_stage_log_rotate (gd1_mgmt_stage_op_req *req)  { -        int                                     ret = 0; +        int                                     ret = -1;          dict_t                                  *dict = NULL;          char                                    *volname = NULL;          gf_boolean_t                            exists = _gf_false; @@ -1134,7 +1050,7 @@ glusterd_check_option_exists(char *optstring)  static int  glusterd_op_stage_remove_brick (gd1_mgmt_stage_op_req *req)  { -        int                                     ret = 0; +        int                                     ret = -1;          dict_t                                  *dict = NULL;          char                                    *volname = NULL;          glusterd_volinfo_t                      *volinfo = NULL; @@ -1203,6 +1119,80 @@ out:  }  static int +glusterd_op_stage_sync_volume (gd1_mgmt_stage_op_req *req, char **op_errstr) +{ +        int                                     ret = -1; +        dict_t                                  *dict = NULL; +        char                                    *volname = NULL; +        char                                    *hostname = NULL; +        gf_boolean_t                            exists = _gf_false; +        glusterd_peerinfo_t                     *peerinfo = NULL; +        char                                    msg[2048] = {0,}; + +        GF_ASSERT (req); + +        dict = dict_new (); +        if (!dict) +                goto out; + +        ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to unserialize dict"); +                goto out; +        } + +        ret = dict_get_str (dict, "hostname", &hostname); +        if (ret) { +                snprintf (msg, sizeof (msg), "hostname couldn't be " +                          "retrieved from msg"); +                *op_errstr = gf_strdup (msg); +                goto out; +        } + +        ret = glusterd_is_local_addr (hostname); +        if (ret) { +                ret = glusterd_friend_find (NULL, hostname, &peerinfo); +                if (ret) { +                        snprintf (msg, sizeof (msg), "%s, is not a friend", +                                  hostname); +                        *op_errstr = gf_strdup (msg); +                        goto out; +                } + +                if (!peerinfo->connected) { +                        snprintf (msg, sizeof (msg), "%s, is not connected at " +                                  "the moment", hostname); +                        *op_errstr = gf_strdup (msg); +                        ret = -1; +                        goto out; +                } +        } else { + +                //volname is not present in case of sync all +                ret = dict_get_str (dict, "volname", &volname); +                if (!ret) { +                        exists = glusterd_check_volume_exists (volname); +                        if (!exists) { +                                snprintf (msg, sizeof (msg), "volume: %s, " +                                         "doesn't exist", volname); +                                *op_errstr = gf_strdup (msg); +                                ret = -1; +                                goto out; +                        } +                } else { +                        ret = 0; +                } +        } + +out: +        if (dict) +                dict_unref (dict); +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +static int  glusterd_op_create_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)  {          int                   ret        = 0; @@ -2390,7 +2380,7 @@ glusterd_op_set_volume (gd1_mgmt_stage_op_req *req)          dict = dict_new ();          if (!dict)                  goto out; -	 +          ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict);          if (ret) { @@ -2454,9 +2444,9 @@ glusterd_op_set_volume (gd1_mgmt_stage_op_req *req)  		ret = -1;  		goto out;          } -	 -	 + +          gf_log ("", GF_LOG_DEBUG, "Received set volume command"); @@ -2469,7 +2459,7 @@ out:  static int  glusterd_op_remove_brick (gd1_mgmt_stage_op_req *req)  { -        int                                     ret = 0; +        int                                     ret = -1;          dict_t                                  *dict = NULL;          char                                    *volname = NULL;          glusterd_conf_t                         *priv = NULL; @@ -2642,18 +2632,17 @@ glusterd_op_start_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)  {          int                                     ret = 0;          char                                    volname[1024] = {0,}; -        glusterd_conf_t                         *priv = NULL;          glusterd_volinfo_t                      *volinfo = NULL; +        glusterd_conf_t                         *priv = NULL;          glusterd_brickinfo_t                    *brickinfo = NULL;          xlator_t                                *this = NULL;          int32_t                                 mybrick = 0; -        GF_ASSERT (req); -          this = THIS;          GF_ASSERT (this);          priv = this->private;          GF_ASSERT (priv); +        GF_ASSERT (req);          strncpy (volname, req->buf.buf_val, req->buf.buf_len); @@ -2661,8 +2650,18 @@ glusterd_op_start_volume (gd1_mgmt_stage_op_req *req, char **op_errstr)          if (ret)                  goto out; -          list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                if (uuid_is_null (brickinfo->uuid)) { +                        ret = glusterd_resolve_brick (brickinfo); +                        if (ret) { +                                gf_log ("glusterd", GF_LOG_ERROR, +                                        "cannot resolve brick: %s:%s", +                                        brickinfo->hostname, brickinfo->path); +                                goto out; +                        } + +                } +                  if (!uuid_compare (brickinfo->uuid, priv->uuid)) {                          gf_log ("", GF_LOG_NORMAL, "About to start glusterfs"                                  " for brick %s:%s", brickinfo->hostname, @@ -2697,7 +2696,7 @@ out:  static int  glusterd_op_log_filename (gd1_mgmt_stage_op_req *req)  { -        int                   ret                = 0; +        int                   ret                = -1;          dict_t               *dict               = NULL;          glusterd_conf_t      *priv               = NULL;          glusterd_volinfo_t   *volinfo            = NULL; @@ -2785,7 +2784,7 @@ out:  static int  glusterd_op_log_rotate (gd1_mgmt_stage_op_req *req)  { -        int                   ret                = 0; +        int                   ret                = -1;          dict_t               *dict               = NULL;          glusterd_conf_t      *priv               = NULL;          glusterd_volinfo_t   *volinfo            = NULL; @@ -2901,10 +2900,10 @@ glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req)          char                                    *volname = NULL;          glusterd_conf_t                         *priv = NULL;          glusterd_volinfo_t                      *volinfo = NULL; -        glusterd_brickinfo_t                    *brickinfo = NULL;          xlator_t                                *this = NULL; -        int32_t                                 mybrick = 0;          dict_t                                  *dict = NULL; +        glusterd_brickinfo_t                    *brickinfo = NULL; +        int32_t                                 mybrick = 0;          this = THIS;          GF_ASSERT (this); @@ -2925,6 +2924,16 @@ glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req)                  goto out;          list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                if (uuid_is_null (brickinfo->uuid)) { +                        ret = glusterd_resolve_brick (brickinfo); +                        if (ret) { +                                gf_log ("glusterd", GF_LOG_ERROR, +                                        "cannot resolve brick: %s:%s", +                                        brickinfo->hostname, brickinfo->path); +                                goto out; +                        } + +                }                  if (!uuid_compare (brickinfo->uuid, priv->uuid)) {                          gf_log ("", GF_LOG_NORMAL, "About to stop glusterfs"                                  " for brick %s:%s", brickinfo->hostname, @@ -2957,7 +2966,6 @@ glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req)          } else {                  ret = glusterd_check_generate_start_nfs (volinfo);          } -  out:          if (flags & GF_CLI_FLAG_OP_FORCE)                  ret = 0; @@ -2967,6 +2975,91 @@ out:  }  static int +glusterd_op_sync_volume (gd1_mgmt_stage_op_req *req, char **op_errstr, +                         dict_t *rsp_dict) +{ +        int                                     ret = -1; +        dict_t                                  *dict = NULL; +        char                                    *volname = NULL; +        char                                    *hostname = NULL; +        char                                    msg[2048] = {0,}; +        int                                     count = 1; +        int                                     vol_count = 0; +        glusterd_conf_t                         *priv = NULL; +        glusterd_volinfo_t                      *volinfo = NULL; +        xlator_t                                *this = NULL; + +        GF_ASSERT (req); +        this = THIS; +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); + + +        dict = dict_new (); +        if (!dict) +                goto out; + +        ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to unserialize dict"); +                goto out; +        } + +        ret = dict_get_str (dict, "hostname", &hostname); +        if (ret) { +                snprintf (msg, sizeof (msg), "hostname couldn't be " +                          "retrieved from msg"); +                *op_errstr = gf_strdup (msg); +                goto out; +        } + +        if (glusterd_is_local_addr (hostname)) { +                ret = 0; +                goto out; +        } + +        //volname is not present in case of sync all +        ret = dict_get_str (dict, "volname", &volname); +        if (!ret) { +                ret = glusterd_volinfo_find (volname, &volinfo); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Volume with name: %s " +                                "not exists", volname); +                        goto out; +                } +        } + +        if (!rsp_dict) { +                //this should happen only on source +                ret = 0; +                goto out; +        } + +        if (volname) { +                ret = glusterd_add_volume_to_dict (volinfo, rsp_dict, +                                                   1); +                vol_count = 1; +        } else { +                list_for_each_entry (volinfo, &priv->volumes, vol_list) { +                        ret = glusterd_add_volume_to_dict (volinfo, +                                                           rsp_dict, count); +                        if (ret) +                                goto out; + +                        vol_count = count++; +                } +        } +        ret = dict_set_int32 (rsp_dict, "count", vol_count); +out: +        if (dict) +                dict_unref (dict); +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +static int  glusterd_op_ac_none (glusterd_op_sm_event_t *event, void *ctx)  {          int ret = 0; @@ -3475,6 +3568,19 @@ glusterd_op_send_cli_response (int32_t op, int32_t op_ret,                                  sfunc = gf_xdr_serialize_cli_log_rotate_rsp;                                  break;                          } +                case GD_MGMT_CLI_SYNC_VOLUME: +                        { +                                gf1_cli_sync_volume_rsp rsp = {0,}; +                                rsp.op_ret = op_ret; +                                rsp.op_errno = op_errno; +                                if (op_errstr) +                                        rsp.op_errstr = op_errstr; +                                else +                                        rsp.op_errstr = ""; +                                cli_rsp = &rsp; +                                sfunc = gf_xdr_from_cli_sync_volume_rsp; +                                break; +                        }          }          ret = glusterd_submit_reply (req, cli_rsp, NULL, 0, NULL, @@ -3635,6 +3741,7 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)          glusterd_op_commit_ctx_t        *commit_ctx = NULL;          int32_t                         status = 0;          char                            *op_errstr = NULL; +        dict_t                          *rsp_dict = NULL;          GF_ASSERT (ctx); @@ -3642,14 +3749,27 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)          req = &commit_ctx->stage_req; -        status = glusterd_op_commit_perform (req, &op_errstr); +        rsp_dict = dict_new (); +        if (!rsp_dict) { +                gf_log ("", GF_LOG_DEBUG, +                        "Out of memory"); +                ret = -1; +                goto out; +        } + + +        status = glusterd_op_commit_perform (req, &op_errstr, rsp_dict);          if (status) {                  gf_log ("", GF_LOG_ERROR, "Commit failed: %d", status);          } -        ret = glusterd_op_commit_send_resp (commit_ctx->req, req->op, status, op_errstr); +        ret = glusterd_op_commit_send_resp (commit_ctx->req, req->op, status, +                                            op_errstr, rsp_dict); +out: +        if (rsp_dict) +                dict_unref (rsp_dict);          if (op_errstr && (strcmp (op_errstr, "")))                  GF_FREE (op_errstr); @@ -3723,6 +3843,10 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req, char **op_errstr)                          ret = glusterd_op_stage_log_rotate (req);                          break; +                case GD_OP_SYNC_VOLUME: +                        ret = glusterd_op_stage_sync_volume (req, op_errstr); +                        break; +                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d",                                  req->op); @@ -3735,7 +3859,8 @@ glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req, char **op_errstr)  int32_t -glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr) +glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr, +                            dict_t *rsp_dict)  {          int     ret = -1; @@ -3782,6 +3907,10 @@ glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr)                          ret = glusterd_op_log_rotate (req);                          break; +                case GD_OP_SYNC_VOLUME: +                        ret = glusterd_op_sync_volume (req, op_errstr, rsp_dict); +                        break; +                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d",                                  req->op); @@ -4191,6 +4320,7 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx, gf_boolean_t ctx_free)                  case GD_OP_REPLACE_BRICK:                  case GD_OP_LOG_FILENAME:                  case GD_OP_LOG_ROTATE: +                case GD_OP_SYNC_VOLUME:                          dict_unref (ctx);                          break;                  case GD_OP_DELETE_VOLUME: diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index e14f00759..2f39d24f7 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -196,7 +196,8 @@ int32_t  glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req, char **op_errstr);  int32_t -glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr); +glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req, char **op_errstr, +                            dict_t* dict);  void *  glusterd_op_get_ctx (glusterd_op_t op); diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c index 602494b14..025fee775 100644 --- a/xlators/mgmt/glusterd/src/glusterd-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-sm.c @@ -620,6 +620,60 @@ glusterd_destroy_friend_event_context (glusterd_friend_sm_event_t *event)  }  int +glusterd_check_and_add_friend (glusterd_friend_sm_event_t *event) +{ +        rpcsvc_request_t                *req = NULL; +        glusterd_peerinfo_t             *peerinfo   = NULL; +        glusterd_friend_sm_event_type_t  event_type = 0; +        glusterd_friend_req_ctx_t       *fr_ctx = NULL; +        glusterd_probe_ctx_t            *pb_ctx = NULL; +        gf_boolean_t                    add_friend = _gf_false; +        char                            rhost[UNIX_PATH_MAX + 1] = {0}; +        char                            *host_str = NULL; +        int                             port       = 6969; //TODO, use standard +        int                             ret = 0; + +        peerinfo = event->peerinfo; +        event_type = event->event; + +        if (!peerinfo && +           (GD_FRIEND_EVENT_PROBE == event_type)) { +                add_friend = _gf_true; +                pb_ctx = event->ctx; +                req = pb_ctx->req; +        } +        if (!peerinfo && +            (GD_FRIEND_EVENT_RCVD_FRIEND_REQ == event_type)) { +                add_friend = _gf_true; +                fr_ctx = event->ctx; +                req = fr_ctx->req; +        } +        if (add_friend) { +                if (req) { +                        ret = glusterd_remote_hostname_get (req, rhost, +                                                            sizeof (rhost)); +                        if (!ret) +                                host_str = rhost; +                } +                ret = glusterd_friend_add ((const char*)host_str, port, +                                          GD_FRIEND_STATE_DEFAULT, +                                          NULL, NULL, &peerinfo, 0); +                if (ret) { +                        gf_log ("glusterd", GF_LOG_ERROR, "Unable to add peer, " +                                "ret = %d", ret); +                        ret = 1; +                        goto out; +                } +                GF_ASSERT (peerinfo); +                event->peerinfo = peerinfo; +        } +        ret = 0; + +out: +        return ret; +} + +int  glusterd_friend_sm ()  {          glusterd_friend_sm_event_t      *event      = NULL; @@ -629,32 +683,21 @@ glusterd_friend_sm ()          glusterd_sm_t                   *state      = NULL;          glusterd_peerinfo_t             *peerinfo   = NULL;          glusterd_friend_sm_event_type_t  event_type = 0; -        int                              port       = 6969; //TODO, use standard          gf_boolean_t                     is_await_conn = _gf_false; +        int                              loop       = 0;          while (!list_empty (&gd_friend_sm_queue)) {                  list_for_each_entry_safe (event, tmp, &gd_friend_sm_queue, list) {                          list_del_init (&event->list); -                        peerinfo = event->peerinfo;                          event_type = event->event; -                        if (!peerinfo && -                           (GD_FRIEND_EVENT_PROBE == event_type || -                            GD_FRIEND_EVENT_RCVD_FRIEND_REQ == event_type)) { -                                ret = glusterd_friend_add (NULL, port, -                                                          GD_FRIEND_STATE_DEFAULT, -                                                          NULL, NULL, &peerinfo, 0); - -                                if (ret) { -                                        gf_log ("glusterd", GF_LOG_ERROR, "Unable to add peer, " -                                                "ret = %d", ret); -                                        continue; -                                } -                                GF_ASSERT (peerinfo); -                                event->peerinfo = peerinfo; -                        } +                        loop = glusterd_check_and_add_friend (event); +                        if (loop) +                                continue; + +                        peerinfo = event->peerinfo;                          if (!peerinfo)                                  goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 017ab6873..358d6ffe4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -1000,6 +1000,7 @@ glusterd_is_cli_op_req (int32_t op)                  case GD_MGMT_CLI_LOG_FILENAME:                  case GD_MGMT_CLI_LOG_LOCATE:                  case GD_MGMT_CLI_LOG_ROTATE: +                case GD_MGMT_CLI_SYNC_VOLUME:                          return _gf_true;                          break;          } @@ -1452,7 +1453,6 @@ out:          return ret;  } -  int32_t  glusterd_import_friend_volumes (dict_t  *vols)  { @@ -1470,7 +1470,6 @@ glusterd_import_friend_volumes (dict_t  *vols)                  ret = glusterd_import_friend_volume (vols, i);                  if (ret)                          goto out; -                  i++;          } @@ -1645,27 +1644,6 @@ glusterd_nfs_server_stop ()          return glusterd_service_stop ("nfsd", pidfile, SIGTERM, _gf_false);  } -gf_boolean_t -glusterd_are_all_volumes_stopped () -{ -        glusterd_conf_t                         *priv = NULL; -        xlator_t                                *this = NULL; -        glusterd_volinfo_t                      *voliter = NULL; - -        this = THIS; -        GF_ASSERT (this); -        priv = this->private; -        GF_ASSERT (priv); - -        list_for_each_entry (voliter, &priv->volumes, vol_list) { -                if (voliter->status == GLUSTERD_STATUS_STARTED) -                        return _gf_false; -        } - -        return _gf_true; - -} -  int  glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)  { @@ -1691,3 +1669,50 @@ glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)          return 0;  } +int +glusterd_check_generate_start_nfs (glusterd_volinfo_t *volinfo) +{ +        int ret = -1; + +        if (!volinfo) { +                gf_log ("", GF_LOG_ERROR, "Invalid Arguments"); +                goto out; +        } + +        ret = volgen_generate_nfs_volfile (volinfo); +        if (ret) +                goto out; + +        if (glusterd_is_nfs_started ()) { +                ret = glusterd_nfs_server_stop (); +                if (ret) +                        goto out; +        } + +        ret = glusterd_nfs_server_start (); +out: +        return ret; +} + +int +glusterd_volume_count_get (void) +{ +        glusterd_volinfo_t      *tmp_volinfo = NULL; +        int32_t                 ret = 0; +        xlator_t                *this = NULL; +        glusterd_conf_t         *priv = NULL; + +        this = THIS; +        GF_ASSERT (this); + +        priv = this->private; + +        list_for_each_entry (tmp_volinfo, &priv->volumes, vol_list) { +                ret++; +        } + + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; + +} diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index a74fa871f..e03968dfe 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -143,10 +143,19 @@ glusterd_nfs_server_stop ();  int  glusterd_file_copy (int out, int in); -gf_boolean_t -glusterd_are_all_volumes_stopped (); -  int  glusterd_remote_hostname_get (rpcsvc_request_t *req,                                char *remote_host, int len); +int32_t +glusterd_import_friend_volumes (dict_t  *vols); +void +glusterd_set_volume_status (glusterd_volinfo_t  *volinfo, +                            glusterd_volume_status status); +int +glusterd_check_generate_start_nfs (glusterd_volinfo_t *volinfo); +int32_t +glusterd_volume_count_get (void); +int32_t +glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, +                             dict_t  *dict, int32_t count);  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index cfa229301..48d78bc33 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -296,7 +296,8 @@ glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,  int  glusterd_op_commit_send_resp (rpcsvc_request_t *req, -                               int32_t op, int32_t status, char *op_errstr); +                              int32_t op, int32_t status, char *op_errstr, +                              dict_t *rsp_dict);  int  glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname, int port); @@ -365,8 +366,12 @@ glusterd_handle_log_locate (rpcsvc_request_t *req);  int  glusterd_handle_log_rotate (rpcsvc_request_t *req); +int +glusterd_handle_sync_volume (rpcsvc_request_t *req); +  int32_t  glusterd_log_filename (rpcsvc_request_t *req, dict_t *dict); +  int32_t  glusterd_log_rotate (rpcsvc_request_t *req, dict_t *dict); @@ -386,4 +391,9 @@ glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,  int  glusterd_fetchspec_notify (xlator_t *this); +int32_t +glusterd_sync_volume (rpcsvc_request_t *req, dict_t *ctx); +int +glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo, +                                    dict_t  *volumes, int   count);  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c index 244b71009..99b5f7b4e 100644 --- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c +++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c @@ -553,6 +553,23 @@ out:  }  static int32_t +glusterd_sync_use_rsp_dict (dict_t *rsp_dict) +{ +        int      ret      = 0; + +        GF_ASSERT (rsp_dict); + +        if (!rsp_dict) { +                goto out; +        } + +        ret = glusterd_import_friend_volumes (rsp_dict); +out: +        return ret; + +} + +static int32_t  glusterd_rb_use_rsp_dict (dict_t *rsp_dict)  {          int32_t  src_port = 0; @@ -663,10 +680,19 @@ glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,                          goto out;                  }          } else { -                if (rsp.op == GD_OP_REPLACE_BRICK) { +                switch (rsp.op) { +                case GD_OP_REPLACE_BRICK:                          ret = glusterd_rb_use_rsp_dict (dict);                          if (ret)                                  goto out; +                        break; +                case GD_OP_SYNC_VOLUME: +                        ret = glusterd_sync_use_rsp_dict (dict); +                        if (ret) +                                goto out; +                        break; +                default: +                        break;                  }                  event_type = GD_OP_EVENT_RCVD_ACC;          } @@ -956,7 +982,8 @@ glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this,          list_for_each_entry (peerinfo, &priv->peers, uuid_list) {                  GF_ASSERT (peerinfo); -                if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) +                if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) && +                    (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))                          continue;                  dummy_frame = create_frame (this, this->ctx->pool); @@ -1007,7 +1034,8 @@ glusterd3_1_cluster_unlock (call_frame_t *frame, xlator_t *this,          list_for_each_entry (peerinfo, &priv->peers, uuid_list) {                  GF_ASSERT (peerinfo); -                if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) +                if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) && +                    (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))                          continue;                  dummy_frame = create_frame (this, this->ctx->pool); @@ -1091,7 +1119,8 @@ glusterd3_1_stage_op (call_frame_t *frame, xlator_t *this,          list_for_each_entry (peerinfo, &priv->peers, uuid_list) {                  GF_ASSERT (peerinfo); -                if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) +                if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) && +                    (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))                          continue;                  dummy_frame = create_frame (this, this->ctx->pool); @@ -1171,7 +1200,8 @@ glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this,          if (ret)                  goto out; -        ret = glusterd_op_commit_perform ((gd1_mgmt_stage_op_req *)req, &op_errstr); +        ret = glusterd_op_commit_perform ((gd1_mgmt_stage_op_req *)req, &op_errstr, +                                          NULL);//rsp_dict invalid for source          if (ret) {                  gf_log ("", GF_LOG_ERROR, "Commit failed"); @@ -1182,7 +1212,8 @@ glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this,          list_for_each_entry (peerinfo, &priv->peers, uuid_list) {                  GF_ASSERT (peerinfo); -                if (peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) +                if ((peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED) && +                    (glusterd_op_get_op() != GD_OP_SYNC_VOLUME))                          continue;                  dummy_frame = create_frame (this, this->ctx->pool); @@ -1339,6 +1370,10 @@ glusterd_handle_rpc_msg (rpcsvc_request_t *req)                          ret = glusterd_handle_set_volume (req);  			break; +                case GD_MGMT_CLI_SYNC_VOLUME: +                        ret = glusterd_handle_sync_volume (req); +                        break; +                  default:  			gf_log("", GF_LOG_ERROR, "Recieved Invalid procnum:%d",  			       req->procnum); @@ -1393,7 +1428,7 @@ rpcsvc_actor_t glusterd1_mgmt_actors[] = {          [GD_MGMT_CLI_LOG_LOCATE] = { "LOG LOCATE", GD_MGMT_CLI_LOG_LOCATE, glusterd_handle_log_locate, NULL, NULL},          [GD_MGMT_CLI_LOG_ROTATE] = { "LOG FILENAME", GD_MGMT_CLI_LOG_ROTATE, glusterd_handle_rpc_msg, NULL, NULL},          [GD_MGMT_CLI_SET_VOLUME] = { "SET_VOLUME", GD_MGMT_CLI_SET_VOLUME, glusterd_handle_rpc_msg, NULL, NULL}, - +        [GD_MGMT_CLI_SYNC_VOLUME] = { "SYNC_VOLUME", GD_MGMT_CLI_SYNC_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},  };  /*rpcsvc_actor_t glusterd1_mgmt_actors[] = {  | 
