Patchwork [BUG:1161] Changes for volume commands

login
register
Submitter Vijay Bellur
Date 2010-07-19 11:24:25
Message ID <20100719112425.GA2374@dev.gluster.com>
Download mbox | patch
Permalink /patch/3749/
State Accepted
Delegated to: Anand Avati
Headers show

Comments

Vijay Bellur - 2010-07-19 11:24:25
Signed-off-by: Vijay Bellur <vijay@gluster.com>
---
 cli/src/cli-cmd-volume.c                       |    4 +-
 cli/src/cli.c                                  |    7 +-
 cli/src/cli3_1-cops.c                          |  136 +++++++-
 contrib/uuid/uuid.h                            |    1 +
 contrib/uuid/uuidP.h                           |    2 +-
 rpc/rpc-lib/src/protocol-common.h              |    1 +
 rpc/xdr/src/cli1-xdr.c                         |   37 ++-
 rpc/xdr/src/cli1-xdr.h                         |   44 ++-
 rpc/xdr/src/cli1.c                             |   29 ++
 rpc/xdr/src/cli1.h                             |   12 +
 rpc/xdr/src/cli1.x                             |   17 +-
 rpc/xdr/src/glusterd1-xdr.c                    |   40 ++-
 rpc/xdr/src/glusterd1-xdr.h                    |   18 +
 rpc/xdr/src/glusterd1.c                        |   15 +
 rpc/xdr/src/glusterd1.h                        |    5 +
 rpc/xdr/src/glusterd1.x                        |   14 +-
 xlators/mgmt/glusterd/src/glusterd-ha.c        |   57 ++-
 xlators/mgmt/glusterd/src/glusterd-handler.c   |  481 +++++++++++++++++-------
 xlators/mgmt/glusterd/src/glusterd-mem-types.h |    5 +
 xlators/mgmt/glusterd/src/glusterd-op-sm.c     |  445 ++++++++++++++++++++---
 xlators/mgmt/glusterd/src/glusterd-op-sm.h     |    6 +-
 xlators/mgmt/glusterd/src/glusterd-sm.c        |   74 +++--
 xlators/mgmt/glusterd/src/glusterd-sm.h        |    7 +
 xlators/mgmt/glusterd/src/glusterd-utils.c     |  290 ++++++++++++++-
 xlators/mgmt/glusterd/src/glusterd-utils.h     |   26 ++
 xlators/mgmt/glusterd/src/glusterd.c           |    9 +-
 xlators/mgmt/glusterd/src/glusterd.h           |   35 ++-
 xlators/mgmt/glusterd/src/glusterd3_1-mops.c   |   87 ++++-
 28 files changed, 1655 insertions(+), 249 deletions(-)

Patch

diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index dd15a78..af06d89 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -51,12 +51,12 @@  cli_cmd_volume_info_cbk (struct cli_state *state, struct cli_cmd_word *word,
                 goto out;
 
         if (proc->fn) {
-                ret = proc->fn (frame, THIS, "localhost");
+                ret = proc->fn (frame, THIS, NULL);
         }
 
 out:
         if (ret)
-                cli_out ("Probe failed!");
+                cli_out ("Getting Volume information failed!");
         return ret;
 
 }
diff --git a/cli/src/cli.c b/cli/src/cli.c
index 96261de..5bf32ec 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -460,13 +460,14 @@  main (int argc, char *argv[])
         if (ret)
                 goto out;
 
+        global_rpc = cli_rpc_init (&state);
+        if (!global_rpc)
+                goto out;
+
         ret = cli_input_init (&state);
         if (ret)
                 goto out;
 
-        global_rpc = cli_rpc_init (&state);
-        if (!global_rpc)
-                goto out;
 
         ret = event_dispatch (ctx->event_pool);
 
diff --git a/cli/src/cli3_1-cops.c b/cli/src/cli3_1-cops.c
index 95d0a70..f0d20ec 100644
--- a/cli/src/cli3_1-cops.c
+++ b/cli/src/cli3_1-cops.c
@@ -127,6 +127,7 @@  gf_cli3_1_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
 
                 if (!rsp.friends.friends_len) {
                         cli_out ("No peers present");
+                        ret = 0;
                         goto out;
                 }
 
@@ -193,7 +194,113 @@  out:
         return ret;
 }
 
+int
+gf_cli3_1_get_volume_cbk (struct rpc_req *req, struct iovec *iov,
+                             int count, void *myframe)
+{
+        gf1_cli_get_vol_rsp        rsp   = {0,};
+        int                        ret   = 0;
+        dict_t                     *dict = NULL;
+        char                       *volname = NULL;
+        int32_t                    i = 1;
+        char                       key[256] = {0,};
+        int32_t                    status = 0;
+        int32_t                    type = 0;
+        int32_t                    brick_count = 0;
+
+        if (-1 == req->rpc_status) {
+                goto out;
+        }
+
+        ret = gf_xdr_to_cli_get_vol_rsp (*iov, &rsp);
+        if (ret < 0) {
+                gf_log ("", GF_LOG_ERROR, "error");
+                //rsp.op_ret   = -1;
+                //rsp.op_errno = EINVAL;
+                goto out;
+        }
+
+
+        gf_log ("cli", GF_LOG_NORMAL, "Received resp to get vol: %d",
+                rsp.op_ret);
+
+        if (!rsp.op_ret) {
+
+                if (!rsp.volumes.volumes_len) {
+                        cli_out ("No volumes present");
+                        ret = 0;
+                        goto out;
+                }
+
+                dict = dict_new ();
+
+                if (!dict) {
+                        ret = -1;
+                        goto out;
+                }
+
+                ret = dict_unserialize (rsp.volumes.volumes_val,
+                                        rsp.volumes.volumes_len,
+                                        &dict);
+
+                if (ret) {
+                        gf_log ("", GF_LOG_ERROR,
+                                        "Unable to allocate memory");
+                        goto out;
+                }
+
+                ret = dict_get_int32 (dict, "count", &count);
+
+                if (ret) {
+                        goto out;
+                }
+
+                cli_out ("Number of Volumes: %d", count);
+
+                while ( i <= count) {
+                        snprintf (key, 256, "volume%d.name", i);
+                        ret = dict_get_str (dict, key, &volname);
+                        if (ret)
+                                goto out;
+
+                        snprintf (key, 256, "volume%d.type", i);
+                        ret = dict_get_int32 (dict, key, &type);
+                        if (ret)
+                                goto out;
+
+                        snprintf (key, 256, "volume%d.status", i);
+                        ret = dict_get_int32 (dict, key, &status);
+                        if (ret)
+                                goto out;
+
+                        snprintf (key, 256, "volume%d.brick_count", i);
+                        ret = dict_get_int32 (dict, key, &brick_count);
+                        if (ret)
+                                goto out;
+
+                        cli_out ("Volume Name:%s, type:%d, status:%d,"
+                                  "brick_count: %d\n",
+                                  volname, type, status, brick_count);
+                        i++;
+                }
+        } else {
+                ret = -1;
+                goto out;
+        }
+
+
+        ret = 0;
+
+out:
+        cli_cmd_broadcast_response ();
+        if (ret)
+                cli_out ("Command Execution Failed\n");
+
+        if (dict)
+                dict_destroy (dict);
 
+        return ret;
+}
 int
 gf_cli3_1_create_volume_cbk (struct rpc_req *req, struct iovec *iov,
                              int count, void *myframe)
@@ -561,6 +668,32 @@  out:
         return ret;
 }
 
+int32_t
+gf_cli3_1_get_volume (call_frame_t *frame, xlator_t *this,
+                        void *data)
+{
+        gf1_cli_get_vol_req     req = {0,};
+        int                     ret = 0;
+
+        if (!frame || !this) {
+                ret = -1;
+                goto out;
+        }
+
+        req.flags = GF_CLI_GET_VOLUME_ALL;
+
+        ret = cli_submit_request (&req, frame, cli_rpc_prog,
+                                   GD_MGMT_CLI_GET_VOLUME, NULL,
+                                   gf_xdr_from_cli_get_vol_req,
+                                   this, gf_cli3_1_get_volume_cbk);
+
+        if (!ret) {
+                ret = cli_cmd_await_response ();
+        }
+out:
+        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+        return ret;
+}
 
 int32_t
 gf_cli3_1_create_volume (call_frame_t *frame, xlator_t *this,
@@ -974,13 +1107,14 @@  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},
         [GF1_CLI_DEPROBE]  = { "DEPROBE_QUERY",  gf_cli3_1_deprobe},
-        [GF1_CLI_LIST_FRIENDS]  = { "DEPROBE_QUERY",  gf_cli3_1_list_friends},
+        [GF1_CLI_LIST_FRIENDS]  = { "LIST_FRIENDS",  gf_cli3_1_list_friends},
         [GF1_CLI_CREATE_VOLUME] = {"CREATE_VOLUME", gf_cli3_1_create_volume},
         [GF1_CLI_DELETE_VOLUME] = {"DELETE_VOLUME", gf_cli3_1_delete_volume},
         [GF1_CLI_START_VOLUME] = {"START_VOLUME", gf_cli3_1_start_volume},
         [GF1_CLI_STOP_VOLUME] = {"STOP_VOLUME", gf_cli3_1_stop_volume},
         [GF1_CLI_RENAME_VOLUME] = {"RENAME_VOLUME", gf_cli3_1_rename_volume},
         [GF1_CLI_DEFRAG_VOLUME] = {"DEFRAG_VOLUME", gf_cli3_1_defrag_volume},
+        [GF1_CLI_GET_VOLUME] = {"GET_VOLUME", gf_cli3_1_get_volume},
         [GF1_CLI_SET_VOLUME] = {"SET_VOLUME", gf_cli3_1_set_volume},
         [GF1_CLI_ADD_BRICK] = {"ADD_BRICK", gf_cli3_1_add_brick},
         [GF1_CLI_REMOVE_BRICK] = {"REMOVE_BRICK", gf_cli3_1_remove_brick},
diff --git a/contrib/uuid/uuid.h b/contrib/uuid/uuid.h
index ca846da..ab00665 100644
--- a/contrib/uuid/uuid.h
+++ b/contrib/uuid/uuid.h
@@ -35,6 +35,7 @@ 
 #ifndef _UUID_UUID_H
 #define _UUID_UUID_H
 
+#include "config.h"
 #include <sys/types.h>
 #ifndef _WIN32
 #include <sys/time.h>
diff --git a/contrib/uuid/uuidP.h b/contrib/uuid/uuidP.h
index 9d65558..9a2de61 100644
--- a/contrib/uuid/uuidP.h
+++ b/contrib/uuid/uuidP.h
@@ -32,6 +32,7 @@ 
  * %End-Header%
  */
 
+#include "uuid.h"
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #else
@@ -39,7 +40,6 @@ 
 #endif
 #include <sys/types.h>
 
-#include "uuid.h"
 
 /*
  * Offset between 15-Oct-1582 and 1-Jan-70
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index c4fc12a..5b6a2c3 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -84,6 +84,7 @@  enum gf_mgmt_procnum {
         GD_MGMT_STAGE_OP,
         GD_MGMT_COMMIT_OP,
         GD_MGMT_FRIEND_REMOVE,
+        GD_MGMT_FRIEND_UPDATE,
         GD_MGMT_CLI_PROBE,
         GD_MGMT_CLI_DEPROBE,
         GD_MGMT_CLI_LIST_FRIENDS,
diff --git a/rpc/xdr/src/cli1-xdr.c b/rpc/xdr/src/cli1-xdr.c
index 5cce70f..832f762 100644
--- a/rpc/xdr/src/cli1-xdr.c
+++ b/rpc/xdr/src/cli1-xdr.c
@@ -3,7 +3,7 @@ 
  * It was generated using rpcgen.
  */
 
-#include "cli1-xdr.h"
+#include "cli1.h"
 
 bool_t
 xdr_gf1_cluster_type (XDR *xdrs, gf1_cluster_type *objp)
@@ -24,7 +24,16 @@  xdr_gf1_cli_replace_op (XDR *xdrs, gf1_cli_replace_op *objp)
 }
 
 bool_t
-xdr_gf1_cli_enum_friends_list (XDR *xdrs, gf1_cli_enum_friends_list *objp)
+xdr_gf1_cli_friends_list (XDR *xdrs, gf1_cli_friends_list *objp)
+{
+
+	 if (!xdr_enum (xdrs, (enum_t *) objp))
+		 return FALSE;
+	return TRUE;
+}
+
+bool_t
+xdr_gf1_cli_get_volume (XDR *xdrs, gf1_cli_get_volume *objp)
 {
 
 	 if (!xdr_enum (xdrs, (enum_t *) objp))
@@ -101,6 +110,30 @@  xdr_gf1_cli_peer_list_rsp (XDR *xdrs, gf1_cli_peer_list_rsp *objp)
 }
 
 bool_t
+xdr_gf1_cli_get_vol_req (XDR *xdrs, gf1_cli_get_vol_req *objp)
+{
+
+	 if (!xdr_int (xdrs, &objp->flags))
+		 return FALSE;
+	 if (!xdr_bytes (xdrs, (char **)&objp->dict.dict_val, (u_int *) &objp->dict.dict_len, ~0))
+		 return FALSE;
+	return TRUE;
+}
+
+bool_t
+xdr_gf1_cli_get_vol_rsp (XDR *xdrs, gf1_cli_get_vol_rsp *objp)
+{
+
+	 if (!xdr_int (xdrs, &objp->op_ret))
+		 return FALSE;
+	 if (!xdr_int (xdrs, &objp->op_errno))
+		 return FALSE;
+	 if (!xdr_bytes (xdrs, (char **)&objp->volumes.volumes_val, (u_int *) &objp->volumes.volumes_len, ~0))
+		 return FALSE;
+	return TRUE;
+}
+
+bool_t
 xdr_gf1_cli_create_vol_req (XDR *xdrs, gf1_cli_create_vol_req *objp)
 {
 
diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h
index 81948b3..56dbef0 100644
--- a/rpc/xdr/src/cli1-xdr.h
+++ b/rpc/xdr/src/cli1-xdr.h
@@ -3,8 +3,8 @@ 
  * It was generated using rpcgen.
  */
 
-#ifndef _GLUSTER1_H_RPCGEN
-#define _GLUSTER1_H_RPCGEN
+#ifndef _CLI1_H_RPCGEN
+#define _CLI1_H_RPCGEN
 
 #include <rpc/rpc.h>
 
@@ -31,10 +31,15 @@  enum gf1_cli_replace_op {
 };
 typedef enum gf1_cli_replace_op gf1_cli_replace_op;
 
-enum gf1_cli_enum_friends_list {
+enum gf1_cli_friends_list {
 	GF_CLI_LIST_ALL = 1,
 };
-typedef enum gf1_cli_enum_friends_list gf1_cli_enum_friends_list;
+typedef enum gf1_cli_friends_list gf1_cli_friends_list;
+
+enum gf1_cli_get_volume {
+	GF_CLI_GET_VOLUME_ALL = 1,
+};
+typedef enum gf1_cli_get_volume gf1_cli_get_volume;
 
 struct gf1_cli_probe_req {
 	char *hostname;
@@ -79,6 +84,25 @@  struct gf1_cli_peer_list_rsp {
 };
 typedef struct gf1_cli_peer_list_rsp gf1_cli_peer_list_rsp;
 
+struct gf1_cli_get_vol_req {
+	int flags;
+	struct {
+		u_int dict_len;
+		char *dict_val;
+	} dict;
+};
+typedef struct gf1_cli_get_vol_req gf1_cli_get_vol_req;
+
+struct gf1_cli_get_vol_rsp {
+	int op_ret;
+	int op_errno;
+	struct {
+		u_int volumes_len;
+		char *volumes_val;
+	} volumes;
+};
+typedef struct gf1_cli_get_vol_rsp gf1_cli_get_vol_rsp;
+
 struct gf1_cli_create_vol_req {
 	char *volname;
 	gf1_cluster_type type;
@@ -236,13 +260,16 @@  typedef struct gf1_cli_set_vol_rsp gf1_cli_set_vol_rsp;
 #if defined(__STDC__) || defined(__cplusplus)
 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_enum_friends_list (XDR *, gf1_cli_enum_friends_list*);
+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_probe_req (XDR *, gf1_cli_probe_req*);
 extern  bool_t xdr_gf1_cli_probe_rsp (XDR *, gf1_cli_probe_rsp*);
 extern  bool_t xdr_gf1_cli_deprobe_req (XDR *, gf1_cli_deprobe_req*);
 extern  bool_t xdr_gf1_cli_deprobe_rsp (XDR *, gf1_cli_deprobe_rsp*);
 extern  bool_t xdr_gf1_cli_peer_list_req (XDR *, gf1_cli_peer_list_req*);
 extern  bool_t xdr_gf1_cli_peer_list_rsp (XDR *, gf1_cli_peer_list_rsp*);
+extern  bool_t xdr_gf1_cli_get_vol_req (XDR *, gf1_cli_get_vol_req*);
+extern  bool_t xdr_gf1_cli_get_vol_rsp (XDR *, gf1_cli_get_vol_rsp*);
 extern  bool_t xdr_gf1_cli_create_vol_req (XDR *, gf1_cli_create_vol_req*);
 extern  bool_t xdr_gf1_cli_create_vol_rsp (XDR *, gf1_cli_create_vol_rsp*);
 extern  bool_t xdr_gf1_cli_delete_vol_req (XDR *, gf1_cli_delete_vol_req*);
@@ -267,13 +294,16 @@  extern  bool_t xdr_gf1_cli_set_vol_rsp (XDR *, gf1_cli_set_vol_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_enum_friends_list ();
+extern bool_t xdr_gf1_cli_friends_list ();
+extern bool_t xdr_gf1_cli_get_volume ();
 extern bool_t xdr_gf1_cli_probe_req ();
 extern bool_t xdr_gf1_cli_probe_rsp ();
 extern bool_t xdr_gf1_cli_deprobe_req ();
 extern bool_t xdr_gf1_cli_deprobe_rsp ();
 extern bool_t xdr_gf1_cli_peer_list_req ();
 extern bool_t xdr_gf1_cli_peer_list_rsp ();
+extern bool_t xdr_gf1_cli_get_vol_req ();
+extern bool_t xdr_gf1_cli_get_vol_rsp ();
 extern bool_t xdr_gf1_cli_create_vol_req ();
 extern bool_t xdr_gf1_cli_create_vol_rsp ();
 extern bool_t xdr_gf1_cli_delete_vol_req ();
@@ -301,4 +331,4 @@  extern bool_t xdr_gf1_cli_set_vol_rsp ();
 }
 #endif
 
-#endif /* !_GLUSTER1_H_RPCGEN */
+#endif /* !_CLI1_H_RPCGEN */
diff --git a/rpc/xdr/src/cli1.c b/rpc/xdr/src/cli1.c
index 008353b..65252e3 100644
--- a/rpc/xdr/src/cli1.c
+++ b/rpc/xdr/src/cli1.c
@@ -107,6 +107,35 @@  gf_xdr_from_cli_peer_list_req (struct iovec outmsg, void *req)
         return xdr_serialize_generic (outmsg, (void *)req,
                                       (xdrproc_t)xdr_gf1_cli_peer_list_req);
 }
+
+ssize_t
+gf_xdr_serialize_cli_get_vol_rsp (struct iovec outmsg, void *rsp)
+{
+        return xdr_serialize_generic (outmsg, (void *)rsp,
+                                      (xdrproc_t)xdr_gf1_cli_get_vol_rsp);
+
+}
+
+ssize_t
+gf_xdr_to_cli_get_vol_req (struct iovec inmsg, void *args)
+{
+        return xdr_to_generic (inmsg, (void *)args,
+                               (xdrproc_t)xdr_gf1_cli_get_vol_req);
+}
+
+ssize_t
+gf_xdr_to_cli_get_vol_rsp (struct iovec inmsg, void *args)
+{
+        return xdr_to_generic (inmsg, (void *)args,
+                               (xdrproc_t)xdr_gf1_cli_get_vol_rsp);
+}
+
+ssize_t
+gf_xdr_from_cli_get_vol_req (struct iovec outmsg, void *req)
+{
+        return xdr_serialize_generic (outmsg, (void *)req,
+                                      (xdrproc_t)xdr_gf1_cli_get_vol_req);
+}
 ssize_t
 gf_xdr_serialize_cli_create_vol_rsp (struct iovec outmsg, void *rsp)
 {
diff --git a/rpc/xdr/src/cli1.h b/rpc/xdr/src/cli1.h
index ab67084..73f9f8d 100644
--- a/rpc/xdr/src/cli1.h
+++ b/rpc/xdr/src/cli1.h
@@ -181,4 +181,16 @@  gf_xdr_to_cli_set_vol_rsp (struct iovec inmsg, void *args);
 ssize_t
 gf_xdr_from_cli_set_vol_req (struct iovec outmsg, void *req);
 
+ssize_t
+gf_xdr_serialize_cli_get_vol_rsp (struct iovec outmsg, void *rsp);
+
+ssize_t
+gf_xdr_to_cli_get_vol_req (struct iovec inmsg, void *args);
+
+ssize_t
+gf_xdr_to_cli_get_vol_rsp (struct iovec inmsg, void *args);
+
+ssize_t
+gf_xdr_from_cli_get_vol_req (struct iovec outmsg, void *req);
+
 #endif /* !_CLI1_H */
diff --git a/rpc/xdr/src/cli1.x b/rpc/xdr/src/cli1.x
index a8af1b7..41f43a4 100644
--- a/rpc/xdr/src/cli1.x
+++ b/rpc/xdr/src/cli1.x
@@ -13,10 +13,14 @@ 
         GF_REPLACE_OP_STATUS
 } ;
 
-enum gf1_cli_enum_friends_list {
+enum gf1_cli_friends_list {
         GF_CLI_LIST_ALL = 1
 } ;
 
+enum gf1_cli_get_volume {
+        GF_CLI_GET_VOLUME_ALL = 1
+} ;
+
  struct gf1_cli_probe_req {
         string  hostname<>;
 }  ;
@@ -48,6 +52,17 @@  struct gf1_cli_peer_list_rsp {
         opaque  friends<>;
 } ;
 
+struct gf1_cli_get_vol_req {
+        int     flags;
+        opaque  dict<>;
+}  ;
+
+struct gf1_cli_get_vol_rsp {
+        int     op_ret;
+        int     op_errno;
+        opaque  volumes<>;
+} ;
+
  struct gf1_cli_create_vol_req {
         string  volname<>;
         gf1_cluster_type type;
diff --git a/rpc/xdr/src/glusterd1-xdr.c b/rpc/xdr/src/glusterd1-xdr.c
index 32e6687..3ad32d9 100644
--- a/rpc/xdr/src/glusterd1-xdr.c
+++ b/rpc/xdr/src/glusterd1-xdr.c
@@ -3,11 +3,21 @@ 
  * It was generated using rpcgen.
  */
 
-#include "glusterd1-xdr.h"
+#include "glusterd1.h"
+
+bool_t
+xdr_glusterd_volume_status (XDR *xdrs, glusterd_volume_status *objp)
+{
+
+	 if (!xdr_enum (xdrs, (enum_t *) objp))
+		 return FALSE;
+	return TRUE;
+}
 
 bool_t
 xdr_gd1_mgmt_probe_req (XDR *xdrs, gd1_mgmt_probe_req *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -19,6 +29,7 @@  xdr_gd1_mgmt_probe_req (XDR *xdrs, gd1_mgmt_probe_req *objp)
 bool_t
 xdr_gd1_mgmt_probe_rsp (XDR *xdrs, gd1_mgmt_probe_rsp *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -30,6 +41,7 @@  xdr_gd1_mgmt_probe_rsp (XDR *xdrs, gd1_mgmt_probe_rsp *objp)
 bool_t
 xdr_gd1_mgmt_friend_req (XDR *xdrs, gd1_mgmt_friend_req *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -41,6 +53,7 @@  xdr_gd1_mgmt_friend_req (XDR *xdrs, gd1_mgmt_friend_req *objp)
 bool_t
 xdr_gd1_mgmt_friend_rsp (XDR *xdrs, gd1_mgmt_friend_rsp *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -56,6 +69,7 @@  xdr_gd1_mgmt_friend_rsp (XDR *xdrs, gd1_mgmt_friend_rsp *objp)
 bool_t
 xdr_gd1_mgmt_unfriend_req (XDR *xdrs, gd1_mgmt_unfriend_req *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -67,6 +81,7 @@  xdr_gd1_mgmt_unfriend_req (XDR *xdrs, gd1_mgmt_unfriend_req *objp)
 bool_t
 xdr_gd1_mgmt_unfriend_rsp (XDR *xdrs, gd1_mgmt_unfriend_rsp *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -82,6 +97,7 @@  xdr_gd1_mgmt_unfriend_rsp (XDR *xdrs, gd1_mgmt_unfriend_rsp *objp)
 bool_t
 xdr_gd1_mgmt_cluster_lock_req (XDR *xdrs, gd1_mgmt_cluster_lock_req *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -91,6 +107,7 @@  xdr_gd1_mgmt_cluster_lock_req (XDR *xdrs, gd1_mgmt_cluster_lock_req *objp)
 bool_t
 xdr_gd1_mgmt_cluster_lock_rsp (XDR *xdrs, gd1_mgmt_cluster_lock_rsp *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -104,6 +121,7 @@  xdr_gd1_mgmt_cluster_lock_rsp (XDR *xdrs, gd1_mgmt_cluster_lock_rsp *objp)
 bool_t
 xdr_gd1_mgmt_cluster_unlock_req (XDR *xdrs, gd1_mgmt_cluster_unlock_req *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -113,6 +131,7 @@  xdr_gd1_mgmt_cluster_unlock_req (XDR *xdrs, gd1_mgmt_cluster_unlock_req *objp)
 bool_t
 xdr_gd1_mgmt_cluster_unlock_rsp (XDR *xdrs, gd1_mgmt_cluster_unlock_rsp *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -126,6 +145,7 @@  xdr_gd1_mgmt_cluster_unlock_rsp (XDR *xdrs, gd1_mgmt_cluster_unlock_rsp *objp)
 bool_t
 xdr_gd1_mgmt_stage_op_req (XDR *xdrs, gd1_mgmt_stage_op_req *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -139,6 +159,7 @@  xdr_gd1_mgmt_stage_op_req (XDR *xdrs, gd1_mgmt_stage_op_req *objp)
 bool_t
 xdr_gd1_mgmt_stage_op_rsp (XDR *xdrs, gd1_mgmt_stage_op_rsp *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -154,6 +175,7 @@  xdr_gd1_mgmt_stage_op_rsp (XDR *xdrs, gd1_mgmt_stage_op_rsp *objp)
 bool_t
 xdr_gd1_mgmt_commit_op_req (XDR *xdrs, gd1_mgmt_commit_op_req *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -167,6 +189,7 @@  xdr_gd1_mgmt_commit_op_req (XDR *xdrs, gd1_mgmt_commit_op_req *objp)
 bool_t
 xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 {
+
 	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
 		sizeof (u_char), (xdrproc_t) xdr_u_char))
 		 return FALSE;
@@ -178,3 +201,18 @@  xdr_gd1_mgmt_commit_op_rsp (XDR *xdrs, gd1_mgmt_commit_op_rsp *objp)
 		 return FALSE;
 	return TRUE;
 }
+
+bool_t
+xdr_gd1_mgmt_friend_update (XDR *xdrs, gd1_mgmt_friend_update *objp)
+{
+
+	 if (!xdr_vector (xdrs, (char *)objp->uuid, 16,
+		sizeof (u_char), (xdrproc_t) xdr_u_char))
+		 return FALSE;
+	 if (!xdr_vector (xdrs, (char *)objp->friend_uuid, 16,
+		sizeof (u_char), (xdrproc_t) xdr_u_char))
+		 return FALSE;
+	 if (!xdr_string (xdrs, &objp->hostname, ~0))
+		 return FALSE;
+	return TRUE;
+}
diff --git a/rpc/xdr/src/glusterd1-xdr.h b/rpc/xdr/src/glusterd1-xdr.h
index ee5fb9c..2fab3fd 100644
--- a/rpc/xdr/src/glusterd1-xdr.h
+++ b/rpc/xdr/src/glusterd1-xdr.h
@@ -14,6 +14,13 @@  extern "C" {
 #endif
 
 
+enum glusterd_volume_status {
+	GLUSTERD_STATUS_NONE = 0,
+	GLUSTERD_STATUS_STARTED = 0 + 1,
+	GLUSTERD_STATUS_STOPPED = 0 + 2,
+};
+typedef enum glusterd_volume_status glusterd_volume_status;
+
 struct gd1_mgmt_probe_req {
 	u_char uuid[16];
 	char *hostname;
@@ -114,9 +121,17 @@  struct gd1_mgmt_commit_op_rsp {
 };
 typedef struct gd1_mgmt_commit_op_rsp gd1_mgmt_commit_op_rsp;
 
+struct gd1_mgmt_friend_update {
+	u_char uuid[16];
+	u_char friend_uuid[16];
+	char *hostname;
+};
+typedef struct gd1_mgmt_friend_update gd1_mgmt_friend_update;
+
 /* the xdr functions */
 
 #if defined(__STDC__) || defined(__cplusplus)
+extern  bool_t xdr_glusterd_volume_status (XDR *, glusterd_volume_status*);
 extern  bool_t xdr_gd1_mgmt_probe_req (XDR *, gd1_mgmt_probe_req*);
 extern  bool_t xdr_gd1_mgmt_probe_rsp (XDR *, gd1_mgmt_probe_rsp*);
 extern  bool_t xdr_gd1_mgmt_friend_req (XDR *, gd1_mgmt_friend_req*);
@@ -131,8 +146,10 @@  extern  bool_t xdr_gd1_mgmt_stage_op_req (XDR *, gd1_mgmt_stage_op_req*);
 extern  bool_t xdr_gd1_mgmt_stage_op_rsp (XDR *, gd1_mgmt_stage_op_rsp*);
 extern  bool_t xdr_gd1_mgmt_commit_op_req (XDR *, gd1_mgmt_commit_op_req*);
 extern  bool_t xdr_gd1_mgmt_commit_op_rsp (XDR *, gd1_mgmt_commit_op_rsp*);
+extern  bool_t xdr_gd1_mgmt_friend_update (XDR *, gd1_mgmt_friend_update*);
 
 #else /* K&R C */
+extern bool_t xdr_glusterd_volume_status ();
 extern bool_t xdr_gd1_mgmt_probe_req ();
 extern bool_t xdr_gd1_mgmt_probe_rsp ();
 extern bool_t xdr_gd1_mgmt_friend_req ();
@@ -147,6 +164,7 @@  extern bool_t xdr_gd1_mgmt_stage_op_req ();
 extern bool_t xdr_gd1_mgmt_stage_op_rsp ();
 extern bool_t xdr_gd1_mgmt_commit_op_req ();
 extern bool_t xdr_gd1_mgmt_commit_op_rsp ();
+extern bool_t xdr_gd1_mgmt_friend_update ();
 
 #endif /* K&R C */
 
diff --git a/rpc/xdr/src/glusterd1.c b/rpc/xdr/src/glusterd1.c
index 76ceea3..6b079f4 100644
--- a/rpc/xdr/src/glusterd1.c
+++ b/rpc/xdr/src/glusterd1.c
@@ -86,6 +86,13 @@  gd_xdr_to_mgmt_friend_req (struct iovec inmsg, void *args)
 }
 
 ssize_t
+gd_xdr_to_mgmt_friend_update (struct iovec inmsg, void *args)
+{
+        return xdr_to_generic (inmsg, (void *)args,
+                               (xdrproc_t)xdr_gd1_mgmt_friend_update);
+}
+
+ssize_t
 gd_xdr_to_mgmt_cluster_lock_req (struct iovec inmsg, void *args)
 {
         return xdr_to_generic (inmsg, (void *)args,
@@ -165,6 +172,14 @@  gd_xdr_from_mgmt_probe_req (struct iovec outmsg, void *req)
 }
 
 ssize_t
+gd_xdr_from_mgmt_friend_update (struct iovec outmsg, void *req)
+{
+        return xdr_serialize_generic (outmsg, (void *)req,
+                                      (xdrproc_t)xdr_gd1_mgmt_friend_update);
+
+}
+
+ssize_t
 gd_xdr_from_mgmt_friend_req (struct iovec outmsg, void *req)
 {
         return xdr_serialize_generic (outmsg, (void *)req,
diff --git a/rpc/xdr/src/glusterd1.h b/rpc/xdr/src/glusterd1.h
index 44b1c54..b4c4e3d 100644
--- a/rpc/xdr/src/glusterd1.h
+++ b/rpc/xdr/src/glusterd1.h
@@ -98,4 +98,9 @@  gd_xdr_serialize_mgmt_commit_op_rsp (struct iovec outmsg, void *rsp);
 ssize_t
 gd_xdr_from_mgmt_commit_op_req (struct iovec outmsg, void *req);
 
+ssize_t
+gd_xdr_to_mgmt_friend_update (struct iovec outmsg, void *req);
+
+ssize_t
+gd_xdr_from_mgmt_friend_update (struct iovec outmsg, void *req);
 #endif /* !_MSG_GD_XDR_H */
diff --git a/rpc/xdr/src/glusterd1.x b/rpc/xdr/src/glusterd1.x
index 935fde4..f374ea4 100644
--- a/rpc/xdr/src/glusterd1.x
+++ b/rpc/xdr/src/glusterd1.x
@@ -1,3 +1,8 @@ 
+ enum glusterd_volume_status {
+        GLUSTERD_STATUS_NONE = 0,
+        GLUSTERD_STATUS_STARTED,
+        GLUSTERD_STATUS_STOPPED
+} ;
 
  struct gd1_mgmt_probe_req {
         unsigned char  uuid[16];
@@ -81,7 +86,8 @@  struct gd1_mgmt_commit_op_rsp {
         int     op_errno;
 }  ;
 
- 
-
-
-
+struct gd1_mgmt_friend_update {
+        unsigned char uuid[16];
+        unsigned char friend_uuid[16];
+        string        hostname<>;
+} ;
diff --git a/xlators/mgmt/glusterd/src/glusterd-ha.c b/xlators/mgmt/glusterd/src/glusterd-ha.c
index 49e7370..ebf6ce0 100644
--- a/xlators/mgmt/glusterd/src/glusterd-ha.c
+++ b/xlators/mgmt/glusterd/src/glusterd-ha.c
@@ -28,7 +28,6 @@ 
 #include "compat.h"
 #include "dict.h"
 #include "protocol-common.h"
-//#include "transport.h"
 #include "xlator.h"
 #include "logging.h"
 #include "timer.h"
@@ -49,6 +48,7 @@ 
 
 #include <sys/resource.h>
 #include <inttypes.h>
+#include <dirent.h>
 
 int32_t
 glusterd_ha_create_volume (glusterd_volinfo_t *volinfo)
@@ -111,31 +111,58 @@  glusterd_ha_delete_volume (glusterd_volinfo_t *volinfo)
 {
         char    pathname[PATH_MAX] = {0,};
         int32_t ret = -1;
-        char    filepath[PATH_MAX] = {0,};
+        glusterd_conf_t *priv = NULL;
+        DIR     *dir = NULL;
+        struct dirent *entry = NULL;
+        char path[PATH_MAX] = {0,};
 
         GF_ASSERT (volinfo);
-        snprintf (pathname, 1024, "%s/vols/%s", GLUSTERD_DEFAULT_WORKDIR,
-                  volinfo->volname);
+        priv = THIS->private;
 
-        snprintf (filepath, 1024, "%s/info", pathname);
-        ret = unlink (filepath);
+        GF_ASSERT (priv);
+        snprintf (pathname, 1024, "%s/vols/%s", priv->workdir,
+                  volinfo->volname);
 
-        if (-1 == ret) {
-                gf_log ("", GF_LOG_ERROR, "unlink() failed on path %s,"
-                        "errno: %d", filepath, errno);
+        dir = opendir (pathname);
+        if (!dir)
                 goto out;
+
+        entry = readdir (dir);
+        while (entry != NULL) {
+                if (!strcmp (entry->d_name, ".") ||
+                    !strcmp (entry->d_name, "..")) {
+                        entry = readdir (dir);
+                        continue;
+                }
+                snprintf (path, PATH_MAX, "%s/%s", pathname, entry->d_name);
+                if (DT_DIR  == entry->d_type)
+                        ret = rmdir (path);
+                else
+                        ret = unlink (path);
+
+                gf_log ("", GF_LOG_NORMAL, "%s %s",
+                                ret?"Failed to remove":"Removed",
+                                entry->d_name);
+                if (ret)
+                        gf_log ("", GF_LOG_NORMAL, "errno:%d", errno);
+                entry = readdir (dir);
+                memset (path, 0, sizeof(path));
         }
 
-        ret = rmdir (pathname);
+        ret = closedir (dir);
+        if (ret) {
+                gf_log ("", GF_LOG_NORMAL, "Failed to close dir, errno:%d",
+                        errno);
+        }
 
-        if (-1 == ret) {
-                gf_log ("", GF_LOG_ERROR, "rmdir() failed on path %s,"
-                        "errno: %d", pathname, errno);
-                goto out;
+        ret = rmdir (pathname);
+        if (ret) {
+                gf_log ("", GF_LOG_ERROR, "Failed to rmdir: %s, errno: %d",
+                        pathname, errno);
         }
 
-out:
 
+out:
         gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
 
         return ret;
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 086e62e..36dc83f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -69,6 +69,7 @@  glusterd_friend_find_by_hostname (const char *hoststr,
         int                     ret = -1;
         glusterd_conf_t         *priv = NULL;
         glusterd_peerinfo_t     *entry = NULL;
+        glusterd_peer_hostname_t *name = NULL;
 
         GF_ASSERT (hoststr);
         GF_ASSERT (peerinfo);
@@ -79,14 +80,16 @@  glusterd_friend_find_by_hostname (const char *hoststr,
         GF_ASSERT (priv);
 
         list_for_each_entry (entry, &priv->peers, uuid_list) {
-                if (entry->hostname && (!strncmp (entry->hostname, hoststr,
-                                        sizeof (entry->hostname)))) {
+                list_for_each_entry (name, &entry->hostnames, hostname_list) {
+                        if (!strncmp (name->hostname, hoststr,
+                                        1024)) {
 
                         gf_log ("glusterd", GF_LOG_NORMAL,
                                  "Friend %s found.. state: %d", hoststr,
                                   entry->state.state);
                         *peerinfo = entry;
                         return 0;
+                        }
                 }
         }
 
@@ -130,7 +133,6 @@  glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t  uuid, char *hostname)
         glusterd_friend_sm_event_t      *event = NULL;
         glusterd_friend_req_ctx_t       *ctx = NULL;
 
-
         ret = glusterd_friend_find (uuid, hostname, &peerinfo);
 
         if (ret) {
@@ -279,6 +281,41 @@  out:
         return ret;
 }
 
+static int
+glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
+                                    dict_t  *volumes, int   count)
+{
+
+        int             ret = -1;
+        char            key[256] = {0, };
+
+        GF_ASSERT (volinfo);
+        GF_ASSERT (volumes);
+
+        snprintf (key, 256, "volume%d.name", count);
+        ret = dict_set_str (volumes, key, volinfo->volname);
+        if (ret)
+                goto out;
+
+        snprintf (key, 256, "volume%d.type", count);
+        ret = dict_set_int32 (volumes, key, volinfo->type);
+        if (ret)
+                goto out;
+
+        snprintf (key, 256, "volume%d.status", count);
+        ret = dict_set_int32 (volumes, key, volinfo->status);
+        if (ret)
+                goto out;
+
+        snprintf (key, 256, "volume%d.brick_count", count);
+        ret = dict_set_int32 (volumes, key, volinfo->brick_count);
+        if (ret)
+                goto out;
+
+out:
+        return ret;
+}
+
 int
 glusterd_friend_find (uuid_t uuid, char *hostname,
                       glusterd_peerinfo_t **peerinfo)
@@ -323,7 +360,7 @@  glusterd_handle_cluster_lock (rpcsvc_request_t *req)
 
         GF_ASSERT (req);
 
-        if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &lock_req)) {
+        if (!gd_xdr_to_mgmt_cluster_lock_req (req->msg[0], &lock_req)) {
                 //failed to decode msg;
                 req->rpc_err = GARBAGE_ARGS;
                 goto out;
@@ -557,6 +594,44 @@  out:
 }
 
 int
+glusterd_handle_cli_get_volume (rpcsvc_request_t *req)
+{
+        int32_t                         ret = -1;
+        gf1_cli_get_vol_req             cli_req = {0,};
+        dict_t                          *dict = NULL;
+
+        GF_ASSERT (req);
+
+        if (!gf_xdr_to_cli_get_vol_req (req->msg[0], &cli_req)) {
+                //failed to decode msg;
+                req->rpc_err = GARBAGE_ARGS;
+                goto out;
+        }
+
+        gf_log ("glusterd", GF_LOG_NORMAL, "Received get vol req");
+
+        if (cli_req.dict.dict_len) {
+                /* Unserialize the dictionary */
+                dict  = dict_new ();
+
+                ret = dict_unserialize (cli_req.dict.dict_val,
+                                        cli_req.dict.dict_len,
+                                        &dict);
+                if (ret < 0) {
+                        gf_log ("glusterd", GF_LOG_ERROR,
+                                "failed to "
+                                "unserialize req-buffer to dictionary");
+                        goto out;
+                }
+        }
+
+        ret = glusterd_get_volumes (req, dict, cli_req.flags);
+
+out:
+        return ret;
+}
+
+int
 glusterd_handle_create_volume (rpcsvc_request_t *req)
 {
         int32_t                         ret = -1;
@@ -595,6 +670,78 @@  out:
 }
 
 int
+glusterd_handle_cli_start_volume (rpcsvc_request_t *req)
+{
+        int32_t                         ret = -1;
+        gf1_cli_start_vol_req           cli_req = {0,};
+        //dict_t                          *dict = NULL;
+        int32_t                         flags = 0;
+
+        GF_ASSERT (req);
+
+        if (!gf_xdr_to_cli_start_vol_req (req->msg[0], &cli_req)) {
+                //failed to decode msg;
+                req->rpc_err = GARBAGE_ARGS;
+                goto out;
+        }
+
+        gf_log ("glusterd", GF_LOG_NORMAL, "Received start vol req"
+                "for volume %s", cli_req.volname);
+
+        ret = glusterd_start_volume (req, cli_req.volname, flags);
+
+out:
+        return ret;
+}
+
+int
+glusterd_handle_cli_stop_volume (rpcsvc_request_t *req)
+{
+        int32_t                         ret = -1;
+        gf1_cli_stop_vol_req           cli_req = {0,};
+        int32_t                         flags = 0;
+
+        GF_ASSERT (req);
+
+        if (!gf_xdr_to_cli_stop_vol_req (req->msg[0], &cli_req)) {
+                //failed to decode msg;
+                req->rpc_err = GARBAGE_ARGS;
+                goto out;
+        }
+
+        gf_log ("glusterd", GF_LOG_NORMAL, "Received stop vol req"
+                "for volume %s", cli_req.volname);
+
+        ret = glusterd_stop_volume (req, cli_req.volname, flags);
+
+out:
+        return ret;
+}
+
+int
+glusterd_handle_cli_delete_volume (rpcsvc_request_t *req)
+{
+        int32_t                         ret = -1;
+        gf1_cli_delete_vol_req          cli_req = {0,};
+        int32_t                         flags = 0;
+
+        GF_ASSERT (req);
+
+        if (!gf_xdr_to_cli_delete_vol_req (req->msg[0], &cli_req)) {
+                //failed to decode msg;
+                req->rpc_err = GARBAGE_ARGS;
+                goto out;
+        }
+
+        gf_log ("glusterd", GF_LOG_NORMAL, "Received delete vol req"
+                "for volume %s", cli_req.volname);
+
+        ret = glusterd_delete_volume (req, cli_req.volname, flags);
+
+out:
+        return ret;
+}
+int
 glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status)
 {
 
@@ -645,7 +792,7 @@  glusterd_handle_cluster_unlock (rpcsvc_request_t *req)
 
         GF_ASSERT (req);
 
-        if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &unlock_req)) {
+        if (!gd_xdr_to_mgmt_cluster_unlock_req (req->msg[0], &unlock_req)) {
                 //failed to decode msg;
                 req->rpc_err = GARBAGE_ARGS;
                 goto out;
@@ -775,6 +922,47 @@  out:
 }
 
 int
+glusterd_handle_friend_update (rpcsvc_request_t *req)
+{
+        int32_t                 ret = -1;
+        gd1_mgmt_friend_update     friend_req = {{0},};
+        char                    str[50] = {0,};
+        glusterd_peerinfo_t     *peerinfo = NULL;
+        glusterd_conf_t         *priv = NULL;
+        xlator_t                *this = NULL;
+        glusterd_peerinfo_t     *tmp = NULL;
+
+        GF_ASSERT (req);
+
+        this = THIS;
+        GF_ASSERT (this);
+        priv = this->private;
+        GF_ASSERT (priv);
+
+        if (!gd_xdr_to_mgmt_friend_update (req->msg[0], &friend_req)) {
+                //failed to decode msg;
+                req->rpc_err = GARBAGE_ARGS;
+                goto out;
+        }
+        uuid_unparse (friend_req.uuid, str);
+
+        gf_log ("glusterd", GF_LOG_NORMAL,
+                "Received friend update from uuid: %s", str);
+
+        ret = glusterd_friend_find (friend_req.uuid, friend_req.hostname, &tmp);
+
+        if (!ret)
+                goto out;
+
+        ret = glusterd_friend_add (friend_req.hostname,
+                                   GD_FRIEND_STATE_BEFRIENDED,
+                                   &friend_req.uuid, NULL, &peerinfo);
+
+out:
+        return ret;
+}
+
+int
 glusterd_handle_probe_query (rpcsvc_request_t *req)
 {
         int32_t             ret = -1;
@@ -784,6 +972,7 @@  glusterd_handle_probe_query (rpcsvc_request_t *req)
         gd1_mgmt_probe_req  probe_req = {{0},};
         gd1_mgmt_probe_rsp  rsp = {{0},};
         char                hostname[1024] = {0};
+        glusterd_peer_hostname_t        *name = NULL;
 
         GF_ASSERT (req);
 
@@ -796,18 +985,25 @@  glusterd_handle_probe_query (rpcsvc_request_t *req)
         }
 
 
+        this = THIS;
+
+        conf = this->private;
         uuid_unparse (probe_req.uuid, str);
 
         gf_log ("glusterd", GF_LOG_NORMAL,
                 "Received probe from uuid: %s", str);
 
+        ret = glusterd_peer_hostname_new (probe_req.hostname, &name);
 
-        this = THIS;
+        if (ret) {
+                gf_log ("", GF_LOG_ERROR, "Unable to get new peer_hostname");
+        } else {
+                list_add_tail (&name->hostname_list, &conf->hostnames);
+        }
 
-        conf = this->private;
 
         uuid_copy (rsp.uuid, conf->uuid);
-        rsp.hostname = gf_strdup (probe_req.hostname);
+        rsp.hostname = probe_req.hostname;
 
         ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
                                      gd_xdr_serialize_mgmt_probe_rsp);
@@ -1159,6 +1355,7 @@  glusterd_friend_add (const char *hoststr,
         char                    *port_str = NULL;
         int                     port_num = 0;
         struct rpc_clnt_config  rpc_cfg = {0,};
+        glusterd_peer_hostname_t *name = NULL;
 
         priv = THIS->private;
 
@@ -1170,9 +1367,13 @@  glusterd_friend_add (const char *hoststr,
         if (friend)
                 *friend = peerinfo;
 
+        INIT_LIST_HEAD (&peerinfo->hostnames);
         peerinfo->state.state = state;
         if (hoststr) {
-                peerinfo->hostname = gf_strdup (hoststr);
+                ret =  glusterd_peer_hostname_new ((char *)hoststr, &name);
+                if (ret)
+                        goto out;
+                list_add_tail (&peerinfo->hostnames, &name->hostname_list);
                 rpc_cfg.remote_host = gf_strdup (hoststr);
         }
         INIT_LIST_HEAD (&peerinfo->uuid_list);
@@ -1195,12 +1396,14 @@  glusterd_friend_add (const char *hoststr,
 
 
                 port_str = getenv ("GLUSTERD_REMOTE_PORT");
-                port_num = atoi (port_str);
-                rpc_cfg.remote_port = port_num;
+                if (port_str)
+                        port_num = atoi (port_str);
+                else
+                        port_num = GLUSTERD_DEFAULT_PORT;
 
+                rpc_cfg.remote_port = port_num;
                 gf_log ("glusterd", GF_LOG_NORMAL, "remote-port: %d", port_num);
 
-                //ret = dict_set_int32 (options, "remote-port", GLUSTERD_DEFAULT_PORT);
                 ret = dict_set_int32 (options, "remote-port", port_num);
                 if (ret)
                         goto out;
@@ -1232,26 +1435,7 @@  out:
 
 }
 
-/*int
-glusterd_friend_probe (const char *hoststr)
-{
-        int                     ret = -1;
-        glusterd_peerinfo_t     *peerinfo = NULL;
-
-
-        ret = glusterd_friend_find (NULL, (char *)hoststr, &peerinfo);
-
-        if (ret) {
-                //We should not reach this state ideally
-                GF_ASSERT (0);
-                goto out;
-        }
-
-        ret = glusterd_xfer_probe_msg (peerinfo, THIS);
 
-out:
-        return ret;
-}*/
 
 int
 glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr)
@@ -1361,68 +1545,6 @@  out:
         return ret;
 }
 
-/*int
-glusterd_interpret (xlator_t *this, transport_t *trans,
-                    char *hdr_p, size_t hdrlen, struct iobuf *iobuf)
-{
-        glusterd_connection_t       *conn = NULL;
-        gf_hdr_common_t             *hdr = NULL;
-        xlator_t                    *bound_xl = NULL;
-        call_frame_t                *frame = NULL;
-        peer_info_t                 *peerinfo = NULL;
-        int32_t                      type = -1;
-        int32_t                      op = -1;
-        int32_t                      ret = 0;
-
-        hdr  = (gf_hdr_common_t *)hdr_p;
-        type = ntoh32 (hdr->type);
-        op   = ntoh32 (hdr->op);
-
-        conn = trans->xl_private;
-        if (conn)
-                bound_xl = conn->bound_xl;
-
-        if (GF_MOP_PROBE_QUERY != op) {
-                //ret = glusterd_validate_sender (hdr, hdrlen);
-        }
-
-        peerinfo = &trans->peerinfo;
-        switch (type) {
-
-        case GF_OP_TYPE_MOP_REQUEST:
-                if ((op < 0) || (op >= GF_MOP_MAXVALUE)) {
-                        gf_log (this->name, GF_LOG_ERROR,
-                                "invalid mop %"PRId32" from  %s",
-                                op, peerinfo->identifier);
-                        break;
-                }
-                frame = glusterd_get_frame_for_call (trans, hdr);
-		frame->op = op;
-                ret = glusterd_ops[op] (frame, hdr, hdrlen);
-                break;
-
-        case GF_OP_TYPE_MOP_REPLY:
-                if ((op < 0) || (op >= GF_MOP_MAXVALUE)) {
-                        gf_log (this->name, GF_LOG_ERROR,
-                                "invalid mop %"PRId32" from  %s",
-                                op, peerinfo->identifier);
-                        break;
-                }
-                ret = glusterd_resp_ops[op] (frame, hdr, hdrlen);
-                gf_log ("glusterd", GF_LOG_NORMAL, "Obtained MOP response");
-                break;
-
-
-        default:
-                gf_log (this->name, GF_LOG_ERROR,
-                        "Unknown type: %d", type);
-                ret = -1;
-                break;
-        }
-
-        return ret;
-}
-*/
 
 int
 glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname)
@@ -1547,9 +1669,7 @@  glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict)
         char        *volname   = NULL;
         char        *bricks    = NULL;
         int          type      = 0;
-        //int          sub_count = 2;
         int          count     = 0;
-        //char         cmd_str[8192] = {0,};
 
         GF_ASSERT (req);
         GF_ASSERT (dict);
@@ -1574,38 +1694,83 @@  glusterd_create_volume (rpcsvc_request_t *req, dict_t *dict)
         if (ret)
                 goto out;
 
-        /*switch (type) {
-                case GF_CLUSTER_TYPE_REPLICATE:
-                {
-                        ret = dict_get_int32 (dict, "replica-count", &sub_count);
-                        if (ret)
-                                goto out;
-                        snprintf (cmd_str, 8192,
-                                  "glusterfs-volgen -n %s -c /etc/glusterd -r 1 %s",
-                                  volname, bricks);
-                        ret = system (cmd_str);
-                        break;
-                }
-                case GF_CLUSTER_TYPE_STRIPE:
-                {
-                        ret = dict_get_int32 (dict, "stripe-count", &sub_count);
-                        if (ret)
-                                goto out;
-                        snprintf (cmd_str, 8192,
-                                  "glusterfs-volgen -n %s -c /etc/glusterd -r 0 %s",
-                                  volname, bricks);
-                        ret = system (cmd_str);
-                        break;
-                }
-                case GF_CLUSTER_TYPE_NONE:
-                {
-                        snprintf (cmd_str, 8192,
-                                  "glusterfs-volgen -n %s -c /etc/glusterd %s",
-                                  volname, bricks);
-                        ret = system (cmd_str);
-                        break;
-                }
-        } */
+        ret = glusterd_op_txn_begin ();
+
+out:
+        return ret;
+}
+
+int32_t
+glusterd_start_volume (rpcsvc_request_t *req, char *volname, int flags)
+{
+        int32_t      ret       = -1;
+        glusterd_op_start_volume_ctx_t  *ctx = NULL;
+
+        GF_ASSERT (req);
+        GF_ASSERT (volname);
+
+        ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_start_volume_ctx_t);
+
+        if (!ctx)
+                goto out;
+
+        strncpy (ctx->volume_name, volname, GD_VOLUME_NAME_MAX);
+
+        glusterd_op_set_op (GD_OP_START_VOLUME);
+
+        glusterd_op_set_ctx (GD_OP_START_VOLUME, ctx);
+
+        ret = glusterd_op_txn_begin ();
+
+out:
+        return ret;
+}
+
+int32_t
+glusterd_stop_volume (rpcsvc_request_t *req, char *volname, int flags)
+{
+        int32_t      ret       = -1;
+        glusterd_op_stop_volume_ctx_t  *ctx = NULL;
+
+        GF_ASSERT (req);
+        GF_ASSERT (volname);
+
+        ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_stop_volume_ctx_t);
+
+        if (!ctx)
+                goto out;
+
+        strncpy (ctx->volume_name, volname, GD_VOLUME_NAME_MAX);
+
+        glusterd_op_set_op (GD_OP_STOP_VOLUME);
+
+        glusterd_op_set_ctx (GD_OP_STOP_VOLUME, ctx);
+
+        ret = glusterd_op_txn_begin ();
+
+out:
+        return ret;
+}
+
+int32_t
+glusterd_delete_volume (rpcsvc_request_t *req, char *volname, int flags)
+{
+        int32_t      ret       = -1;
+        glusterd_op_delete_volume_ctx_t  *ctx = NULL;
+
+        GF_ASSERT (req);
+        GF_ASSERT (volname);
+
+        ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_delete_volume_ctx_t);
+
+        if (!ctx)
+                goto out;
+
+        strncpy (ctx->volume_name, volname, GD_VOLUME_NAME_MAX);
+
+        glusterd_op_set_op (GD_OP_DELETE_VOLUME);
+
+        glusterd_op_set_ctx (GD_OP_DELETE_VOLUME, ctx);
 
         ret = glusterd_op_txn_begin ();
 
@@ -1676,6 +1841,68 @@  out:
         return ret;
 }
 
+int32_t
+glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags)
+{
+        int32_t                 ret = -1;
+        glusterd_conf_t         *priv = NULL;
+        glusterd_volinfo_t      *entry = NULL;
+        int32_t                 count = 0;
+        dict_t                  *volumes = NULL;
+        gf1_cli_get_vol_rsp     rsp = {0,};
+
+        priv = THIS->private;
+        GF_ASSERT (priv);
+
+        if (!list_empty (&priv->volumes)) {
+                volumes = dict_new ();
+                if (!volumes) {
+                        gf_log ("", GF_LOG_WARNING, "Out of Memory");
+                        goto out;
+                }
+        } else {
+                ret = 0;
+                goto out;
+        }
+
+        if (flags == GF_CLI_GET_VOLUME_ALL) {
+                        list_for_each_entry (entry, &priv->volumes, vol_list) {
+                                count++;
+                                ret = glusterd_add_volume_detail_to_dict (entry,
+                                                                volumes, count);
+                                if (ret)
+                                        goto out;
+
+                        }
+
+                        ret = dict_set_int32 (volumes, "count", count);
+
+                        if (ret)
+                                goto out;
+        }
+
+        ret = dict_allocate_and_serialize (volumes, &rsp.volumes.volumes_val,
+                                           (size_t *)&rsp.volumes.volumes_len);
+
+        if (ret)
+                goto out;
+
+        ret = 0;
+out:
+
+        if (ret) {
+                if (volumes)
+                        dict_destroy (volumes);
+        }
+
+        rsp.op_ret = ret;
+
+        ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+                                     gf_xdr_serialize_cli_peer_list_rsp);
+
+        return ret;
+}
+
 int
 glusterd_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
                      void *data)
diff --git a/xlators/mgmt/glusterd/src/glusterd-mem-types.h b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
index 7ede5ef..4d3655b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h
+++ b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
@@ -37,6 +37,7 @@  enum gf_gld_mem_types_ {
         gf_gld_mt_peerinfo_t,
         gf_gld_mt_friend_sm_event_t,
         gf_gld_mt_friend_req_ctx_t,
+        gf_gld_mt_friend_update_ctx_t,
         gf_gld_mt_op_sm_event_t,
         gf_gld_mt_op_lock_ctx_t,
         gf_gld_mt_op_stage_ctx_t,
@@ -44,8 +45,12 @@  enum gf_gld_mem_types_ {
         gf_gld_mt_mop_stage_req_t,
         gf_gld_mt_probe_ctx_t,
         gf_gld_mt_create_volume_ctx_t,
+        gf_gld_mt_start_volume_ctx_t,
+        gf_gld_mt_stop_volume_ctx_t,
+        gf_gld_mt_delete_volume_ctx_t,
         gf_gld_mt_glusterd_volinfo_t,
         gf_gld_mt_glusterd_brickinfo_t,
+        gf_gld_mt_peer_hostname_t,
         gf_gld_mt_end
 };
 #endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 0d99174..1bd246d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -49,6 +49,21 @@ 
 static struct list_head gd_op_sm_queue;
 glusterd_op_info_t    opinfo;
 
+static void
+glusterd_set_volume_status (glusterd_volinfo_t  *volinfo,
+                            glusterd_volume_status status)
+{
+        GF_ASSERT (volinfo);
+        volinfo->status = status;
+}
+
+static int
+glusterd_is_volume_started (glusterd_volinfo_t  *volinfo)
+{
+        GF_ASSERT (volinfo);
+        return (!(volinfo->status == GLUSTERD_STATUS_STARTED));
+}
+
 static int
 glusterd_op_get_len (glusterd_op_t op)
 {
@@ -131,7 +146,43 @@  glusterd_op_build_payload (glusterd_op_t op, gd1_mgmt_stage_op_req **req)
                                         goto out;
                                 }
                         }
+                        break;
+
+                case GD_OP_START_VOLUME:
+                        {
+                                glusterd_op_start_volume_ctx_t *ctx = NULL;
+                                ctx = glusterd_op_get_ctx (op);
+                                GF_ASSERT (ctx);
+                                stage_req->buf.buf_len  =
+                                        strlen (ctx->volume_name);
+                                stage_req->buf.buf_val =
+                                        gf_strdup (ctx->volume_name);
+                        }
+                        break;
+
+                case GD_OP_STOP_VOLUME:
+                        {
+                                glusterd_op_stop_volume_ctx_t *ctx = NULL;
+                                ctx = glusterd_op_get_ctx (op);
+                                GF_ASSERT (ctx);
+                                stage_req->buf.buf_len  =
+                                        strlen (ctx->volume_name);
+                                stage_req->buf.buf_val =
+                                        gf_strdup (ctx->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);
+                                stage_req->buf.buf_len  =
+                                        strlen (ctx->volume_name);
+                                stage_req->buf.buf_val =
+                                        gf_strdup (ctx->volume_name);
+                        }
+                        break;
 
                 default:
                         break;
@@ -144,6 +195,75 @@  out:
         return ret;
 }
 
+static int
+glusterd_volume_create_generate_volfiles (glusterd_volinfo_t *volinfo,
+                                          dict_t *dict, char *bricks)
+{
+        int32_t         sub_count = 0;
+        int32_t         ret = -1;
+        char            cmd_str[8192] = {0,};
+        char            path[PATH_MAX] = {0,};
+        glusterd_conf_t *priv = NULL;
+        xlator_t        *this = NULL;
+
+        this = THIS;
+        GF_ASSERT (this);
+        priv = this->private;
+
+        GF_ASSERT (priv);
+        GF_ASSERT (volinfo);
+        GF_ASSERT (dict);
+        GF_ASSERT (bricks);
+
+        GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv);
+
+        switch (volinfo->type) {
+
+                case GF_CLUSTER_TYPE_REPLICATE:
+                {
+                        ret = dict_get_int32 (dict, "replica-count",
+                                              &sub_count);
+                        if (ret)
+                                goto out;
+                        snprintf (cmd_str, 8192,
+                                  "glusterfs-volgen -n %s -c %s -r 1 %s",
+                                   volinfo->volname, path, bricks);
+                        ret = system (cmd_str);
+                        break;
+                }
+
+                case GF_CLUSTER_TYPE_STRIPE:
+                {
+                        ret = dict_get_int32 (dict, "stripe-count",
+                                              &sub_count);
+                        if (ret)
+                                goto out;
+                        snprintf (cmd_str, 8192,
+                                  "glusterfs-volgen -n %s -c %s -r 0 %s",
+                                  volinfo->volname, path, bricks);
+                        ret = system (cmd_str);
+                        break;
+                }
+
+                case GF_CLUSTER_TYPE_NONE:
+                {
+                        snprintf (cmd_str, 8192,
+                                  "glusterfs-volgen -n %s -c %s %s",
+                                  volinfo->volname, path, bricks);
+                        ret = system (cmd_str);
+                        break;
+                }
+
+                default:
+                        gf_log ("", GF_LOG_ERROR, "Unkown type: %d",
+                                volinfo->type);
+                        ret = -1;
+        }
+out:
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+        return ret;
+}
+
 
 
 static int
@@ -191,6 +311,138 @@  out:
 }
 
 static int
+glusterd_op_stage_start_volume (gd1_mgmt_stage_op_req *req)
+{
+        int                                     ret = 0;
+        char                                    volname [1024] = {0,};
+        gf_boolean_t                            exists = _gf_false;
+        glusterd_volinfo_t                      *volinfo = NULL;
+        glusterd_brickinfo_t                    *brickinfo = NULL;
+
+        GF_ASSERT (req);
+
+        strncpy (volname, req->buf.buf_val, req->buf.buf_len);
+        //volname = req->buf.buf_val;
+
+        exists = glusterd_check_volume_exists (volname);
+
+        if (!exists) {
+                gf_log ("", GF_LOG_ERROR, "Volume with name %s does not exist",
+                        volname);
+                ret = -1;
+        } else {
+                ret = 0;
+        }
+
+        ret  = glusterd_volinfo_find (volname, &volinfo);
+
+        if (ret)
+                goto out;
+
+        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+                ret = glusterd_resolve_brick (brickinfo);
+                if (ret) {
+                        gf_log ("", GF_LOG_ERROR, "Unable to resolve brick"
+                                " with hostname: %s, export: %s",
+                                brickinfo->hostname,brickinfo->path);
+                        goto out;
+                }
+        }
+
+out:
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+        return ret;
+}
+
+static int
+glusterd_op_stage_stop_volume (gd1_mgmt_stage_op_req *req)
+{
+        int                                     ret = 0;
+        char                                    volname[1024] = {0,};
+        gf_boolean_t                            exists = _gf_false;
+        glusterd_volinfo_t                      *volinfo = NULL;
+
+        GF_ASSERT (req);
+
+        strncpy (volname, req->buf.buf_val, req->buf.buf_len);
+
+        exists = glusterd_check_volume_exists (volname);
+
+        if (!exists) {
+                gf_log ("", GF_LOG_ERROR, "Volume with name %s does not exist",
+                        volname);
+                ret = -1;
+        } else {
+                ret = 0;
+        }
+
+        ret  = glusterd_volinfo_find (volname, &volinfo);
+
+        if (ret)
+                goto out;
+
+        ret = glusterd_is_volume_started (volinfo);
+
+        if (ret) {
+                gf_log ("", GF_LOG_ERROR, "Volume %s has not been started",
+                        volname);
+                goto out;
+        }
+
+
+out:
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+        return ret;
+}
+
+static int
+glusterd_op_stage_delete_volume (gd1_mgmt_stage_op_req *req)
+{
+        int                                     ret = 0;
+        char                                    volname [1024] = {0,};
+        gf_boolean_t                            exists = _gf_false;
+        glusterd_volinfo_t                      *volinfo = NULL;
+
+        GF_ASSERT (req);
+
+        strncpy (volname, req->buf.buf_val, req->buf.buf_len);
+
+        exists = glusterd_check_volume_exists (volname);
+
+        if (!exists) {
+                gf_log ("", GF_LOG_ERROR, "Volume with name %s does not exist",
+                        volname);
+                ret = -1;
+        } else {
+                ret = 0;
+        }
+
+        ret  = glusterd_volinfo_find (volname, &volinfo);
+
+        if (ret)
+                goto out;
+
+        ret = glusterd_is_volume_started (volinfo);
+
+        if (!ret) {
+                gf_log ("", GF_LOG_ERROR, "Volume %s has been started."
+                        "Volume needs to be stopped before deletion.",
+                        volname);
+                goto out;
+        }
+
+        ret = 0;
+
+out:
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+        return ret;
+}
+
+
+static int
 glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
 {
         int                                     ret = 0;
@@ -203,10 +455,6 @@  glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
         char                                    *brick = NULL;
         int32_t                                 count = 0;
         int32_t                                 i = 1;
-        //char                                    key[50] = {0,};
-        int32_t                                 sub_count = 0;
-        char                                    path[PATH_MAX] = {0,};
-        char                                    cmd_str[8192] = {0,};
         char                                    *bricks    = NULL;
         char                                    *brick_list = NULL;
         char                                    *saveptr = NULL;
@@ -245,18 +493,15 @@  glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
         }
 
         strncpy (volinfo->volname, volname, 1024);
-
         GF_ASSERT (volinfo->volname);
 
         ret = dict_get_int32 (dict, "type", &volinfo->type);
-
         if (ret) {
                 gf_log ("", GF_LOG_ERROR, "Unable to get type");
                 goto out;
         }
 
         ret = dict_get_int32 (dict, "count", &volinfo->brick_count);
-
         if (ret) {
                 gf_log ("", GF_LOG_ERROR, "Unable to get count");
                 goto out;
@@ -265,7 +510,6 @@  glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
         count = volinfo->brick_count;
 
         ret = dict_get_str (dict, "bricks", &bricks);
-
         if (ret) {
                 gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
                 goto out;
@@ -278,7 +522,6 @@  glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
                 brick = strtok_r (brick_list+1, " \n", &saveptr);
 
         while ( i <= count) {
-
                 ret = glusterd_brickinfo_from_brick (brick, &brickinfo);
                 if (ret)
                         goto out;
@@ -287,58 +530,146 @@  glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)
                 brick = strtok_r (NULL, " \n", &saveptr);
                 i++;
         }
+        list_add_tail (&volinfo->vol_list, &priv->volumes);
 
         ret = glusterd_ha_create_volume (volinfo);
 
         if (ret)
                 goto out;
 
+        ret = glusterd_volume_create_generate_volfiles
+                                        (volinfo, dict, bricks);
+        if (ret)
+                goto out;
 
-        GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv);
 
-        switch (volinfo->type) {
+out:
+        return ret;
+}
 
-                case GF_CLUSTER_TYPE_REPLICATE:
-                {
-                        ret = dict_get_int32 (dict, "replica-count",
-                                              &sub_count);
-                        if (ret)
-                                goto out;
-                        snprintf (cmd_str, 8192,
-                                  "glusterfs-volgen -n %s -c %s -r 1 %s",
-                                   volname, path, bricks);
-                        ret = system (cmd_str);
-                        break;
-                }
+static int
+glusterd_op_delete_volume (gd1_mgmt_stage_op_req *req)
+{
+        int                                     ret = 0;
+        char                                    volname[1024] = {0,};
+        glusterd_conf_t                         *priv = NULL;
+        glusterd_volinfo_t                      *volinfo = NULL;
+        xlator_t                                *this = NULL;
 
-                case GF_CLUSTER_TYPE_STRIPE:
-                {
-                        ret = dict_get_int32 (dict, "stripe-count",
-                                              &sub_count);
-                        if (ret)
+        GF_ASSERT (req);
+
+        this = THIS;
+        GF_ASSERT (this);
+        priv = this->private;
+        GF_ASSERT (priv);
+
+        strncpy (volname, req->buf.buf_val, req->buf.buf_len);
+
+        ret  = glusterd_volinfo_find (volname, &volinfo);
+
+        if (ret)
+                goto out;
+
+        ret = glusterd_ha_delete_volume (volinfo);
+
+        if (ret)
+                goto out;
+
+        ret = glusterd_volinfo_delete (volinfo);
+
+        if (ret)
+                goto out;
+
+out:
+        return ret;
+}
+
+static int
+glusterd_op_start_volume (gd1_mgmt_stage_op_req *req)
+{
+        int                                     ret = 0;
+        char                                    volname[1024] = {0,};
+        glusterd_conf_t                         *priv = NULL;
+        glusterd_volinfo_t                      *volinfo = NULL;
+        glusterd_brickinfo_t                    *brickinfo = NULL;
+        xlator_t                                *this = NULL;
+
+        GF_ASSERT (req);
+
+        this = THIS;
+        GF_ASSERT (this);
+        priv = this->private;
+        GF_ASSERT (priv);
+
+        strncpy (volname, req->buf.buf_val, req->buf.buf_len);
+
+        ret  = glusterd_volinfo_find (volname, &volinfo);
+
+        if (ret)
+                goto out;
+
+        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+                if (!uuid_compare (brickinfo->uuid, priv->uuid)) {
+                        gf_log ("", GF_LOG_NORMAL, "About to start glusterfs"
+                                " for brick %s:%s", brickinfo->hostname,
+                                brickinfo->path);
+                        ret = glusterd_volume_start_glusterfs
+                                                (volinfo, brickinfo);
+                        if (ret) {
+                                gf_log ("", GF_LOG_ERROR, "Unable to start "
+                                        "glusterfs, ret: %d", ret);
                                 goto out;
-                        snprintf (cmd_str, 8192,
-                                  "glusterfs-volgen -n %s -c %s -r 0 %s",
-                                  volname, path, bricks);
-                        ret = system (cmd_str);
-                        break;
+                        }
                 }
+        }
 
-                case GF_CLUSTER_TYPE_NONE:
-                {
-                        snprintf (cmd_str, 8192,
-                                  "glusterfs-volgen -n %s -c %s %s",
-                                  volname, path, bricks);
-                        ret = system (cmd_str);
-                        break;
-                }
+        glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STARTED);
 
-                default:
-                        gf_log ("", GF_LOG_ERROR, "Unkown type: %d",
-                                volinfo->type);
-                        ret = -1;
+out:
+        return ret;
+}
+
+static int
+glusterd_op_stop_volume (gd1_mgmt_stage_op_req *req)
+{
+        int                                     ret = 0;
+        char                                    volname[1024] = {0,};
+        glusterd_conf_t                         *priv = NULL;
+        glusterd_volinfo_t                      *volinfo = NULL;
+        glusterd_brickinfo_t                    *brickinfo = NULL;
+        xlator_t                                *this = NULL;
+
+        GF_ASSERT (req);
+
+        this = THIS;
+        GF_ASSERT (this);
+        priv = this->private;
+        GF_ASSERT (priv);
+
+        strncpy (volname, req->buf.buf_val, req->buf.buf_len);
+
+        ret  = glusterd_volinfo_find (volname, &volinfo);
+
+        if (ret)
+                goto out;
+
+        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+                if (!uuid_compare (brickinfo->uuid, priv->uuid)) {
+                        gf_log ("", GF_LOG_NORMAL, "About to stop glusterfs"
+                                " for brick %s:%s", brickinfo->hostname,
+                                brickinfo->path);
+                        ret = glusterd_volume_stop_glusterfs
+                                                (volinfo, brickinfo);
+                        if (ret) {
+                                gf_log ("", GF_LOG_ERROR, "Unable to stop "
+                                        "glusterfs, ret: %d", ret);
+                                goto out;
+                        }
+                }
         }
 
+        glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED);
+
 out:
         return ret;
 }
@@ -720,6 +1051,18 @@  glusterd_op_stage_validate (gd1_mgmt_stage_op_req *req)
                         ret = glusterd_op_stage_create_volume (req);
                         break;
 
+                case GD_OP_START_VOLUME:
+                        ret = glusterd_op_stage_start_volume (req);
+                        break;
+
+                case GD_OP_STOP_VOLUME:
+                        ret = glusterd_op_stage_stop_volume (req);
+                        break;
+
+                case GD_OP_DELETE_VOLUME:
+                        ret = glusterd_op_stage_delete_volume (req);
+                        break;
+
                 default:
                         gf_log ("", GF_LOG_ERROR, "Unknown op %d",
                                 req->op);
@@ -743,6 +1086,18 @@  glusterd_op_commit_perform (gd1_mgmt_stage_op_req *req)
                         ret = glusterd_op_create_volume (req);
                         break;
 
+                case GD_OP_START_VOLUME:
+                        ret = glusterd_op_start_volume (req);
+                        break;
+
+                case GD_OP_STOP_VOLUME:
+                        ret = glusterd_op_stop_volume (req);
+                        break;
+
+                case GD_OP_DELETE_VOLUME:
+                        ret = glusterd_op_delete_volume (req);
+                        break;
+
                 default:
                         gf_log ("", GF_LOG_ERROR, "Unknown op %d",
                                 req->op);
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
index 3bfbcb9..500d0eb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
@@ -116,11 +116,13 @@  struct glusterd_op_info_ {
 
 typedef struct glusterd_op_info_ glusterd_op_info_t;
 
-struct glusterd_op_create_volume_ctx_ {
+struct glusterd_op_start_volume_ctx_ {
         char                    volume_name[GD_VOLUME_NAME_MAX];
 };
 
-typedef struct glusterd_op_create_volume_ctx_ glusterd_op_create_volume_ctx_t;
+typedef struct glusterd_op_start_volume_ctx_ glusterd_op_start_volume_ctx_t;
+typedef struct glusterd_op_start_volume_ctx_ glusterd_op_stop_volume_ctx_t;
+typedef struct glusterd_op_start_volume_ctx_ glusterd_op_delete_volume_ctx_t;
 
 
 struct glusterd_op_lock_ctx_ {
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index c024126..a5f760f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -29,7 +29,6 @@ 
 #include <libgen.h>
 #include "uuid.h"
 
-//#include "transport.h"
 #include "fnmatch.h"
 #include "xlator.h"
 #include "protocol-common.h"
@@ -96,13 +95,6 @@  glusterd_ac_friend_add (glusterd_friend_sm_event_t *event, void *ctx)
                 ret = proc->fn (frame, this, event);
         }
 
-/*        ret = glusterd_xfer_friend_req_msg (peerinfo, THIS);
-
-        if (ret) {
-                gf_log ("", GF_LOG_ERROR, "Unable to probe: %s", hostname);
-        }
-*/
-
 out:
         gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
 
@@ -147,13 +139,6 @@  glusterd_ac_friend_probe (glusterd_friend_sm_event_t *event, void *ctx)
         }
 
 
-/*        ret = glusterd_friend_probe (hostname);
-
-        if (ret) {
-                gf_log ("", GF_LOG_ERROR, "Unable to probe: %s", hostname);
-        }
-*/
-
 out:
         gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
 
@@ -190,12 +175,41 @@  glusterd_ac_send_friend_remove_req (glusterd_friend_sm_event_t *event, void *ctx
                 ret = proc->fn (frame, this, event);
         }
 
-/*        ret = glusterd_xfer_friend_req_msg (peerinfo, THIS);
+out:
+        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
 
-        if (ret) {
-                gf_log ("", GF_LOG_ERROR, "Unable to probe: %s", hostname);
+        return ret;
+}
+
+static int
+glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
+{
+        int                     ret = 0;
+        glusterd_peerinfo_t     *peerinfo = NULL;
+        rpc_clnt_procedure_t    *proc = NULL;
+        call_frame_t            *frame = NULL;
+        glusterd_conf_t         *conf = NULL;
+        xlator_t                *this = NULL;
+
+
+        GF_ASSERT (event);
+        peerinfo = event->peerinfo;
+
+        this = THIS;
+        conf = this->private;
+
+        GF_ASSERT (conf);
+        GF_ASSERT (conf->mgmt);
+
+        proc = &conf->mgmt->proctable[GD_MGMT_FRIEND_UPDATE];
+        if (proc->fn) {
+                frame = create_frame (this, this->ctx->pool);
+                if (!frame) {
+                        goto out;
+                }
+                frame->local = ctx;
+                ret = proc->fn (frame, this, event);
         }
-*/
 
 out:
         gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
@@ -203,6 +217,7 @@  out:
         return ret;
 }
 
+
 static int
 glusterd_ac_handle_friend_remove_req (glusterd_friend_sm_event_t *event,
                                       void *ctx)
@@ -260,6 +275,7 @@  glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
         uuid_t                          uuid;
         glusterd_peerinfo_t             *peerinfo = NULL;
         glusterd_friend_req_ctx_t       *ev_ctx = NULL;
+        glusterd_friend_update_ctx_t    *new_ev_ctx = NULL;
         glusterd_friend_sm_event_t      *new_event = NULL;
         glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
         int                             status = 0;
@@ -285,10 +301,24 @@  glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx)
         }
 
         new_event->peerinfo = peerinfo;
+
+        new_ev_ctx = GF_CALLOC (1, sizeof (*new_ev_ctx),
+                                gf_gld_mt_friend_update_ctx_t);
+        if (!new_ev_ctx) {
+                ret = -1;
+                goto out;
+        }
+
+        uuid_copy (new_ev_ctx->uuid, ev_ctx->uuid);
+        new_ev_ctx->hostname = gf_strdup (ev_ctx->hostname);
+
+        new_event->ctx = new_ev_ctx;
+
         glusterd_friend_sm_inject_event (new_event);
 
         ret = glusterd_xfer_friend_add_resp (ev_ctx->req, ev_ctx->hostname);
 
+out:
         gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
 
         return ret;
@@ -373,7 +403,7 @@  glusterd_sm_t  glusterd_state_req_sent_rcvd [] = {
         {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_NONE,
         {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_PROBE,
         {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
-        {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_ACC
+        {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_ACC
         {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
         {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT
         {GD_FRIEND_STATE_REQ_SENT_RCVD, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
@@ -401,8 +431,8 @@  glusterd_sm_t  glusterd_state_req_accepted [] = {
         {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_NONE,
         {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_PROBE,
         {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_none}, //EVENT_INIT_FRIEND_REQ,
-        {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_ACC
-        {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_ACC
+        {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_ACC
+        {GD_FRIEND_STATE_BEFRIENDED, glusterd_ac_send_friend_update}, //EVENT_RCVD_LOCAL_ACC
         {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_RJT
         {GD_FRIEND_STATE_REJECTED, glusterd_ac_none}, //EVENT_RCVD_LOCAL_RJT
         {GD_FRIEND_STATE_REQ_ACCEPTED, glusterd_ac_handle_friend_add_req}, //EVENT_RCV_FRIEND_REQ
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h
index 2c31238..ee1b4cc 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.h
@@ -55,6 +55,10 @@  typedef struct glusterd_peer_state_info_ {
         struct timeval          transition_time;
 }glusterd_peer_state_info_t;
 
+typedef struct glusterd_peer_hostname_ {
+        char                    *hostname;
+        struct list_head        hostname_list;
+}glusterd_peer_hostname_t;
 
 struct glusterd_peerinfo_ {
         uuid_t                          uuid;
@@ -64,6 +68,7 @@  struct glusterd_peerinfo_ {
         int                             port;
         struct list_head                uuid_list;
         struct list_head                op_peers_list;
+        struct list_head                hostnames;
         struct rpc_clnt                 *rpc;
 };
 
@@ -108,6 +113,8 @@  typedef struct glusterd_friend_req_ctx_ {
         rpcsvc_request_t        *req;
 } glusterd_friend_req_ctx_t;
 
+typedef glusterd_friend_req_ctx_t glusterd_friend_update_ctx_t;
+
 typedef struct glusterd_probe_ctx_ {
         char                    *hostname;
         rpcsvc_request_t        *req;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index feb4919..ad9c907 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -28,8 +28,6 @@ 
 #include "glusterfs.h"
 #include "compat.h"
 #include "dict.h"
-//#include "protocol.h"
-//#include "transport.h"
 #include "xlator.h"
 #include "logging.h"
 #include "timer.h"
@@ -44,6 +42,8 @@ 
 
 #include <sys/resource.h>
 #include <inttypes.h>
+#include <signal.h>
+#include <sys/types.h>
 
 static glusterd_lock_t lock;
 
@@ -336,15 +336,19 @@  glusterd_check_volume_exists (char *volname)
         char pathname[1024] = {0,};
         struct stat stbuf = {0,};
         int32_t ret = -1;
+        glusterd_conf_t *priv = NULL;
 
-        snprintf (pathname, 1024, "%s/vols/%s", GLUSTERD_DEFAULT_WORKDIR,
+        priv = THIS->private;
+
+        snprintf (pathname, 1024, "%s/vols/%s", priv->workdir,
                   volname);
 
         ret = stat (pathname, &stbuf);
 
         if (ret) {
                 gf_log ("", GF_LOG_DEBUG, "Volume %s does not exist."
-                        "stat failed with errno: %d", volname, errno);
+                        "stat failed with errno : %d on path: %s",
+                        volname, errno, pathname);
                 return _gf_false;
         }
 
@@ -378,6 +382,49 @@  out:
 }
 
 int32_t
+glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo)
+{
+        int32_t         ret = -1;
+
+        GF_ASSERT (brickinfo);
+
+        list_del_init (&brickinfo->brick_list);
+
+        GF_FREE (brickinfo);
+
+        ret = 0;
+
+        return ret;
+}
+
+int32_t
+glusterd_volinfo_delete (glusterd_volinfo_t *volinfo)
+{
+        int32_t                 ret = -1;
+        glusterd_brickinfo_t    *brickinfo = NULL;
+        glusterd_brickinfo_t    *tmp = NULL;
+
+        GF_ASSERT (volinfo);
+
+        list_del_init (&volinfo->vol_list);
+
+        list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,
+                                   brick_list) {
+                ret = glusterd_brickinfo_delete (brickinfo);
+                if (ret)
+                        goto out;
+        }
+
+        GF_FREE (volinfo);
+        ret = 0;
+
+out:
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+        return ret;
+}
+
+
+int32_t
 glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo)
 {
         glusterd_brickinfo_t      *new_brickinfo = NULL;
@@ -403,7 +450,48 @@  out:
 }
 
 int32_t
-glusterd_brickinfo_from_brick (char *brick, glusterd_brickinfo_t **brickinfo)
+glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo)
+{
+        int32_t                 ret = -1;
+        glusterd_peerinfo_t     *peerinfo = NULL;
+        glusterd_conf_t         *priv = NULL;
+        glusterd_peer_hostname_t        *host = NULL;
+
+        priv = THIS->private;
+        GF_ASSERT (priv);
+
+        GF_ASSERT (brickinfo);
+
+        ret = glusterd_friend_find (NULL, brickinfo->hostname, &peerinfo);
+
+        if (!ret) {
+                uuid_copy (brickinfo->uuid, peerinfo->uuid);
+        } else {
+                list_for_each_entry (host, &priv->hostnames, hostname_list) {
+                        if (!strcmp (host->hostname, brickinfo->hostname)) {
+                                uuid_copy (brickinfo->uuid, priv->uuid);
+                                ret = 0;
+                                break;
+                        }
+
+                }
+        }
+
+        if (ret) {
+                if ((!strcmp (brickinfo->hostname, "localhost")) ||
+                     (!strcmp (brickinfo->hostname, "127.0.0.1"))) {
+                        uuid_copy (brickinfo->uuid, priv->uuid);
+                        ret = 0;
+                }
+        }
+
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+        return ret;
+}
+
+int32_t
+glusterd_brickinfo_from_brick (char *brick,
+                               glusterd_brickinfo_t **brickinfo)
 {
         int32_t                 ret = -1;
         glusterd_brickinfo_t    *new_brickinfo = NULL;
@@ -444,7 +532,197 @@  glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo)
                 rpc_clnt_destroy (peerinfo->rpc);
                 peerinfo->rpc = NULL;
         }
-        GF_FREE (peerinfo->hostname);
+        glusterd_peer_destroy (peerinfo);
 
         return 0;
 }
+
+int32_t
+glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo)
+{
+        glusterd_volinfo_t      *tmp_volinfo = NULL;
+        int32_t                 ret = -1;
+        xlator_t                *this = NULL;
+        glusterd_conf_t         *priv = NULL;
+
+        GF_ASSERT (volname);
+
+        this = THIS;
+        GF_ASSERT (this);
+
+        priv = this->private;
+
+        list_for_each_entry (tmp_volinfo, &priv->volumes, vol_list) {
+                if (!strcmp (tmp_volinfo->volname, volname)) {
+                        gf_log ("", GF_LOG_DEBUG, "Volume %s found", volname);
+                        ret = 0;
+                        *volinfo = tmp_volinfo;
+                        break;
+                }
+        }
+
+
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+        return ret;
+}
+
+
+
+int32_t
+glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,
+                                 glusterd_brickinfo_t   *brickinfo)
+{
+        int32_t                 ret = -1;
+        xlator_t                *this = NULL;
+        glusterd_conf_t         *priv = NULL;
+        char                    pidfile[PATH_MAX] = {0,};
+        char                    volfile[PATH_MAX] = {0,};
+        char                    path[PATH_MAX] = {0,};
+        char                    cmd_str[8192] = {0,};
+        char                    rundir[PATH_MAX] = {0,};
+
+        GF_ASSERT (volinfo);
+        GF_ASSERT (brickinfo);
+
+        this = THIS;
+        GF_ASSERT (this);
+
+        priv = this->private;
+
+        GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
+        snprintf (rundir, PATH_MAX, "%s/run", path);
+        ret = mkdir (rundir, 0777);
+
+        if ((ret == -1) && (EEXIST != errno)) {
+                gf_log ("", GF_LOG_ERROR, "Unable to create rundir %s",
+                        rundir);
+                goto out;
+        }
+
+        GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname);
+        snprintf (volfile, PATH_MAX, "%s/%s-%s-export.vol", path,
+                  brickinfo->hostname, volinfo->volname);
+        snprintf (cmd_str, 8192, "glusterfs -f %s -p %s", volfile, pidfile);
+        ret = system (cmd_str);
+
+out:
+        return ret;
+}
+
+int32_t
+glusterd_volume_stop_glusterfs (glusterd_volinfo_t  *volinfo,
+                                glusterd_brickinfo_t   *brickinfo)
+{
+        int32_t                 ret = -1;
+        xlator_t                *this = NULL;
+        glusterd_conf_t         *priv = NULL;
+        char                    pidfile[PATH_MAX] = {0,};
+        char                    path[PATH_MAX] = {0,};
+        pid_t                   pid = -1;
+        FILE                    *file = NULL;
+
+        GF_ASSERT (volinfo);
+        GF_ASSERT (brickinfo);
+
+        this = THIS;
+        GF_ASSERT (this);
+
+        priv = this->private;
+
+        GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
+        GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname);
+
+        file = fopen (pidfile, "r+");
+
+        if (!file) {
+                gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s",
+                                pidfile);
+                ret = -1;
+                goto out;
+        }
+
+        ret = fscanf (file, "%d", &pid);
+        if (ret <= 0) {
+                gf_log ("", GF_LOG_ERROR, "Unable to read pidfile: %s",
+                                pidfile);
+                ret = -1;
+                goto out;
+        }
+        fclose (file);
+        file = NULL;
+
+        gf_log ("", GF_LOG_NORMAL, "Stopping glusterfs running in pid: %d",
+                pid);
+
+        ret = kill (pid, SIGQUIT);
+
+        if (ret) {
+                gf_log ("", GF_LOG_ERROR, "Unable to kill pid %d", pid);
+                goto out;
+        }
+
+        ret = unlink (pidfile);
+
+        if (ret) {
+                gf_log ("", GF_LOG_ERROR, "Unable to unlink pidfile: %s",
+                                pidfile);
+                goto out;
+        }
+
+out:
+        if (file)
+                fclose (file);
+        return ret;
+}
+
+int32_t
+glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name)
+{
+        glusterd_peer_hostname_t        *peer_hostname = NULL;
+        int32_t                         ret = -1;
+
+        GF_ASSERT (hostname);
+        GF_ASSERT (name);
+
+        peer_hostname = GF_CALLOC (1, sizeof (*peer_hostname),
+                                   gf_gld_mt_peer_hostname_t);
+
+        if (!peer_hostname)
+                goto out;
+
+        peer_hostname->hostname = gf_strdup (hostname);
+        INIT_LIST_HEAD (&peer_hostname->hostname_list);
+
+        *name = peer_hostname;
+        ret = 0;
+
+out:
+        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+        return ret;
+}
+
+int32_t
+glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo)
+{
+        int32_t                         ret = -1;
+        glusterd_peer_hostname_t        *name = NULL;
+        glusterd_peer_hostname_t        *tmp = NULL;
+
+        if (!peerinfo)
+                goto out;
+
+        list_del_init (&peerinfo->uuid_list);
+        list_for_each_entry_safe (name, tmp, &peerinfo->hostnames,
+                                  hostname_list) {
+                list_del_init (&name->hostname_list);
+                GF_FREE (name->hostname);
+        }
+
+        list_del_init (&peerinfo->hostnames);
+        GF_FREE (peerinfo);
+
+        ret = 0;
+
+out:
+        return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 03c1b9f..f21971a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -79,4 +79,30 @@  glusterd_brickinfo_from_brick (char *brick, glusterd_brickinfo_t **brickinfo);
 
 int32_t
 glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo);
+
+int32_t
+glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo);
+
+int32_t
+glusterd_peer_hostname_new (char *hostname, glusterd_peer_hostname_t **name);
+
+int32_t
+glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo);
+
+int32_t
+glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo);
+
+int32_t
+glusterd_volume_start_glusterfs (glusterd_volinfo_t  *volinfo,
+                                 glusterd_brickinfo_t   *brickinfo);
+
+int32_t
+glusterd_volume_stop_glusterfs (glusterd_volinfo_t  *volinfo,
+                                glusterd_brickinfo_t   *brickinfo);
+
+int32_t
+glusterd_volinfo_delete (glusterd_volinfo_t *volinfo);
+
+int32_t
+glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo);
 #endif
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index 8b8509d..3be035e 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -170,7 +170,7 @@  init (xlator_t *this)
         struct stat     buf = {0,};
         char            *port_str = NULL;
         int             port_num = 0;
-        char            voldir [PATH_MAX];
+        char            voldir [PATH_MAX] = {0,};
 
 
         dir_data = dict_get (this->options, "working-directory");
@@ -199,7 +199,7 @@  init (xlator_t *this)
 
 
         if ((-1 == ret) && (ENOENT == errno)) {
-                ret = mkdir (dirname, 0644);
+                ret = mkdir (dirname, 0777);
 
                 if (-1 == ret) {
                         gf_log (this->name, GF_LOG_CRITICAL,
@@ -213,9 +213,9 @@  init (xlator_t *this)
 
         snprintf (voldir, PATH_MAX, "%s/vols", dirname);
 
-        ret = mkdir (voldir, 0644);
+        ret = mkdir (voldir, 0777);
 
-        if (-1 == ret) {
+        if ((-1 == ret) && (errno != EEXIST)) {
                 gf_log (this->name, GF_LOG_CRITICAL,
                         "Unable to create volume directory %s"
                         " ,errno = %d", voldir, errno);
@@ -260,6 +260,7 @@  init (xlator_t *this)
         GF_VALIDATE_OR_GOTO(this->name, conf, out);
         INIT_LIST_HEAD (&conf->peers);
         INIT_LIST_HEAD (&conf->volumes);
+        INIT_LIST_HEAD (&conf->hostnames);
         pthread_mutex_init (&conf->mutex, NULL);
         conf->rpc = rpc;
         conf->mgmt = &glusterd3_1_mgmt_prog;
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index d92ec31..a998ce4 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -54,12 +54,14 @@  typedef struct {
         rpcsvc_t          *rpc;
         rpc_clnt_prog_t   *mgmt;
         struct list_head  volumes;
+        struct list_head  hostnames;
 } glusterd_conf_t;
 
 struct glusterd_brickinfo {
         char    hostname[1024];
         char    path[PATH_MAX];
         struct list_head  brick_list;
+        uuid_t  uuid;
 };
 
 typedef struct glusterd_brickinfo glusterd_brickinfo_t;
@@ -70,19 +72,23 @@  struct glusterd_volinfo_ {
         int     brick_count;
         struct list_head        vol_list;
         struct list_head        bricks;
+        glusterd_volume_status  status;
 };
 
 typedef struct glusterd_volinfo_ glusterd_volinfo_t;
 
 
 #define GLUSTERD_DEFAULT_WORKDIR "/etc/glusterd"
-#define GLUSTERD_DEFAULT_PORT   4284
+#define GLUSTERD_DEFAULT_PORT   6969
 
 typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
 
 #define GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv) \
         snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir,\
                   volinfo->volname);
+
+#define GLUSTERD_GET_BRICK_PIDFILE(pidfile, volpath, hostname)\
+        snprintf (pidfile, PATH_MAX, "%s/run/%s.pid", volpath, hostname);
 int
 glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr);
 
@@ -170,4 +176,31 @@  glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags);
 
 int
 glusterd_handle_cli_list_friends (rpcsvc_request_t *req);
+
+int
+glusterd_handle_cli_start_volume (rpcsvc_request_t *req);
+
+int32_t
+glusterd_start_volume (rpcsvc_request_t *req, char *volname, int flags);
+
+int
+glusterd_handle_friend_update (rpcsvc_request_t *req);
+
+int
+glusterd_handle_cli_stop_volume (rpcsvc_request_t *req);
+
+int
+glusterd_stop_volume (rpcsvc_request_t *req, char *volname, int flags);
+
+int32_t
+glusterd_delete_volume (rpcsvc_request_t *req, char *volname, int flags);
+
+int
+glusterd_handle_cli_delete_volume (rpcsvc_request_t *req);
+
+int
+glusterd_handle_cli_get_volume (rpcsvc_request_t *req);
+
+int32_t
+glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags);
 #endif
diff --git a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
index 29e1dd6..3ea0f66 100644
--- a/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
+++ b/xlators/mgmt/glusterd/src/glusterd3_1-mops.c
@@ -59,6 +59,7 @@  glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
         glusterd_peerinfo_t           *peerinfo = NULL;
         glusterd_peerinfo_t           *dup_peerinfo = NULL;
         glusterd_friend_sm_event_t    *event = NULL;
+        glusterd_peer_hostname_t      *name = NULL;
 
         conf  = THIS->private;
 
@@ -85,17 +86,18 @@  glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
                 GF_ASSERT (0);
         }
 
-        if (!peerinfo->hostname) {
+        if (list_empty (&peerinfo->hostnames)) {
                 glusterd_friend_find (NULL, rsp.hostname, &dup_peerinfo);
                 GF_ASSERT (dup_peerinfo);
-                GF_ASSERT (dup_peerinfo->hostname);
                 peerinfo->hostname = gf_strdup (rsp.hostname);
+                glusterd_peer_hostname_new (rsp.hostname, &name);
+                list_add_tail (&name->hostname_list, &peerinfo->hostnames);
                 peerinfo->rpc = dup_peerinfo->rpc;
                 list_del_init (&dup_peerinfo->uuid_list);
-                GF_FREE (dup_peerinfo->hostname);
                 GF_FREE (dup_peerinfo);
         }
-        GF_ASSERT (peerinfo->hostname);
+        if (!peerinfo->hostname)
+                peerinfo->hostname = gf_strdup (rsp.hostname);
         uuid_copy (peerinfo->uuid, rsp.uuid);
 
         ret = glusterd_friend_sm_new_event
@@ -139,6 +141,7 @@  glusterd3_1_friend_add_cbk (struct rpc_req * req, struct iovec *iov,
         int32_t                       op_ret = -1;
         int32_t                       op_errno = -1;
         glusterd_probe_ctx_t          *ctx = NULL;
+        glusterd_friend_update_ctx_t  *ev_ctx = NULL;
 
         conf  = THIS->private;
 
@@ -182,7 +185,17 @@  glusterd3_1_friend_add_cbk (struct rpc_req * req, struct iovec *iov,
                 goto out;
         }
         event->peerinfo = peerinfo;
+        ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx),
+                                gf_gld_mt_friend_update_ctx_t);
+        if (!ev_ctx) {
+                ret = -1;
+                goto out;
+        }
+
+        uuid_copy (ev_ctx->uuid, rsp.uuid);
+        ev_ctx->hostname = gf_strdup (rsp.hostname);
 
+        event->ctx = ev_ctx;
         ret = glusterd_friend_sm_inject_event (event);
 
         if (ret)
@@ -683,6 +696,45 @@  out:
 
 
 int32_t
+glusterd3_1_friend_update (call_frame_t *frame, xlator_t *this,
+                           void *data)
+{
+        gd1_mgmt_friend_update          req = {{0},};
+        int                             ret = 0;
+        glusterd_peerinfo_t             *peerinfo = NULL;
+        glusterd_conf_t                 *priv = NULL;
+        glusterd_friend_sm_event_t      *event = NULL;
+        glusterd_friend_update_ctx_t     *ctx = NULL;
+
+
+        if (!frame || !this || !data) {
+                ret = -1;
+                goto out;
+        }
+
+        event = data;
+        priv = this->private;
+
+        GF_ASSERT (priv);
+
+        ctx = event->ctx;
+
+        peerinfo = event->peerinfo;
+        uuid_copy (req.uuid, priv->uuid);
+        uuid_copy (req.friend_uuid, ctx->uuid);
+        req.hostname = ctx->hostname;
+
+        ret = glusterd_submit_request (peerinfo, &req, frame, priv->mgmt,
+                                       GD_MGMT_FRIEND_UPDATE,
+                                       NULL, gd_xdr_from_mgmt_friend_update,
+                                       this, NULL);
+
+out:
+        gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+        return ret;
+}
+
+int32_t
 glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this,
                            void *data)
 {
@@ -1016,6 +1068,26 @@  glusterd_handle_rpc_msg (rpcsvc_request_t *req)
                         ret = glusterd_handle_cli_list_friends (req);
                         break;
 
+                case GD_MGMT_CLI_START_VOLUME:
+                        ret = glusterd_handle_cli_start_volume (req);
+                        break;
+
+                case GD_MGMT_CLI_STOP_VOLUME:
+                        ret = glusterd_handle_cli_stop_volume (req);
+                        break;
+
+                case GD_MGMT_CLI_DELETE_VOLUME:
+                        ret = glusterd_handle_cli_delete_volume (req);
+                        break;
+
+                case GD_MGMT_FRIEND_UPDATE:
+                        ret = glusterd_handle_friend_update (req);
+                        break;
+
+                case GD_MGMT_CLI_GET_VOLUME:
+                        ret = glusterd_handle_cli_get_volume (req);
+                        break;
+
                 default:
                         GF_ASSERT (0);
         }
@@ -1034,6 +1106,7 @@  rpcsvc_actor_t glusterd1_mgmt_actors[] = {
         [GD_MGMT_PROBE_QUERY] = { "PROBE_QUERY", GD_MGMT_PROBE_QUERY, glusterd_handle_rpc_msg, NULL, NULL},
         [GD_MGMT_FRIEND_ADD] = { "FRIEND_ADD", GD_MGMT_FRIEND_ADD, glusterd_handle_rpc_msg, NULL, NULL},
         [GD_MGMT_FRIEND_REMOVE] = { "FRIEND_REMOVE", GD_MGMT_FRIEND_REMOVE, glusterd_handle_rpc_msg, NULL, NULL},
+        [GD_MGMT_FRIEND_UPDATE] = { "FRIEND_UPDATE", GD_MGMT_FRIEND_UPDATE, glusterd_handle_rpc_msg, NULL, NULL},
         [GD_MGMT_CLUSTER_LOCK] = { "CLUSTER_LOCK", GD_MGMT_CLUSTER_LOCK, glusterd_handle_rpc_msg, NULL, NULL},
         [GD_MGMT_CLUSTER_UNLOCK] = { "CLUSTER_UNLOCK", GD_MGMT_CLUSTER_UNLOCK, glusterd_handle_rpc_msg, NULL, NULL},
         [GD_MGMT_STAGE_OP] = { "STAGE_OP", GD_MGMT_STAGE_OP, glusterd_handle_rpc_msg, NULL, NULL},
@@ -1042,6 +1115,10 @@  rpcsvc_actor_t glusterd1_mgmt_actors[] = {
         [GD_MGMT_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GD_MGMT_CLI_CREATE_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},
         [GD_MGMT_CLI_DEPROBE] = { "FRIEND_REMOVE", GD_MGMT_CLI_DEPROBE, glusterd_handle_rpc_msg, NULL, NULL},
         [GD_MGMT_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GD_MGMT_CLI_LIST_FRIENDS, glusterd_handle_rpc_msg, NULL, NULL},
+        [GD_MGMT_CLI_START_VOLUME] = { "START_VOLUME", GD_MGMT_CLI_START_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},
+        [GD_MGMT_CLI_STOP_VOLUME] = { "STOP_VOLUME", GD_MGMT_CLI_STOP_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},
+        [GD_MGMT_CLI_DELETE_VOLUME] = { "DELETE_VOLUME", GD_MGMT_CLI_DELETE_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},
+        [GD_MGMT_CLI_GET_VOLUME] = { "GET_VOLUME", GD_MGMT_CLI_GET_VOLUME, glusterd_handle_rpc_msg, NULL, NULL},
 };
 
 /*rpcsvc_actor_t glusterd1_mgmt_actors[] = {
@@ -1075,7 +1152,7 @@  struct rpc_clnt_procedure glusterd3_1_clnt_mgmt_actors[GD_MGMT_MAXVALUE] = {
         [GD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd3_1_stage_op},
         [GD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd3_1_commit_op},
         [GD_MGMT_FRIEND_REMOVE]  = { "FRIEND_REMOVE",  glusterd3_1_friend_remove},
-//        [GF_FOP_GETSPEC]     = { "GETSPEC",   client_getspec, client_getspec_cbk },
+        [GD_MGMT_FRIEND_UPDATE]  = { "FRIEND_UPDATE",  glusterd3_1_friend_update},
 };