diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 777 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 15 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 10 | 
3 files changed, 651 insertions, 151 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index b3d27efa0fb..8c7d75c6437 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -46,6 +46,9 @@  #include "glusterd-store.h"  #include "cli1.h" +#include <sys/types.h> +#include <signal.h> +  static struct list_head gd_op_sm_queue;  glusterd_op_info_t    opinfo;  static int glusterfs_port = GLUSTERD_DEFAULT_PORT; @@ -554,10 +557,14 @@ out:  static int  glusterd_op_stage_replace_brick (gd1_mgmt_stage_op_req *req)  { -        int                                     ret = 0; -        dict_t                                  *dict = NULL; -        char                                    *src_brick = NULL; -        char                                    *dst_brick = NULL; +        int                                      ret           = 0; +        dict_t                                  *dict          = NULL; +        char                                    *src_brick     = NULL; +        char                                    *dst_brick     = NULL; +        char                                    *volname       = NULL; +        glusterd_volinfo_t                      *volinfo       = NULL; +        glusterd_brickinfo_t                    *src_brickinfo = NULL; +        gf_boolean_t                             exists        = _gf_false;          GF_ASSERT (req); @@ -571,7 +578,7 @@ glusterd_op_stage_replace_brick (gd1_mgmt_stage_op_req *req)                  gf_log ("", GF_LOG_ERROR, "Unable to unserialize dict");                  goto out;          } -        /* Need to do a little more error checking and validation */ +          ret = dict_get_str (dict, "src-brick", &src_brick);          if (ret) { @@ -590,7 +597,35 @@ glusterd_op_stage_replace_brick (gd1_mgmt_stage_op_req *req)          }          gf_log ("", GF_LOG_DEBUG, -                "dest brick=%s", dst_brick); +                "dst brick=%s", dst_brick); + +        ret = dict_get_str (dict, "volname", &volname); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); +                goto out; +        } + +        ret = glusterd_brickinfo_get (src_brick, volinfo, +                                      &src_brickinfo); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, "Unable to get src-brickinfo"); +                goto out; +        } + +        if (!glusterd_is_local_addr (src_brickinfo->hostname)) { +                gf_log ("", GF_LOG_DEBUG, +                        "I AM THE SOURCE HOST"); +                exists = glusterd_check_volume_exists (volname); + +                if (!exists) { +                        gf_log ("", GF_LOG_ERROR, "Volume with name: %s " +                                "does not exist", +                                volname); +                        ret = -1; +                        goto out; +                } +        }          ret = 0; @@ -896,218 +931,653 @@ out:  }  static int -replace_brick_start_dst_brick (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *dst_brickinfo) -{        glusterd_conf_t    *priv = NULL; -        char  cmd_str[8192] = {0,}; -        char filename[PATH_MAX]; -        FILE *file = NULL; -        int ret; +rb_send_xattr_command (glusterd_volinfo_t *volinfo, +                       glusterd_brickinfo_t *src_brickinfo, +                       glusterd_brickinfo_t *dst_brickinfo, +                       const char *xattr_key, +                       const char *value) +{ +        glusterd_conf_t  *priv                        = NULL; +        char              mount_point_path[PATH_MAX]  = {0,}; +        struct stat       buf; +        int               ret                         = -1;          priv = THIS->private; -        snprintf (filename, PATH_MAX, "%s/vols/%s/replace_dst_brick.vol", -                  priv->workdir, volinfo->volname); +        snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENT_MOUNTPOINT); + +        ret = stat (mount_point_path, &buf); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "stat failed. Could not send " +                        " %s command", xattr_key); +                goto out; +        } +        ret = lsetxattr (mount_point_path, xattr_key, +                         value, +                         strlen (value), +                         0); -        file = fopen (filename, "a+"); -        if (!file) { +        if (ret) {                  gf_log ("", GF_LOG_DEBUG, -                        "Open of volfile failed"); -                return -1; +                        "setxattr failed"); +                goto out;          } -        ret = truncate (filename, 0); +        ret = 0; -        fprintf (file, "volume src-posix\n"); -        fprintf (file, "type storage/posix\n"); -        fprintf (file, "option directory %s\n", -                 dst_brickinfo->path); -        fprintf (file, "end-volume\n"); -        fprintf (file, "volume %s\n", -                 dst_brickinfo->path); -        fprintf (file, "type features/locks\n"); -        fprintf (file, "subvolumes src-posix\n"); -        fprintf (file, "end-volume\n"); -        fprintf (file, "volume src-server\n"); -        fprintf (file, "type protocol/server\n"); -        fprintf (file, "option auth.addr.%s.allow *\n", -                 dst_brickinfo->path); -        fprintf (file, "option listen-port 34034\n"); -        fprintf (file, "subvolumes %s\n", -                 dst_brickinfo->path); -        fprintf (file, "end-volume\n"); +out: +        return ret; +} -        gf_log ("", GF_LOG_DEBUG, -                "starting dst brick"); +static int +rb_spawn_dst_brick (glusterd_volinfo_t *volinfo, +                    glusterd_brickinfo_t *brickinfo) +{ +        glusterd_conf_t    *priv           = NULL; +        char                cmd_str[8192]  = {0,}; +        int                 ret            = -1; -        snprintf (cmd_str, 4096, "glusterfs -f %s/vols/%s/replace_dst_brick.vol", -                  priv->workdir, volinfo->volname); +        priv = THIS->private; + +        snprintf (cmd_str, 8192, "glusterfs -f %s/vols/%s/%s -p %s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_DSTBRICKVOL_FILENAME, +                  priv->workdir, volinfo->volname, +                  RB_DSTBRICK_PIDFILE);          ret = system (cmd_str); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "Could not start glusterfs"); +                goto out; +        } +        gf_log ("", GF_LOG_DEBUG, +                "Successfully started glusterfs: brick=%s:%s", +                brickinfo->hostname, brickinfo->path); -        fclose (file); +        ret = 0; -        return 0; +out: +        return ret;  }  static int -replace_brick_spawn_brick (glusterd_volinfo_t *volinfo, dict_t *dict, -                           glusterd_brickinfo_t *dst_brickinfo) - +rb_spawn_glusterfs_client (glusterd_volinfo_t *volinfo, +                           glusterd_brickinfo_t *brickinfo)  { +        glusterd_conf_t    *priv           = NULL; +        char                cmd_str[8192]  = {0,}; +        struct stat         buf; +        int                 ret            = -1; + +        priv = THIS->private; -        replace_brick_start_dst_brick (volinfo, dst_brickinfo); +        snprintf (cmd_str, 4096, "glusterfs -f %s/vols/%s/%s %s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENTVOL_FILENAME, +                  priv->workdir, volinfo->volname, +                  RB_CLIENT_MOUNTPOINT); -        return 0; +        ret = system (cmd_str); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "Could not start glusterfs"); +                goto out; +        } + +        gf_log ("", GF_LOG_DEBUG, +                "Successfully started glusterfs: brick=%s:%s", +                brickinfo->hostname, brickinfo->path); + +        snprintf (cmd_str, 4096, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENT_MOUNTPOINT); + +        ret = stat (cmd_str, &buf); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "stat on mountpoint failed"); +                goto out; +        } + +        gf_log ("", GF_LOG_DEBUG, +                "stat on mountpoint succeeded"); + +        ret = 0; + +out: +        return ret;  } +static const char *client_volfile_str =  "volume client/protocol\n" +        "type protocol/client\n" +        "option remote-host %s\n" +        "option remote-subvolume %s\n" +        "option remote-port 34034\n" +        "echo end-volume\n"; +  static int -replace_brick_generate_volfile (glusterd_volinfo_t *volinfo, -                                glusterd_brickinfo_t *src_brickinfo) +rb_generate_client_volfile (glusterd_volinfo_t *volinfo, +                            glusterd_brickinfo_t *src_brickinfo)  {          glusterd_conf_t    *priv = NULL;          FILE *file = NULL;          char filename[PATH_MAX]; -        int ret; +        int ret = -1;          priv = THIS->private;          gf_log ("", GF_LOG_DEBUG,                  "Creating volfile"); -        snprintf (filename, PATH_MAX, "%s/vols/%s/replace_brick.vol", -                  priv->workdir, volinfo->volname); +        snprintf (filename, PATH_MAX, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENTVOL_FILENAME); -        file = fopen (filename, "a+"); +        file = fopen (filename, "w+");          if (!file) {                  gf_log ("", GF_LOG_DEBUG,                          "Open of volfile failed"); -                return -1; +                ret = -1; +                goto out;          } -        ret = truncate (filename, 0); -        ret = unlink ("/tmp/replace_brick.vol"); - -        fprintf (file, "volume client/protocol\n"); -        fprintf (file, "type protocol/client\n"); -        fprintf (file, "option remote-host %s\n", -                 src_brickinfo->hostname); -        fprintf (file, "option remote-subvolume %s\n", +        fprintf (file, client_volfile_str, src_brickinfo->hostname,                   src_brickinfo->path); -        fprintf (file, "option remote-port 34034\n"); -        fprintf (file, "echo end-volume\n"); - -        ret = symlink(filename, "/tmp/replace_brick.vol"); -        if (!ret) { -                gf_log ("", GF_LOG_DEBUG, -                        "symlink call failed"); -                return -1; -        }          fclose (file); -        return 0; +        ret = 0; + +out: +        return ret;  } +static const char *dst_brick_volfile_str = "volume src-posix\n" +        "type storage/posix\n" +        "option directory %s\n" +        "end-volume\n" +        "volume %s\n" +        "type features/locks\n" +        "subvolumes src-posix\n" +        "end-volume\n" +        "volume src-server\n" +        "type protocol/server\n" +        "option auth.addr.%s.allow *\n" +        "option listen-port 34034\n" +        "subvolumes %s\n" +        "end-volume\n"; +  static int -replace_brick_start_source_brick (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *src_brickinfo, -                                  glusterd_brickinfo_t *dst_brickinfo) -{        glusterd_conf_t    *priv = NULL; -        char filename[PATH_MAX]; +rb_generate_dst_brick_volfile (glusterd_volinfo_t *volinfo, +                               glusterd_brickinfo_t *dst_brickinfo) +{ +        glusterd_conf_t    *priv = NULL;          FILE *file = NULL; -        char  cmd_str[8192] = {0,}; -        int ret; +        char filename[PATH_MAX]; +        int ret = -1;          priv = THIS->private;          gf_log ("", GF_LOG_DEBUG,                  "Creating volfile"); -        snprintf (filename, PATH_MAX, "%s/vols/%s/replace_source_brick.vol", -                  priv->workdir, volinfo->volname); +        snprintf (filename, PATH_MAX, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_DSTBRICKVOL_FILENAME); -        file = fopen (filename, "a+"); +        file = fopen (filename, "w+");          if (!file) {                  gf_log ("", GF_LOG_DEBUG,                          "Open of volfile failed"); -                return -1; +                ret = -1; +                goto out;          } -        ret = truncate (filename, 0); - -        fprintf (file, "volume src-posix\n"); -        fprintf (file, "type storage/posix\n"); -        fprintf (file, "option directory %s\n", -                 src_brickinfo->path); -        fprintf (file, "end-volume\n"); -        fprintf (file, "volume locks\n"); -        fprintf (file, "type features/locks\n"); -        fprintf (file, "subvolumes src-posix\n"); -        fprintf (file, "end-volume\n"); -        fprintf (file, "volume remote-client\n"); -        fprintf (file, "type protocol/client\n"); -        fprintf (file, "option remote-host %s\n", -                 dst_brickinfo->hostname); -        fprintf (file, "option remote-port 34034\n"); -        fprintf (file, "option remote-subvolume %s\n", +        fprintf (file, dst_brick_volfile_str, dst_brickinfo->path, +                 dst_brickinfo->path, dst_brickinfo->path,                   dst_brickinfo->path); -        fprintf (file, "end-volume\n"); -        fprintf (file, "volume %s\n", -                 src_brickinfo->path); -        fprintf (file, "type cluster/pump\n"); -        fprintf (file, "subvolumes locks remote-client\n"); -        fprintf (file, "end-volume\n"); -        fprintf (file, "volume src-server\n"); -        fprintf (file, "type protocol/server\n"); -        fprintf (file, "option auth.addr.%s.allow *\n", -                 src_brickinfo->path); -        fprintf (file, "option listen-port 34034\n"); -        fprintf (file, "subvolumes %s\n", -                 src_brickinfo->path); -        fprintf (file, "end-volume\n"); +        fclose (file); -        gf_log ("", GF_LOG_DEBUG, -                "starting source brick"); +        ret = 0; + +out: +        return ret; +} + +static int +rb_destroy_maintainence_client (glusterd_volinfo_t *volinfo, +                                glusterd_brickinfo_t *src_brickinfo) +{ +        glusterd_conf_t  *priv                        = NULL; +        char              cmd_str[8192]               = {0,}; +        char              filename[PATH_MAX]          = {0,}; +        struct stat       buf; +        char              mount_point_path[PATH_MAX]  = {0,}; +        int               ret                         = -1; -        snprintf (cmd_str, 4096, "glusterfs -f %s/vols/%s/replace_source_brick.vol -l /tmp/b_log -LTRACE", -                  priv->workdir, volinfo->volname); +        priv = THIS->private; + +        snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENT_MOUNTPOINT); + +        ret = stat (mount_point_path, &buf); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "stat failed. Cannot destroy maintainence " +                        "client"); +                goto out; +        } + +        snprintf (cmd_str, 8192, "umount %s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENT_MOUNTPOINT);          ret = system (cmd_str); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "umount failed on maintainence client"); +                goto out; +        } -        fclose (file); +        snprintf (filename, PATH_MAX, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENTVOL_FILENAME); -        return 0; +        ret = unlink (filename); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "unlink failed"); +                goto out; +        } + +        ret = 0; + +out: +        return ret;  }  static int -replace_brick_mount (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *src_brickinfo, -                     glusterd_brickinfo_t *dst_brickinfo, gf1_cli_replace_op op) +rb_spawn_maintainence_client (glusterd_volinfo_t *volinfo, +                              glusterd_brickinfo_t *src_brickinfo)  { +        int ret = -1; -        gf_log ("", GF_LOG_DEBUG, -                "starting source brick"); +        ret = rb_generate_client_volfile (volinfo, src_brickinfo); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, "Unable to generate client " +                        "volfile"); +                goto out; +        } + +        ret = rb_spawn_glusterfs_client (volinfo, src_brickinfo); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, "Unable to start glusterfs"); +                goto out; +        } + +        ret = 0; +out: +        return ret; +} + +static int +rb_spawn_destination_brick (glusterd_volinfo_t *volinfo, +                            glusterd_brickinfo_t *dst_brickinfo) +{ +        int ret = -1; + +        ret = rb_generate_dst_brick_volfile (volinfo, dst_brickinfo); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, "Unable to generate client " +                        "volfile"); +                goto out; +        } + +        ret = rb_spawn_dst_brick (volinfo, dst_brickinfo); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, "Unable to start glusterfs"); +                goto out; +        } + +        ret = 0; +out: +        return ret; +} + +static int +rb_do_operation_start (glusterd_volinfo_t *volinfo, +                       glusterd_brickinfo_t *src_brickinfo, +                       glusterd_brickinfo_t *dst_brickinfo) +{ +        char start_value[8192] = {0,}; +        int ret = -1; + +        if (!glusterd_is_local_addr (src_brickinfo->hostname)) { +                gf_log ("", GF_LOG_NORMAL, +                        "I AM THE SOURCE HOST"); +                ret = rb_spawn_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Could not spawn maintainence " +                                "client"); +                        goto out; +                } + +                snprintf (start_value, 8192, "%s:%s:", +                          dst_brickinfo->hostname, +                          dst_brickinfo->path); + +                ret = rb_send_xattr_command (volinfo, src_brickinfo, +                                             dst_brickinfo, RB_PUMP_START_CMD, +                                             start_value); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to send command to pump"); +                        goto out; +                } + +                ret = rb_destroy_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to destroy maintainence " +                                "client"); +                        goto out; +                } + +        } else if (!glusterd_is_local_addr (dst_brickinfo->hostname)) { +                gf_log ("", GF_LOG_NORMAL, +                        "I AM THE DESTINATION HOST"); +                ret = rb_spawn_destination_brick (volinfo, dst_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to spawn destination brick"); +                        goto out; +                } + +        } else { +                gf_log ("", GF_LOG_DEBUG, +                        "Not a source or destination brick"); +                ret = 0; +                goto out; +        } + +        ret = 0; + +out: +        return ret; +} -        replace_brick_start_source_brick (volinfo, src_brickinfo, -                                          dst_brickinfo); +/* replace brick commit is handled by cli directly. + * return success all the time. + */ +static int +rb_do_operation_commit (glusterd_volinfo_t *volinfo, +                        glusterd_brickinfo_t *src_brickinfo, +                        glusterd_brickinfo_t *dst_brickinfo) +{ +        gf_log ("", GF_LOG_DEBUG, +                "received commit on %s:%s to %s:%s " +                "on volume %s", +                src_brickinfo->hostname, +                src_brickinfo->path, +                dst_brickinfo->hostname, +                dst_brickinfo->path, +                volinfo->volname);          return 0;  }  static int +rb_do_operation_pause (glusterd_volinfo_t *volinfo, +                       glusterd_brickinfo_t *src_brickinfo, +                       glusterd_brickinfo_t *dst_brickinfo) +{ +        int ret = -1; + +        if (!glusterd_is_local_addr (src_brickinfo->hostname)) { +                gf_log ("", GF_LOG_NORMAL, +                        "I AM THE SOURCE HOST"); +                ret = rb_spawn_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Could not spawn maintainence " +                                "client"); +                        goto out; +                } + +                ret = rb_send_xattr_command (volinfo, src_brickinfo, +                                             dst_brickinfo, RB_PUMP_PAUSE_CMD, +                                             "jargon"); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to send command to pump"); +                        goto out; +                } + +                ret = rb_destroy_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to destroy maintainence " +                                "client"); +                        goto out; +                } +        } + +        ret = 0; + +out: +        return ret; +} + +static int +rb_kill_destination_brick (glusterd_volinfo_t *volinfo, +                           glusterd_brickinfo_t *dst_brickinfo) +{ +        glusterd_conf_t  *priv     = NULL; +        int               ret      = -1; +        char             *pidfile  = NULL; +        pid_t             pid      = -1; +        FILE             *file     = NULL; + +        priv = THIS->private; + +        snprintf (pidfile, PATH_MAX, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_DSTBRICKVOL_FILENAME); + +        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 = 0; + +out: +        return ret; +} + +static int +rb_do_operation_abort (glusterd_volinfo_t *volinfo, +                       glusterd_brickinfo_t *src_brickinfo, +                       glusterd_brickinfo_t *dst_brickinfo) +{ +        int ret = -1; + +        if (!glusterd_is_local_addr (src_brickinfo->hostname)) { +                gf_log ("", GF_LOG_NORMAL, +                        "I AM THE SOURCE HOST"); +                ret = rb_spawn_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Could not spawn maintainence " +                                "client"); +                        goto out; +                } + +                ret = rb_send_xattr_command (volinfo, src_brickinfo, +                                             dst_brickinfo, RB_PUMP_ABORT_CMD, +                                             "jargon"); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to send command to pump"); +                        goto out; +                } + +                ret = rb_destroy_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to destroy maintainence " +                                "client"); +                        goto out; +                } +        } +        else if (!glusterd_is_local_addr (dst_brickinfo->hostname)) { +                gf_log ("", GF_LOG_NORMAL, +                        "I AM THE DESTINATION HOST"); +                ret = rb_kill_destination_brick (volinfo, dst_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to kill destination brick"); +                        goto out; +                } +        } + +        ret = 0; + +out: +        return ret; +} + +static int +rb_get_xattr_command (glusterd_volinfo_t *volinfo, +                      glusterd_brickinfo_t *src_brickinfo, +                      glusterd_brickinfo_t *dst_brickinfo, +                      const char *xattr_key, +                      const char **value) +{ +        glusterd_conf_t  *priv                        = NULL; +        char              mount_point_path[PATH_MAX]  = {0,}; +        struct stat       buf; +        int               ret                         = -1; + +        priv = THIS->private; + +        snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s", +                  priv->workdir, volinfo->volname, +                  RB_CLIENT_MOUNTPOINT); + +        ret = stat (mount_point_path, &buf); +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "stat failed. Could not send " +                        " %s command", xattr_key); +                goto out; +        } + +        ret = lgetxattr (mount_point_path, xattr_key, +                         (char *)(*value), +                         8192); + +        if (ret) { +                gf_log ("", GF_LOG_DEBUG, +                        "setxattr failed"); +                goto out; +        } + +        ret = 0; + +out: +        return ret; +} + +static int +rb_do_operation_status (glusterd_volinfo_t *volinfo, +                        glusterd_brickinfo_t *src_brickinfo, +                        glusterd_brickinfo_t *dst_brickinfo) +{ +        const char *status = NULL; +        int ret = -1; + +        if (!glusterd_is_local_addr (src_brickinfo->hostname)) { +                gf_log ("", GF_LOG_NORMAL, +                        "I AM THE SOURCE HOST"); +                ret = rb_spawn_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Could not spawn maintainence " +                                "client"); +                        goto out; +                } + +                ret = rb_get_xattr_command (volinfo, src_brickinfo, +                                            dst_brickinfo, RB_PUMP_STATUS_CMD, +                                            &status); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to get status from pump"); +                        goto out; +                } + +                gf_log ("", GF_LOG_DEBUG, +                        "pump status is %s", status); + +                ret = rb_destroy_maintainence_client (volinfo, src_brickinfo); +                if (ret) { +                        gf_log ("", GF_LOG_DEBUG, +                                "Failed to destroy maintainence " +                                "client"); +                        goto out; +                } +        } + +out: +        return ret; +} + +static int  glusterd_op_replace_brick (gd1_mgmt_stage_op_req *req)  { -        int                                     ret = 0; +        int                                      ret = 0;          dict_t                                  *dict = NULL; +        gf1_cli_replace_op                       replace_op;          glusterd_volinfo_t                      *volinfo = NULL;          char                                    *volname = NULL;          xlator_t                                *this = NULL;          glusterd_conf_t                         *priv = NULL;          char                                    *src_brick = NULL;          char                                    *dst_brick = NULL; -        char                                    *str = NULL; -          glusterd_brickinfo_t                    *src_brickinfo = NULL;          glusterd_brickinfo_t                    *dst_brickinfo = NULL; @@ -1124,15 +1594,12 @@ glusterd_op_replace_brick (gd1_mgmt_stage_op_req *req)                  goto out;          ret = dict_unserialize (req->buf.buf_val, req->buf.buf_len, &dict); -          if (ret) {                  gf_log ("", GF_LOG_ERROR, "Unable to unserialize dict");                  goto out;          } -        /* Need to do a little more error checking and validation */          ret = dict_get_str (dict, "src-brick", &src_brick); -          if (ret) {                  gf_log ("", GF_LOG_ERROR, "Unable to get src brick");                  goto out; @@ -1142,9 +1609,8 @@ glusterd_op_replace_brick (gd1_mgmt_stage_op_req *req)                  "src brick=%s", src_brick);          ret = dict_get_str (dict, "dst-brick", &dst_brick); -          if (ret) { -                gf_log ("", GF_LOG_ERROR, "Unable to get dest brick"); +                gf_log ("", GF_LOG_ERROR, "Unable to get dst brick");                  goto out;          } @@ -1158,17 +1624,20 @@ glusterd_op_replace_brick (gd1_mgmt_stage_op_req *req)                  goto out;          } -        ret = glusterd_volinfo_find (volname, &volinfo); +        ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op); +        if (ret) { +                gf_log (this->name, GF_LOG_DEBUG, +                        "dict_get on operation failed"); +                goto out; +        } +        ret = glusterd_volinfo_find (volname, &volinfo);          if (ret) {                  gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");                  goto out;          } -        str = strdup (src_brick); - -        ret = glusterd_brickinfo_get (str, volinfo, -                                      &src_brickinfo); +        ret = glusterd_brickinfo_get (src_brick, volinfo, &src_brickinfo);          if (ret) {                  gf_log ("", GF_LOG_DEBUG, "Unable to get src-brickinfo");                  goto out; @@ -1180,17 +1649,25 @@ glusterd_op_replace_brick (gd1_mgmt_stage_op_req *req)                  goto out;          } -        replace_brick_generate_volfile (volinfo, src_brickinfo); - -        if (!glusterd_is_local_addr (src_brickinfo->hostname)) { -                gf_log ("", GF_LOG_NORMAL, -                        "I AM THE SOURCE HOST"); -                replace_brick_mount (volinfo, src_brickinfo, dst_brickinfo, -                                     req->op); -        } else if (!glusterd_is_local_addr (dst_brickinfo->hostname)) { -                gf_log ("", GF_LOG_NORMAL, -                        "I AM THE DESTINATION HOST"); -                replace_brick_spawn_brick (volinfo, dict, dst_brickinfo); +        switch (replace_op) { +        case GF_REPLACE_OP_START: +                rb_do_operation_start (volinfo, src_brickinfo, dst_brickinfo); +                break; +        case GF_REPLACE_OP_COMMIT: +                rb_do_operation_commit (volinfo, src_brickinfo, dst_brickinfo); +                break; +        case GF_REPLACE_OP_PAUSE: +                rb_do_operation_pause (volinfo, src_brickinfo, dst_brickinfo); +                break; +        case GF_REPLACE_OP_ABORT: +                rb_do_operation_abort (volinfo, src_brickinfo, dst_brickinfo); +                break; +        case GF_REPLACE_OP_STATUS: +                rb_do_operation_status (volinfo, src_brickinfo, dst_brickinfo); +                break; +        default: +                ret = -1; +                goto out;          }          ret = 0; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 81c6cb2f4e4..959a9c99926 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -640,6 +640,7 @@ glusterd_brickinfo_get (char *brick, glusterd_volinfo_t *volinfo,          int32_t                 ret = -1;          char                    *hostname = NULL;          char                    *path = NULL; +        char                    *dup_brick = NULL;          glusterd_brickinfo_t    *tmp = NULL;          GF_ASSERT (brick); @@ -648,7 +649,15 @@ glusterd_brickinfo_get (char *brick, glusterd_volinfo_t *volinfo,          gf_log ("", GF_LOG_NORMAL, "brick: %s", brick); -        hostname = strtok (brick, ":"); +        dup_brick = gf_strdup (brick); +        if (!dup_brick) { +                gf_log ("", GF_LOG_ERROR, +                        "Out of memory"); +                ret = -1; +                goto out; +        } + +        hostname = strtok (dup_brick, ":");          path = strtok (NULL, ":");          GF_ASSERT (hostname); @@ -666,6 +675,10 @@ glusterd_brickinfo_get (char *brick, glusterd_volinfo_t *volinfo,          *brickinfo = tmp; +out: +        if (dup_brick) +                GF_FREE (dup_brick); +          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 600381243de..c0ac17c53b2 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -142,6 +142,16 @@ enum glusterd_op_ret {  #define GLUSTERD_VOLUME_INFO_FILE "info"  #define GLUSTERD_BRICK_INFO_DIR "bricks" +/*All definitions related to replace brick */ +#define RB_PUMP_START_CMD       "trusted.glusterfs.pump.start" +#define RB_PUMP_PAUSE_CMD       "trusted.glusterfs.pump.pause" +#define RB_PUMP_ABORT_CMD       "trusted.glusterfs.pump.abort" +#define RB_PUMP_STATUS_CMD      "trusted.glusterfs.pump.status" +#define RB_CLIENT_MOUNTPOINT    "rb_mount" +#define RB_CLIENTVOL_FILENAME   "rb_client.vol" +#define RB_DSTBRICK_PIDFILE     "rb_dst_brick.pid" +#define RB_DSTBRICKVOL_FILENAME "rb_dst_brick.vol" +  #define GLUSTERD_UUID_LEN 50  typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);  | 
