diff options
author | Jeff Darcy <jdarcy@redhat.com> | 2014-01-14 17:00:14 +0000 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2014-01-14 17:00:14 +0000 |
commit | 455791f265e6e581fa4ebddd5dc4642b2201f8ce (patch) | |
tree | ebd5cad9534291822f8c47dbbc8162525f8fe92e /xlators/mgmt/glusterd/src | |
parent | 92eaa72ea4cd0d06c2161842c548008db0eee01c (diff) | |
parent | 7d89ec77763dc5076379753c736f7fce2bedd9ec (diff) |
Merge branch 'upstream' into merge
Diffstat (limited to 'xlators/mgmt/glusterd/src')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 127 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 563 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-mountbroker.c | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 38 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 3 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rebalance.c | 53 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 114 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 463 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 20 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 2 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 10 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 30 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 15 |
16 files changed, 946 insertions, 507 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index 6c316af88..26d608a2f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -585,10 +585,23 @@ subvol_matcher_update (int *subvols, glusterd_volinfo_t *volinfo, static int subvol_matcher_verify (int *subvols, glusterd_volinfo_t *volinfo, char *err_str, - size_t err_len, char *vol_type) + size_t err_len, char *vol_type, int replica_count) { int i = 0; int ret = 0; + int count = volinfo->replica_count-replica_count; + + if (replica_count) { + for (i = 0; i < volinfo->subvol_count; i++) { + if (subvols[i] != count) { + ret = -1; + snprintf (err_str, err_len, "Remove exactly %d" + " brick(s) from each subvolume.", count); + break; + } + } + return ret; + } do { @@ -598,7 +611,6 @@ subvol_matcher_verify (int *subvols, glusterd_volinfo_t *volinfo, char *err_str, ret = -1; snprintf (err_str, err_len, "Bricks not from same subvol for %s", vol_type); - gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str); break; } } while (++i < volinfo->subvol_count); @@ -626,16 +638,11 @@ __glusterd_handle_remove_brick (rpcsvc_request_t *req) glusterd_volinfo_t *volinfo = NULL; glusterd_brickinfo_t *brickinfo = NULL; int *subvols = NULL; - glusterd_brickinfo_t *tmp = NULL; char err_str[2048] = {0}; gf_cli_rsp rsp = {0,}; void *cli_rsp = NULL; char vol_type[256] = {0,}; int32_t replica_count = 0; - int32_t brick_index = 0; - int32_t tmp_brick_idx = 0; - int found = 0; - int diff_count = 0; char *volname = 0; xlator_t *this = NULL; @@ -826,45 +833,6 @@ __glusterd_handle_remove_brick (rpcsvc_request_t *req) (volinfo->brick_count <= volinfo->dist_leaf_count)) continue; - if (replica_count) { - /* do the validation of bricks here */ - /* -2 because i++ is already done, and i starts with 1, - instead of 0 */ - diff_count = (volinfo->replica_count - replica_count); - brick_index = (((i -2) / diff_count) * volinfo->replica_count); - tmp_brick_idx = 0; - found = 0; - list_for_each_entry (tmp, &volinfo->bricks, brick_list) { - tmp_brick_idx++; - gf_log (this->name, GF_LOG_TRACE, - "validate brick %s:%s (%d %d %d)", - tmp->hostname, tmp->path, tmp_brick_idx, - brick_index, volinfo->replica_count); - if (tmp_brick_idx <= brick_index) - continue; - if (tmp_brick_idx > - (brick_index + volinfo->replica_count)) - break; - if ((!strcmp (tmp->hostname,brickinfo->hostname)) && - !strcmp (tmp->path, brickinfo->path)) { - found = 1; - break; - } - } - if (found) - continue; - - snprintf (err_str, sizeof (err_str), "Bricks are from " - "same subvol"); - gf_log (this->name, GF_LOG_INFO, - "failed to validate brick %s:%s (%d %d %d)", - tmp->hostname, tmp->path, tmp_brick_idx, - brick_index, volinfo->replica_count); - ret = -1; - /* brick order is not valid */ - goto out; - } - /* Find which subvolume the brick belongs to */ subvol_matcher_update (subvols, volinfo, brickinfo); } @@ -874,7 +842,7 @@ __glusterd_handle_remove_brick (rpcsvc_request_t *req) (volinfo->subvol_count > 1)) { ret = subvol_matcher_verify (subvols, volinfo, err_str, sizeof(err_str), - vol_type); + vol_type, replica_count); if (ret) goto out; } @@ -1825,6 +1793,11 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr) } case GF_OP_CMD_START: + /* Reset defrag status to 'NOT STARTED' whenever a + * remove-brick/rebalance command is issued to remove + * stale information from previous run. + */ + volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_NOT_STARTED; ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str); if (ret) { gf_log (this->name, GF_LOG_DEBUG, @@ -1869,19 +1842,22 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr) goto out; } - /* Save the list of bricks for later usage. Right now this is required - * for displaying the task parameters with task status in volume status. + /* Save the list of bricks for later usage only on starting a + * remove-brick. Right now this is required for displaying the task + * parameters with task status in volume status. */ - bricks_dict = dict_new (); - if (!bricks_dict) { - ret = -1; - goto out; - } - ret = dict_set_int32 (bricks_dict, "count", count); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to save remove-brick count"); - goto out; + if (GF_OP_CMD_START == cmd) { + bricks_dict = dict_new (); + if (!bricks_dict) { + ret = -1; + goto out; + } + ret = dict_set_int32 (bricks_dict, "count", count); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to save remove-brick count"); + goto out; + } } while ( i <= count) { snprintf (key, 256, "brick%d", i); @@ -1892,20 +1868,22 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr) goto out; } - brick_tmpstr = gf_strdup (brick); - if (!brick_tmpstr) { - ret = -1; - gf_log (this->name, GF_LOG_ERROR, - "Failed to duplicate brick name"); - goto out; - } - ret = dict_set_dynstr (bricks_dict, key, brick_tmpstr); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to add brick to dict"); - goto out; + if (GF_OP_CMD_START == cmd) { + brick_tmpstr = gf_strdup (brick); + if (!brick_tmpstr) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "Failed to duplicate brick name"); + goto out; + } + ret = dict_set_dynstr (bricks_dict, key, brick_tmpstr); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to add brick to dict"); + goto out; + } + brick_tmpstr = NULL; } - brick_tmpstr = NULL; ret = glusterd_op_perform_remove_brick (volinfo, brick, force, &need_rebalance); @@ -1913,6 +1891,9 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr) goto out; i++; } + if (GF_OP_CMD_START == cmd) + volinfo->rebal.dict = dict_ref (bricks_dict); + ret = dict_get_int32 (dict, "replica-count", &replica_count); if (!ret) { gf_log (this->name, GF_LOG_INFO, @@ -1937,8 +1918,6 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr) } } } - volinfo->rebal.dict = bricks_dict; - bricks_dict = NULL; ret = glusterd_create_volfiles_and_notify_services (volinfo); if (ret) { diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 5786694bd..c5c76e11a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -28,17 +28,6 @@ static int dict_get_param (dict_t *dict, char *key, char **param); -static int -glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave, - char *conf_path, char **statefile); - -static int -glusterd_get_slave_info (char *slave, char **slave_ip, - char **slave_vol, char **op_errstr); - -static int -glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen); - struct gsync_config_opt_vals_ gsync_confopt_vals[] = { {.op_name = "change_detector", .no_of_pos_vals = 2, @@ -55,6 +44,11 @@ struct gsync_config_opt_vals_ gsync_confopt_vals[] = { .case_sensitive = _gf_false, .values = {"critical", "error", "warning", "info", "debug"} }, + {.op_name = "use-tarssh", + .no_of_pos_vals = 6, + .case_sensitive = _gf_false, + .values = {"true", "false", "0", "1", "yes", "no"} + }, {.op_name = NULL, }, }; @@ -74,6 +68,11 @@ static char *gsync_reserved_opts[] = { NULL }; +static char *gsync_no_restart_opts[] = { + "checkpoint", + NULL +}; + int __glusterd_handle_sys_exec (rpcsvc_request_t *req) { @@ -899,6 +898,8 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname) } if (op_match) { + if (!op_value) + goto out; val_match = _gf_false; for (i = 0; i < conf_vals->no_of_pos_vals; i++) { if(conf_vals->case_sensitive){ @@ -912,7 +913,7 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname) if (!val_match) { ret = snprintf (errmsg, sizeof(errmsg) - 1, - "Invalid values (%s) for" + "Invalid value(%s) for" " option %s", op_value, op_name); errmsg[ret] = '\0'; @@ -923,7 +924,7 @@ gsync_verify_config_options (dict_t *dict, char **op_errstr, char *volname) } } } - +out: return 0; } @@ -1581,7 +1582,7 @@ out: return ret; } -static int +int glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave, char *conf_path, char **statefile) { @@ -1736,7 +1737,7 @@ glusterd_verify_slave (char *volname, char *slave_ip, char *slave, gf_log ("", GF_LOG_ERROR, "Not a valid slave"); ret = glusterd_gsync_read_frm_status (log_file_path, buf, sizeof(buf)); - if (ret) { + if (ret <= 0) { gf_log ("", GF_LOG_ERROR, "Unable to read from %s", log_file_path); goto out; @@ -2391,6 +2392,8 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave, char *slave_ip = NULL; char *slave_vol = NULL; struct stat stbuf = {0, }; + gf_boolean_t restart_required = _gf_true; + char **resopt = NULL; GF_ASSERT (slave); GF_ASSERT (op_errstr); @@ -2495,18 +2498,28 @@ glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave, out: if (!ret && volinfo) { + for (resopt = gsync_no_restart_opts; *resopt; resopt++) { + restart_required = _gf_true; + if (!strcmp ((*resopt), op_name)){ + restart_required = _gf_false; + break; + } + } + + if (restart_required) { ret = glusterd_check_restart_gsync_session (volinfo, slave, resp_dict, path_list, conf_path, 0); if (ret) - *op_errstr = gf_strdup ("internal error"); + *op_errstr = gf_strdup ("internal error"); + } } gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); return ret; } -static int +int glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen) { int ret = 0; @@ -2530,7 +2543,6 @@ glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen) char *p = buf + len - 1; while (isspace (*p)) *p-- = '\0'; - ret = 0; } } else if (ret < 0) gf_log ("", GF_LOG_ERROR, "Status file of gsyncd is corrupt"); @@ -2540,20 +2552,146 @@ glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen) } static int -glusterd_gsync_fetch_status_extra (char *path, char *buf, size_t blen) +dict_get_param (dict_t *dict, char *key, char **param) +{ + char *dk = NULL; + char *s = NULL; + char x = '\0'; + int ret = 0; + + if (dict_get_str (dict, key, param) == 0) + return 0; + + dk = gf_strdup (key); + if (!key) + return -1; + + s = strpbrk (dk, "-_"); + if (!s) + return -1; + x = (*s == '-') ? '_' : '-'; + *s++ = x; + while ((s = strpbrk (s, "-_"))) + *s++ = x; + + ret = dict_get_str (dict, dk, param); + + GF_FREE (dk); + return ret; +} + +static int +glusterd_parse_gsync_status (char *buf, gf_gsync_status_t *sts_val) +{ + int ret = -1; + int i = -1; + int num_of_fields = 8; + char *token = NULL; + char **tokens = NULL; + char **ptr = NULL; + char *save_ptr = NULL; + char na_buf[] = "N/A"; + + if (!buf) { + gf_log ("", GF_LOG_ERROR, "Empty buf"); + goto out; + } + + tokens = calloc (num_of_fields, sizeof (char *)); + if (!tokens) { + gf_log ("", GF_LOG_ERROR, "Out of memory"); + goto out; + } + + ptr = tokens; + + for (token = strtok_r (buf, ",", &save_ptr); token; + token = strtok_r (NULL, ",", &save_ptr)) { + *ptr = gf_strdup(token); + if (!*ptr) { + gf_log ("", GF_LOG_ERROR, "Out of memory"); + goto out; + } + ptr++; + } + + for (i = 0; i < num_of_fields; i++) { + token = strtok_r (tokens[i], ":", &save_ptr); + token = strtok_r (NULL, "\0", &save_ptr); + token++; + + /* token NULL check */ + if (!token && (i != 0) && + (i != 5) && (i != 7)) + token = na_buf; + + if (i == 0) { + if (!token) + token = na_buf; + else { + token++; + if (!token) + token = na_buf; + else + token[strlen(token) - 1] = '\0'; + } + memcpy (sts_val->slave_node, token, strlen(token)); + } + if (i == 1) + memcpy (sts_val->files_syncd, token, strlen(token)); + if (i == 2) + memcpy (sts_val->purges_remaining, token, strlen(token)); + if (i == 3) + memcpy (sts_val->total_files_skipped, token, strlen(token)); + if (i == 4) + memcpy (sts_val->files_remaining, token, strlen(token)); + if (i == 5) { + if (!token) + token = na_buf; + else { + token++; + if (!token) + token = na_buf; + else + token[strlen(token) - 1] = '\0'; + } + memcpy (sts_val->worker_status, token, strlen(token)); + } + if (i == 6) + memcpy (sts_val->bytes_remaining, token, strlen(token)); + if (i == 7) { + if (!token) + token = na_buf; + else { + token++; + if (!token) + token = na_buf; + else + token[strlen(token) - 2] = '\0'; + } + memcpy (sts_val->crawl_status, token, strlen(token)); + } + } + + ret = 0; +out: + for (i = 0; i< num_of_fields; i++) + if (tokens[i]) + GF_FREE(tokens[i]); + + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +static int +glusterd_gsync_fetch_status_extra (char *path, gf_gsync_status_t *sts_val) { char sockpath[PATH_MAX] = {0,}; struct sockaddr_un sa = {0,}; - size_t l = 0; int s = -1; struct pollfd pfd = {0,}; int ret = 0; - l = strlen (buf); - /* seek to end of data in buf */ - buf += l; - blen -= l; - glusterd_set_socket_filepath (path, sockpath, sizeof (sockpath)); strncpy(sa.sun_path, sockpath, sizeof(sa.sun_path)); @@ -2581,66 +2719,40 @@ glusterd_gsync_fetch_status_extra (char *path, char *buf, size_t blen) ret = -1; goto out; } - ret = read(s, buf, blen); + ret = read(s, sts_val->checkpoint_status, + sizeof(sts_val->checkpoint_status)); /* we expect a terminating 0 byte */ - if (ret == 0 || (ret > 0 && buf[ret - 1])) + if (ret == 0 || (ret > 0 && sts_val->checkpoint_status[ret - 1])) ret = -1; - if (ret > 0) + if (ret > 0) { ret = 0; + } - out: +out: close (s); return ret; } -static int -dict_get_param (dict_t *dict, char *key, char **param) -{ - char *dk = NULL; - char *s = NULL; - char x = '\0'; - int ret = 0; - - if (dict_get_str (dict, key, param) == 0) - return 0; - - dk = gf_strdup (key); - if (!key) - return -1; - - s = strpbrk (dk, "-_"); - if (!s) - return -1; - x = (*s == '-') ? '_' : '-'; - *s++ = x; - while ((s = strpbrk (s, "-_"))) - *s++ = x; - - ret = dict_get_str (dict, dk, param); - - GF_FREE (dk); - return ret; -} - -static int +int glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave, char *conf_path, dict_t *dict, char *node) { - glusterd_conf_t *priv = NULL; - int ret = 0; - char *statefile = NULL; - char *master = NULL; - char buf[1024] = "defunct"; - char nds[1024] = {0, }; - char mst[1024] = {0, }; - char slv[1024] = {0, }; - char sts[1024] = {0, }; - char *bufp = NULL; - dict_t *confd = NULL; - int gsync_count = 0; - int status = 0; - char *dyn_node = NULL; - char *path_list = NULL; + char brick_state_file[PATH_MAX] = ""; + char brick_path[PATH_MAX] = ""; + char *georep_session_wrkng_dir = NULL; + char *master = NULL; + char tmp[1024] = ""; + char sts_val_name[1024] = ""; + char monitor_status[NAME_MAX] = ""; + char *statefile = NULL; + char *socketfile = NULL; + dict_t *confd = NULL; + int gsync_count = 0; + int i = 0; + int ret = 0; + glusterd_brickinfo_t *brickinfo = NULL; + gf_gsync_status_t *sts_val = NULL; + glusterd_conf_t *priv = NULL; GF_ASSERT (THIS); GF_ASSERT (THIS->private); @@ -2661,7 +2773,7 @@ glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave, if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to get configuration data" "for %s(master), %s(slave)", master, slave); - goto done; + goto out; } @@ -2670,120 +2782,168 @@ glusterd_read_status_file (glusterd_volinfo_t *volinfo, char *slave, gf_log ("", GF_LOG_ERROR, "Unable to get state_file's name " "for %s(master), %s(slave). Please check gsync " "config file.", master, slave); - goto done; + goto out; } - ret = glusterd_gsync_read_frm_status (statefile, buf, sizeof (buf)); - if (ret) { + + ret = glusterd_gsync_read_frm_status (statefile, monitor_status, + sizeof (monitor_status)); + if (ret <= 0) { gf_log ("", GF_LOG_ERROR, "Unable to read the status" "file for %s(master), %s(slave)", master, slave); - strncpy (buf, "defunct", sizeof (buf)); - goto done; - } - - ret = gsync_status (master, slave, conf_path, &status); - if (ret == 0 && status == -1) { - if ((strcmp (buf, "Not Started")) && - (strcmp (buf, "Stopped"))) - strncpy (buf, "defunct", sizeof (buf)); - goto done; - } else if (ret == -1) { - gf_log ("", GF_LOG_ERROR, "Unable to get gsync status"); - goto done; + strncpy (monitor_status, "defunct", sizeof (monitor_status)); } - if (strcmp (buf, "Stable") != 0) - goto done; - - ret = dict_get_param (confd, "state_socket_unencoded", &statefile); + ret = dict_get_param (confd, "georep_session_working_dir", + &georep_session_wrkng_dir); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to get state_socket_unencoded" - " filepath. Please check gsync config file."); - goto done; + gf_log ("", GF_LOG_ERROR, "Unable to get geo-rep session's " + "working directory name for %s(master), %s(slave). " + "Please check gsync config file.", master, slave); + goto out; } - ret = glusterd_gsync_fetch_status_extra (statefile, buf, sizeof (buf)); + + ret = dict_get_param (confd, "state_socket_unencoded", &socketfile); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to fetch extra status" - "for %s(master), %s(slave)", master, slave); - /* there is a slight chance that this occurs due to race - * -- in that case, the following options all seem bad: - * - * - suppress irregurlar behavior by just leaving status - * on "OK" - * - freak out users with a misleading "defunct" - * - overload the meaning of the regular error signal - * mechanism of gsyncd, that is, when status is "faulty" - * - * -- so we just come up with something new... - */ - strncpy (buf, "N/A", sizeof (buf)); - goto done; + gf_log ("", GF_LOG_ERROR, "Unable to get socket file's name " + "for %s(master), %s(slave). Please check gsync " + "config file.", master, slave); + goto out; } - done: - if ((!strcmp (buf, "defunct")) || - (!strcmp (buf, "Not Started")) || - (!strcmp (buf, "Stopped"))) { - ret = glusterd_get_local_brickpaths (volinfo, &path_list); - if (!path_list) { - gf_log ("", GF_LOG_DEBUG, "This node not being part of" - " volume should not be running gsyncd. Hence" - " shouldn't display status for this node."); - ret = 0; + ret = dict_get_int32 (dict, "gsync-count", &gsync_count); + if (ret) + gsync_count = 0; + + list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { + if (uuid_compare (brickinfo->uuid, MY_UUID)) + continue; + + sts_val = GF_CALLOC (1, sizeof(gf_gsync_status_t), + gf_common_mt_gsync_status_t); + if (!sts_val) { + gf_log ("", GF_LOG_ERROR, "Out Of Memory"); goto out; } - } - ret = dict_get_int32 (dict, "gsync-count", &gsync_count); + /* Creating the brick state file's path */ + memset(brick_state_file, '\0', PATH_MAX); + memcpy (brick_path, brickinfo->path, PATH_MAX - 1); + for (i = 0; i < strlen(brick_path) - 1; i++) + if (brick_path[i] == '/') + brick_path[i] = '_'; + ret = snprintf(brick_state_file, PATH_MAX - 1, "%s%s.status", + georep_session_wrkng_dir, brick_path); + brick_state_file[ret] = '\0'; + + gf_log ("", GF_LOG_DEBUG, "brick_state_file = %s", brick_state_file); + + memset (tmp, '\0', sizeof(tmp)); + + ret = glusterd_gsync_read_frm_status (brick_state_file, + tmp, sizeof (tmp)); + if (ret <= 0) { + gf_log ("", GF_LOG_ERROR, "Unable to read the status" + "file for %s brick for %s(master), %s(slave) " + "session", brickinfo->path, master, slave); + memcpy (sts_val->slave_node, slave, strlen(slave)); + sts_val->slave_node[strlen(slave)] = '\0'; + ret = snprintf (sts_val->worker_status, sizeof(sts_val->worker_status), "N/A"); + sts_val->worker_status[ret] = '\0'; + ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); + sts_val->checkpoint_status[ret] = '\0'; + ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); + sts_val->crawl_status[ret] = '\0'; + ret = snprintf (sts_val->files_syncd, sizeof(sts_val->files_syncd), "N/A"); + sts_val->files_syncd[ret] = '\0'; + ret = snprintf (sts_val->purges_remaining, sizeof(sts_val->purges_remaining), "N/A"); + sts_val->purges_remaining[ret] = '\0'; + ret = snprintf (sts_val->total_files_skipped, sizeof(sts_val->total_files_skipped), "N/A"); + sts_val->total_files_skipped[ret] = '\0'; + ret = snprintf (sts_val->files_remaining, sizeof(sts_val->files_remaining), "N/A"); + sts_val->files_remaining[ret] = '\0'; + ret = snprintf (sts_val->bytes_remaining, sizeof(sts_val->bytes_remaining), "N/A"); + sts_val->bytes_remaining[ret] = '\0'; + goto store_status; + } - if (ret) - gsync_count = 1; - else - gsync_count++; + ret = glusterd_gsync_fetch_status_extra (socketfile, sts_val); + if (ret || strlen(sts_val->checkpoint_status) == 0) { + gf_log ("", GF_LOG_DEBUG, "No checkpoint status" + "for %s(master), %s(slave)", master, slave); + ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); + sts_val->checkpoint_status[ret] = '\0'; + } - (void) snprintf (nds, sizeof (nds), "node%d", gsync_count); - dyn_node = gf_strdup (node); - if (!dyn_node) - goto out; - ret = dict_set_dynstr (dict, nds, dyn_node); - if (ret) { - GF_FREE (dyn_node); - goto out; - } + ret = glusterd_parse_gsync_status (tmp, sts_val); + if (ret) { + gf_log ("", GF_LOG_ERROR, + "Unable to parse the gsync status for %s", + brickinfo->path); + memcpy (sts_val->slave_node, slave, strlen(slave)); + sts_val->slave_node[strlen(slave)] = '\0'; + ret = snprintf (sts_val->worker_status, sizeof(sts_val->worker_status), "N/A"); + sts_val->worker_status[ret] = '\0'; + ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); + sts_val->checkpoint_status[ret] = '\0'; + ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); + sts_val->crawl_status[ret] = '\0'; + ret = snprintf (sts_val->files_syncd, sizeof(sts_val->files_syncd), "N/A"); + sts_val->files_syncd[ret] = '\0'; + ret = snprintf (sts_val->purges_remaining, sizeof(sts_val->purges_remaining), "N/A"); + sts_val->purges_remaining[ret] = '\0'; + ret = snprintf (sts_val->total_files_skipped, sizeof(sts_val->total_files_skipped), "N/A"); + sts_val->total_files_skipped[ret] = '\0'; + ret = snprintf (sts_val->files_remaining, sizeof(sts_val->files_remaining), "N/A"); + sts_val->files_remaining[ret] = '\0'; + ret = snprintf (sts_val->bytes_remaining, sizeof(sts_val->bytes_remaining), "N/A"); + sts_val->bytes_remaining[ret] = '\0'; + } - snprintf (mst, sizeof (mst), "master%d", gsync_count); - master = gf_strdup (master); - if (!master) - goto out; - ret = dict_set_dynstr (dict, mst, master); - if (ret) { - GF_FREE (master); - goto out; - } +store_status: + if ((strcmp (monitor_status, "Stable"))) { + memcpy (sts_val->worker_status, monitor_status, strlen(monitor_status)); + sts_val->worker_status[strlen(monitor_status)] = '\0'; + ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); + sts_val->crawl_status[ret] = '\0'; + ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); + sts_val->checkpoint_status[ret] = '\0'; + } - snprintf (slv, sizeof (slv), "slave%d", gsync_count); - slave = gf_strdup (slave); - if (!slave) - goto out; - ret = dict_set_dynstr (dict, slv, slave); - if (ret) { - GF_FREE (slave); - goto out; - } + if (strcmp (sts_val->worker_status, "Active")) { + ret = snprintf (sts_val->checkpoint_status, sizeof(sts_val->checkpoint_status), "N/A"); + sts_val->checkpoint_status[ret] = '\0'; + ret = snprintf (sts_val->crawl_status, sizeof(sts_val->crawl_status), "N/A"); + sts_val->crawl_status[ret] = '\0'; + } - snprintf (sts, sizeof (slv), "status%d", gsync_count); - bufp = gf_strdup (buf); - if (!bufp) - goto out; - ret = dict_set_dynstr (dict, sts, bufp); - if (ret) { - GF_FREE (bufp); - goto out; + if (!strcmp (sts_val->slave_node, "N/A")) { + memcpy (sts_val->slave_node, slave, strlen(slave)); + sts_val->slave_node[strlen(slave)] = '\0'; + } + + memcpy (sts_val->node, node, strlen(node)); + sts_val->node[strlen(node)] = '\0'; + memcpy (sts_val->brick, brickinfo->path, strlen(brickinfo->path)); + sts_val->brick[strlen(brickinfo->path)] = '\0'; + memcpy (sts_val->master, master, strlen(master)); + sts_val->master[strlen(master)] = '\0'; + + snprintf (sts_val_name, sizeof (sts_val_name), "status_value%d", gsync_count); + ret = dict_set_bin (dict, sts_val_name, sts_val, sizeof(gf_gsync_status_t)); + if (ret) { + GF_FREE (sts_val); + goto out; + } + + gsync_count++; + sts_val = NULL; } + ret = dict_set_int32 (dict, "gsync-count", gsync_count); if (ret) goto out; - out: +out: dict_destroy (confd); return 0; @@ -3246,30 +3406,32 @@ glusterd_op_sys_exec (dict_t *dict, char **op_errstr, dict_t *rsp_dict) goto out; } - ptr = fgets(buf, sizeof(buf), runner_chio (&runner, STDOUT_FILENO)); - if (ptr) { - ret = dict_get_int32 (rsp_dict, "output_count", &output_count); - if (ret) - output_count = 1; - else - output_count++; - memset (output_name, '\0', sizeof (output_name)); - snprintf (output_name, sizeof (output_name), - "output_%d", output_count); - if (buf[strlen(buf) - 1] == '\n') - buf[strlen(buf) - 1] = '\0'; - bufp = gf_strdup (buf); - if (!bufp) - gf_log ("", GF_LOG_ERROR, "gf_strdup failed."); - ret = dict_set_dynstr (rsp_dict, output_name, bufp); - if (ret) { - GF_FREE (bufp); - gf_log ("", GF_LOG_ERROR, "output set failed."); + do { + ptr = fgets(buf, sizeof(buf), runner_chio (&runner, STDOUT_FILENO)); + if (ptr) { + ret = dict_get_int32 (rsp_dict, "output_count", &output_count); + if (ret) + output_count = 1; + else + output_count++; + memset (output_name, '\0', sizeof (output_name)); + snprintf (output_name, sizeof (output_name), + "output_%d", output_count); + if (buf[strlen(buf) - 1] == '\n') + buf[strlen(buf) - 1] = '\0'; + bufp = gf_strdup (buf); + if (!bufp) + gf_log ("", GF_LOG_ERROR, "gf_strdup failed."); + ret = dict_set_dynstr (rsp_dict, output_name, bufp); + if (ret) { + GF_FREE (bufp); + gf_log ("", GF_LOG_ERROR, "output set failed."); + } + ret = dict_set_int32 (rsp_dict, "output_count", output_count); + if (ret) + gf_log ("", GF_LOG_ERROR, "output_count set failed."); } - ret = dict_set_int32 (rsp_dict, "output_count", output_count); - if (ret) - gf_log ("", GF_LOG_ERROR, "output_count set failed."); - } + } while (ptr); ret = runner_end (&runner); if (ret) { @@ -3708,7 +3870,7 @@ out: } -static int +int glusterd_get_slave_info (char *slave, char **slave_ip, char **slave_vol, char **op_errstr) { @@ -3888,7 +4050,7 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path) /* gluster-params */ runinit_gsyncd_setrx (&runner, conf_path); runner_add_args (&runner, "gluster-params", - "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", + "aux-gfid-mount", ".", ".", NULL); RUN_GSYNCD_CMD; @@ -3902,6 +4064,16 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path) runner_add_args (&runner, ".", ".", NULL); RUN_GSYNCD_CMD; + /* ssh-command tar */ + runinit_gsyncd_setrx (&runner, conf_path); + runner_add_arg (&runner, "ssh-command-tar"); + runner_argprintf (&runner, + "ssh -oPasswordAuthentication=no " + "-oStrictHostKeyChecking=no " + "-i %s/tar_ssh.pem", georepdir); + runner_add_args (&runner, ".", ".", NULL); + RUN_GSYNCD_CMD; + /* pid-file */ runinit_gsyncd_setrx (&runner, conf_path); runner_add_arg (&runner, "pid-file"); @@ -3909,6 +4081,13 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path) runner_add_args (&runner, ".", ".", NULL); RUN_GSYNCD_CMD; + /* geo-rep-working-dir */ + runinit_gsyncd_setrx (&runner, conf_path); + runner_add_arg (&runner, "georep-session-working-dir"); + runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/", georepdir); + runner_add_args (&runner, ".", ".", NULL); + RUN_GSYNCD_CMD; + /* state-file */ runinit_gsyncd_setrx (&runner, conf_path); runner_add_arg (&runner, "state-file"); @@ -3986,7 +4165,7 @@ create_conf_file (glusterd_conf_t *conf, char *conf_path) /* gluster-params */ runinit_gsyncd_setrx (&runner, conf_path); runner_add_args (&runner, "gluster-params", - "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", + "aux-gfid-mount", ".", NULL); RUN_GSYNCD_CMD; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index c7bf53b4e..e296509d8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -3725,10 +3725,12 @@ __glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata, "%s:%s", brickinfo->hostname, brickinfo->path); glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED); - if (rpc_clnt_is_disabled (rpc)) - GF_FREE (brickid); break; + case RPC_CLNT_DESTROY: + GF_FREE (mydata); + mydata = NULL; + break; default: gf_log (this->name, GF_LOG_TRACE, "got some other RPC event %d", event); diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c index 0d67d1303..4ce441da8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c +++ b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c @@ -231,7 +231,6 @@ parse_mount_pattern_desc (gf_mount_spec_t *mspec, char *pdesc) const char *georep_mnt_desc_template = "SUP(" - "xlator-option=\\*-dht.assert-no-child-down=true " "volfile-server=localhost " "client-pid=%d " "user-map-root=%s " diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 0bf7a3352..06ee849f5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -155,6 +155,40 @@ glusterd_op_sm_inject_all_acc () return ret; } +static int +glusterd_check_quota_cmd (char *key, char *value, char *errstr, size_t size) +{ + int ret = -1; + gf_boolean_t b = _gf_false; + + if ((strcmp (key, "quota") == 0) || + (strcmp (key, "features.quota") == 0)) { + ret = gf_string2boolean (value, &b); + if (ret) + goto out; + if (b) { + snprintf (errstr, size," 'gluster " + "volume set <VOLNAME> %s %s' is " + "deprecated. Use 'gluster volume " + "quota <VOLNAME> enable' instead.", + key, value); + ret = -1; + goto out; + } else { + snprintf (errstr, size, " 'gluster " + "volume set <VOLNAME> %s %s' is " + "deprecated. Use 'gluster volume " + "quota <VOLNAME> disable' instead.", + key, value); + ret = -1; + goto out; + } + } + ret = 0; +out: + return ret; +} + int glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickinfo, gd1_mgmt_brick_op_req **req, dict_t *dict) @@ -544,6 +578,10 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) } } + ret = glusterd_check_quota_cmd (key, value, errstr, sizeof (errstr)); + if (ret) + goto out; + if (is_key_glusterd_hooks_friendly (key)) continue; diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index f46f08787..3c8dcf8dd 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -1403,6 +1403,9 @@ glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) "greater than INT64_MAX", hard_limit_str); goto out; } + /*The break statement is missing here to allow intentional fall + * through of code execution to the next switch case + */ case GF_QUOTA_OPTION_TYPE_REMOVE: ret = glusterd_get_gfid_from_brick (dict, volinfo, rsp_dict, diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c index 7911c3d21..b28056135 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c +++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c @@ -152,7 +152,7 @@ __glusterd_defrag_notify (struct rpc_clnt *rpc, void *mydata, glusterd_store_perform_node_state_store (volinfo); if (defrag->rpc) { - rpc_clnt_unref (defrag->rpc); + glusterd_rpc_clnt_unref (priv, defrag->rpc); defrag->rpc = NULL; } if (defrag->cbk_fn) @@ -164,6 +164,9 @@ __glusterd_defrag_notify (struct rpc_clnt *rpc, void *mydata, rpc->conn.trans->name); break; } + case RPC_CLNT_DESTROY: + glusterd_volinfo_unref (volinfo); + break; default: gf_log ("", GF_LOG_TRACE, "got some other RPC event %d", event); @@ -234,7 +237,7 @@ glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr, goto out; } - GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo, priv); + GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo); GLUSTERD_GET_DEFRAG_PID_FILE (pidfile, volinfo, priv); snprintf (logfile, PATH_MAX, "%s/%s-rebalance.log", DEFAULT_LOG_FILE_DIRECTORY, volinfo->volname); @@ -285,7 +288,7 @@ glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr, sleep (5); - ret = glusterd_rebalance_rpc_create (volinfo); + ret = glusterd_rebalance_rpc_create (volinfo, _gf_false); //FIXME: this cbk is passed as NULL in all occurrences. May be //we never needed it. @@ -299,13 +302,21 @@ out: int -glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo) +glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo, + gf_boolean_t reconnect) { dict_t *options = NULL; char sockfile[PATH_MAX] = {0,}; int ret = -1; glusterd_defrag_info_t *defrag = volinfo->rebal.defrag; - glusterd_conf_t *priv = THIS->private; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; + struct stat buf = {0,}; + + this = THIS; + GF_ASSERT (this); + priv = this->private; + GF_ASSERT (priv); //rebalance process is not started if (!defrag) @@ -316,7 +327,30 @@ glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo) ret = 0; goto out; } - GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo, priv); + GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo); + /* If reconnecting check if defrag sockfile exists in the new location + * in /var/run/ , if it does not try the old location + */ + if (reconnect) { + ret = sys_stat (sockfile, &buf); + /* TODO: Remove this once we don't need backward compatability + * with the older path + */ + if (ret && (errno == ENOENT)) { + gf_log (this->name, GF_LOG_WARNING, "Rebalance sockfile " + "%s does not exist. Trying old path.", + sockfile); + GLUSTERD_GET_DEFRAG_SOCK_FILE_OLD (sockfile, volinfo, + priv); + ret =sys_stat (sockfile, &buf); + if (ret && (ENOENT == errno)) { + gf_log (this->name, GF_LOG_ERROR, "Rebalance " + "sockfile %s does not exist.", + sockfile); + goto out; + } + } + } /* Setting frame-timeout to 10mins (600seconds). * Unix domain sockets ensures that the connection is reliable. The @@ -329,6 +363,7 @@ glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo) goto out; } + glusterd_volinfo_ref (volinfo); synclock_unlock (&priv->big_lock); ret = glusterd_rpc_create (&defrag->rpc, options, glusterd_defrag_notify, volinfo); @@ -634,6 +669,12 @@ glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict) case GF_DEFRAG_CMD_START: case GF_DEFRAG_CMD_START_LAYOUT_FIX: case GF_DEFRAG_CMD_START_FORCE: + /* Reset defrag status to 'NOT STARTED' whenever a + * remove-brick/rebalance command is issued to remove + * stale information from previous run. + */ + volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_NOT_STARTED; + ret = dict_get_str (dict, GF_REBALANCE_TID_KEY, &task_id_str); if (ret) { gf_log (this->name, GF_LOG_DEBUG, "Missing rebalance " diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c index 94b0383fe..5c3fc2d82 100644 --- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c @@ -2012,5 +2012,9 @@ out: else ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_ACC, NULL); - glusterd_op_sm (); + synclock_lock (&priv->big_lock); + { + glusterd_op_sm (); + } + synclock_unlock (&priv->big_lock); } diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 5b51aabad..d0ad7dcdb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -166,7 +166,7 @@ out: if (brickinfo) glusterd_brickinfo_delete (brickinfo); if (volinfo) - glusterd_volinfo_delete (volinfo); + glusterd_volinfo_unref (volinfo); return ret; } @@ -883,6 +883,19 @@ out: return ret; } +int +_gd_store_rebalance_dict (dict_t *dict, char *key, data_t *value, void *data) +{ + int ret = -1; + int fd = 0; + + fd = *(int *)data; + + ret = gf_store_save_value (fd, key, value->data); + + return ret; +} + int32_t glusterd_store_node_state_write (int fd, glusterd_volinfo_t *volinfo) { @@ -907,9 +920,14 @@ glusterd_store_node_state_write (int fd, glusterd_volinfo_t *volinfo) if (ret) goto out; - if (volinfo->rebal.defrag_cmd) { - uuid_unparse (volinfo->rebal.rebalance_id, buf); - ret = gf_store_save_value (fd, GF_REBALANCE_TID_KEY, buf); + uuid_unparse (volinfo->rebal.rebalance_id, buf); + ret = gf_store_save_value (fd, GF_REBALANCE_TID_KEY, buf); + if (ret) + goto out; + + if (volinfo->rebal.dict) { + dict_foreach (volinfo->rebal.dict, _gd_store_rebalance_dict, + &fd); } out: gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); @@ -1311,12 +1329,14 @@ glusterd_store_global_info (xlator_t *this) ret = gf_store_rename_tmppath (handle); out: - if (ret && (handle->fd > 0)) - gf_store_unlink_tmppath (handle); + if (handle) { + if (ret && (handle->fd > 0)) + gf_store_unlink_tmppath (handle); - if (handle->fd > 0) { - close (handle->fd); - handle->fd = 0; + if (handle->fd > 0) { + close (handle->fd); + handle->fd = 0; + } } if (uuid_str) @@ -1726,17 +1746,22 @@ out: int32_t glusterd_store_retrieve_node_state (char *volname) { - int32_t ret = -1; - glusterd_volinfo_t *volinfo = NULL; - gf_store_iter_t *iter = NULL; - char *key = NULL; - char *value = NULL; - char volpath[PATH_MAX] = {0,}; - glusterd_conf_t *priv = NULL; - char path[PATH_MAX] = {0,}; - gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; + int32_t ret = -1; + glusterd_volinfo_t *volinfo = NULL; + gf_store_iter_t *iter = NULL; + char *key = NULL; + char *value = NULL; + char *dup_value = NULL; + char volpath[PATH_MAX] = {0,}; + glusterd_conf_t *priv = NULL; + char path[PATH_MAX] = {0,}; + gf_store_op_errno_t op_errno = GD_STORE_SUCCESS; + dict_t *tmp_dict = NULL; + xlator_t *this = NULL; - priv = THIS->private; + this = THIS; + GF_ASSERT (this); + priv = this->private; ret = glusterd_volinfo_find (volname, &volinfo); if (ret) { @@ -1766,16 +1791,35 @@ glusterd_store_retrieve_node_state (char *volname) if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_DEFRAG, strlen (GLUSTERD_STORE_KEY_VOL_DEFRAG))) { volinfo->rebal.defrag_cmd = atoi (value); - } - - if (volinfo->rebal.defrag_cmd) { - if (!strncmp (key, GF_REBALANCE_TID_KEY, - strlen (GF_REBALANCE_TID_KEY))) - uuid_parse (value, volinfo->rebal.rebalance_id); - - if (!strncmp (key, GLUSTERD_STORE_KEY_DEFRAG_OP, - strlen (GLUSTERD_STORE_KEY_DEFRAG_OP))) - volinfo->rebal.op = atoi (value); + } else if (!strncmp (key, GF_REBALANCE_TID_KEY, + strlen (GF_REBALANCE_TID_KEY))) { + uuid_parse (value, volinfo->rebal.rebalance_id); + } else if (!strncmp (key, GLUSTERD_STORE_KEY_DEFRAG_OP, + strlen (GLUSTERD_STORE_KEY_DEFRAG_OP))) { + volinfo->rebal.op = atoi (value); + } else { + if (!tmp_dict) { + tmp_dict = dict_new (); + if (!tmp_dict) { + ret = -1; + goto out; + } + } + dup_value = gf_strdup (value); + if (!dup_value) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "Failed to strdup value string"); + goto out; + } + ret = dict_set_str (tmp_dict, key, dup_value); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "Error setting data in rebal " + "dict."); + goto out; + } + dup_value = NULL; } GF_FREE (key); @@ -1785,9 +1829,13 @@ glusterd_store_retrieve_node_state (char *volname) ret = gf_store_iter_get_next (iter, &key, &value, &op_errno); } + if (tmp_dict) + volinfo->rebal.dict = dict_ref (tmp_dict); - if (op_errno != GD_STORE_EOF) + if (op_errno != GD_STORE_EOF) { + ret = -1; goto out; + } ret = gf_store_iter_destroy (iter); @@ -1795,6 +1843,12 @@ glusterd_store_retrieve_node_state (char *volname) goto out; out: + if (dup_value) + GF_FREE (dup_value); + if (ret && volinfo->rebal.dict) + dict_unref (volinfo->rebal.dict); + if (tmp_dict) + dict_unref (tmp_dict); gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index bcb2dc703..fc4018190 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -445,6 +445,37 @@ glusterd_check_volume_exists (char *volname) return _gf_true; } +glusterd_volinfo_t * +glusterd_volinfo_unref (glusterd_volinfo_t *volinfo) +{ + int refcnt = -1; + + pthread_mutex_lock (&volinfo->reflock); + { + refcnt = --volinfo->refcnt; + } + pthread_mutex_unlock (&volinfo->reflock); + + if (!refcnt) { + glusterd_volinfo_delete (volinfo); + return NULL; + } + + return volinfo; +} + +glusterd_volinfo_t * +glusterd_volinfo_ref (glusterd_volinfo_t *volinfo) +{ + pthread_mutex_lock (&volinfo->reflock); + { + ++volinfo->refcnt; + } + pthread_mutex_unlock (&volinfo->reflock); + + return volinfo; +} + int32_t glusterd_volinfo_new (glusterd_volinfo_t **volinfo) { @@ -478,7 +509,8 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo) new_volinfo->xl = THIS; - *volinfo = new_volinfo; + pthread_mutex_init (&new_volinfo->reflock, NULL); + *volinfo = glusterd_volinfo_ref (new_volinfo); ret = 0; @@ -571,6 +603,14 @@ out: return ret; } +int +glusterd_volinfo_remove (glusterd_volinfo_t *volinfo) +{ + list_del_init (&volinfo->vol_list); + glusterd_volinfo_unref (volinfo); + return 0; +} + int32_t glusterd_volinfo_delete (glusterd_volinfo_t *volinfo) { @@ -595,6 +635,7 @@ glusterd_volinfo_delete (glusterd_volinfo_t *volinfo) glusterd_auth_cleanup (volinfo); + pthread_mutex_destroy (&volinfo->reflock); GF_FREE (volinfo); ret = 0; @@ -1054,7 +1095,7 @@ glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo) peerctx = peerinfo->rpc->mydata; peerinfo->rpc->mydata = NULL; - peerinfo->rpc = rpc_clnt_unref (peerinfo->rpc); + peerinfo->rpc = glusterd_rpc_clnt_unref (priv, peerinfo->rpc); peerinfo->rpc = NULL; if (peerctx) { GF_FREE (peerctx->errstr); @@ -1142,6 +1183,18 @@ glusterd_service_stop (const char *service, char *pidfile, int sig, "%d", service, pid); ret = kill (pid, sig); + if (ret) { + switch (errno) { + case ESRCH: + gf_log (this->name, GF_LOG_DEBUG, "%s is already stopped", + service); + ret = 0; + goto out; + default: + gf_log (this->name, GF_LOG_ERROR, "Failed to kill %s: %s", + service, strerror (errno)); + } + } if (!force_kill) goto out; @@ -1466,9 +1519,7 @@ glusterd_brick_disconnect (glusterd_brickinfo_t *brickinfo) brickinfo->rpc = NULL; if (rpc) { - synclock_unlock (&priv->big_lock); - rpc_clnt_unref (rpc); - synclock_lock (&priv->big_lock); + glusterd_rpc_clnt_unref (priv, rpc); } return 0; @@ -1959,20 +2010,18 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; - if (volinfo->rebal.defrag_cmd) { - rebalance_id_str = gf_strdup (uuid_utoa - (volinfo->rebal.rebalance_id)); - if (!rebalance_id_str) { - ret = -1; - goto out; - } - memset (key, 0, sizeof (key)); - snprintf (key, 256, "volume%d.rebalance-id", count); - ret = dict_set_dynstr (dict, key, rebalance_id_str); - if (ret) - goto out; - rebalance_id_str = NULL; + rebalance_id_str = gf_strdup (uuid_utoa + (volinfo->rebal.rebalance_id)); + if (!rebalance_id_str) { + ret = -1; + goto out; } + memset (key, 0, sizeof (key)); + snprintf (key, 256, "volume%d.rebalance-id", count); + ret = dict_set_dynstr (dict, key, rebalance_id_str); + if (ret) + goto out; + rebalance_id_str = NULL; memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "volume%d.rebalance-op", count); @@ -1980,6 +2029,23 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; + if (volinfo->rebal.dict) { + snprintf (prefix, sizeof (prefix), "volume%d", count); + ctx.dict = dict; + ctx.prefix = prefix; + ctx.opt_count = 1; + ctx.key_name = "rebal-dict-key"; + ctx.val_name = "rebal-dict-value"; + + dict_foreach (volinfo->rebal.dict, _add_dict_to_prdict, &ctx); + ctx.opt_count--; + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.rebal-dict-count", count); + ret = dict_set_int32 (dict, key, ctx.opt_count); + if (ret) + goto out; + } + memset (key, 0, sizeof (key)); snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count); ret = dict_set_int32 (dict, key, volinfo->rep_brick.rb_status); @@ -2069,6 +2135,13 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.brick%d.decommissioned", + count, i); + ret = dict_set_int32 (dict, key, brickinfo->decommissioned); + if (ret) + goto out; + i++; } @@ -2736,6 +2809,7 @@ glusterd_import_new_brick (dict_t *vols, int32_t vol_count, int ret = -1; char *hostname = NULL; char *path = NULL; + int decommissioned = 0; glusterd_brickinfo_t *new_brickinfo = NULL; char msg[2048] = {0}; @@ -2761,12 +2835,22 @@ glusterd_import_new_brick (dict_t *vols, int32_t vol_count, goto out; } + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.brick%d.decommissioned", + vol_count, brick_count); + ret = dict_get_int32 (vols, key, &decommissioned); + if (ret) { + /* For backward compatibility */ + ret = 0; + } + ret = glusterd_brickinfo_new (&new_brickinfo); if (ret) goto out; strcpy (new_brickinfo->path, path); strcpy (new_brickinfo->hostname, hostname); + new_brickinfo->decommissioned = decommissioned; //peerinfo might not be added yet (void) glusterd_resolve_brick (new_brickinfo); ret = 0; @@ -2911,6 +2995,43 @@ out: return ret; } +int +gd_import_friend_volume_rebal_dict (dict_t *dict, int count, + glusterd_volinfo_t *volinfo) +{ + int ret = -1; + char key[256] = {0,}; + int dict_count = 0; + char prefix[64] = {0}; + + GF_ASSERT (dict); + GF_ASSERT (volinfo); + + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.rebal-dict-count", count); + ret = dict_get_int32 (dict, key, &dict_count); + if (ret) { + /* Older peers will not have this dict */ + ret = 0; + goto out; + } + + volinfo->rebal.dict = dict_new (); + if(!volinfo->rebal.dict) { + ret = -1; + goto out; + } + + snprintf (prefix, sizeof (prefix), "volume%d", count); + ret = import_prdict_dict (dict, volinfo->rebal.dict, "rebal-dict-key", + "rebal-dict-value", dict_count, prefix); +out: + if (ret && volinfo->rebal.dict) + dict_unref (volinfo->rebal.dict); + gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret); + return ret; +} + int32_t glusterd_import_volinfo (dict_t *vols, int count, glusterd_volinfo_t **volinfo) @@ -3017,7 +3138,8 @@ glusterd_import_volinfo (dict_t *vols, int count, if (ret) gf_log (THIS->name, GF_LOG_INFO, "peer is possibly old version"); - + new_volinfo->subvol_count = new_volinfo->brick_count/ + glusterd_get_dist_leaf_count (new_volinfo); memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "volume%d.ckusm", count); ret = dict_get_uint32 (vols, key, &new_volinfo->cksum); @@ -3074,19 +3196,16 @@ glusterd_import_volinfo (dict_t *vols, int count, goto out; } - if (new_volinfo->rebal.defrag_cmd) { - memset (key, 0, sizeof (key)); - snprintf (key, sizeof (key), "volume%d.rebalance-id", count); - ret = dict_get_str (vols, key, &rebalance_id_str); - if (ret) { - /* This is not present in older glusterfs versions, - * so don't error out - */ - ret = 0; - } else { - uuid_parse (rebalance_id_str, - new_volinfo->rebal.rebalance_id); - } + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.rebalance-id", count); + ret = dict_get_str (vols, key, &rebalance_id_str); + if (ret) { + /* This is not present in older glusterfs versions, + * so don't error out + */ + ret = 0; + } else { + uuid_parse (rebalance_id_str, new_volinfo->rebal.rebalance_id); } memset (key, 0, sizeof (key)); @@ -3098,6 +3217,12 @@ glusterd_import_volinfo (dict_t *vols, int count, */ ret = 0; } + ret = gd_import_friend_volume_rebal_dict (vols, count, new_volinfo); + if (ret) { + snprintf (msg, sizeof (msg), "Failed to import rebalance dict " + "for volume."); + goto out; + } memset (key, 0, sizeof (key)); snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count); @@ -3324,7 +3449,7 @@ glusterd_delete_stale_volume (glusterd_volinfo_t *stale_volinfo, (void) gf_store_handle_destroy (stale_volinfo->shandle); stale_volinfo->shandle = NULL; } - (void) glusterd_volinfo_delete (stale_volinfo); + (void) glusterd_volinfo_remove (stale_volinfo); return 0; } @@ -3344,10 +3469,14 @@ gd_check_and_update_rebalance_info (glusterd_volinfo_t *old_volinfo, old = &(old_volinfo->rebal); new = &(new_volinfo->rebal); - /* If the task-id's don't match, the old volinfo task is stale and - * should be cleaned up - */ - if (uuid_compare (old->rebalance_id, new->rebalance_id)) { + + //Disconnect from rebalance process + if (old->defrag && old->defrag->rpc) { + rpc_transport_disconnect (old->defrag->rpc->conn.trans); + } + + if (!uuid_is_null (old->rebalance_id) && + uuid_compare (old->rebalance_id, new->rebalance_id)) { (void)gd_stop_rebalance_process (old_volinfo); goto out; } @@ -3362,11 +3491,11 @@ gd_check_and_update_rebalance_info (glusterd_volinfo_t *old_volinfo, new->skipped_files = old->skipped_files; new->rebalance_failures = old->rebalance_failures; new->rebalance_time = old->rebalance_time; - new->defrag = old->defrag; new->dict = (old->dict ? dict_ref (old->dict) : NULL); /* glusterd_rebalance_t.{op, id, defrag_cmd} are copied during volume * import + * a new defrag object should come to life with rebalance being restarted */ out: return ret; @@ -3824,12 +3953,13 @@ int32_t glusterd_nodesvc_disconnect (char *server) { struct rpc_clnt *rpc = NULL; + glusterd_conf_t *priv = THIS->private; rpc = glusterd_nodesvc_get_rpc (server); (void)glusterd_nodesvc_set_rpc (server, NULL); if (rpc) - rpc_clnt_unref (rpc); + glusterd_rpc_clnt_unref (priv, rpc); return 0; } @@ -4594,14 +4724,24 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) { char *path_list = NULL; char *slave = NULL; + char *slave_ip = NULL; + char *slave_vol = NULL; + char *statefile = NULL; + char buf[1024] = "faulty"; int uuid_len = 0; int ret = 0; char uuid_str[64] = {0}; - glusterd_volinfo_t *volinfo = NULL; - char *conf_path = NULL; + glusterd_volinfo_t *volinfo = NULL; + char confpath[PATH_MAX] = ""; + char *op_errstr = NULL; + glusterd_conf_t *priv = NULL; + + GF_ASSERT (THIS); + priv = THIS->private; + GF_ASSERT (priv); + GF_ASSERT (data); volinfo = data; - GF_ASSERT (volinfo); slave = strchr(value->data, ':'); if (slave) slave ++; @@ -4611,22 +4751,63 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) strncpy (uuid_str, (char*)value->data, uuid_len); + /* Getting Local Brickpaths */ ret = glusterd_get_local_brickpaths (volinfo, &path_list); - ret = dict_get_str (this, "conf_path", &conf_path); + /*Generating the conf file path needed by gsyncd */ + ret = glusterd_get_slave_info (slave, &slave_ip, + &slave_vol, &op_errstr); if (ret) { gf_log ("", GF_LOG_ERROR, - "Unable to fetch conf file path."); + "Unable to fetch slave details."); + ret = -1; goto out; } - glusterd_start_gsync (volinfo, slave, path_list, conf_path, - uuid_str, NULL); + ret = snprintf (confpath, sizeof(confpath) - 1, + "%s/"GEOREP"/%s_%s_%s/gsyncd.conf", + priv->workdir, volinfo->volname, + slave_ip, slave_vol); + confpath[ret] = '\0'; + + /* Fetching the last status of the node */ + ret = glusterd_get_statefile_name (volinfo, slave, + confpath, &statefile); + if (ret) { + if (!strstr(slave, "::")) + gf_log ("", GF_LOG_INFO, + "%s is not a valid slave url.", slave); + else + gf_log ("", GF_LOG_INFO, "Unable to get" + " statefile's name"); + goto out; + } - GF_FREE (path_list); - path_list = NULL; + ret = glusterd_gsync_read_frm_status (statefile, buf, sizeof (buf)); + if (ret < 0) { + gf_log ("", GF_LOG_ERROR, "Unable to read the status"); + goto out; + } + + /* Looks for the last status, to find if the sessiom was running + * when the node went down. If the session was not started or + * not started, do not restart the geo-rep session */ + if ((!strcmp (buf, "Not Started")) || + (!strcmp (buf, "Stopped"))) { + gf_log ("", GF_LOG_INFO, + "Geo-Rep Session was not started between " + "%s and %s::%s. Not Restarting", volinfo->volname, + slave_ip, slave_vol); + goto out; + } + + glusterd_start_gsync (volinfo, slave, path_list, confpath, + uuid_str, NULL); out: + if (path_list) + GF_FREE (path_list); + return ret; } @@ -6045,7 +6226,7 @@ glusterd_delete_volume (glusterd_volinfo_t *volinfo) if (ret) goto out; - ret = glusterd_volinfo_delete (volinfo); + glusterd_volinfo_remove (volinfo); out: gf_log (THIS->name, GF_LOG_DEBUG, "returning %d", ret); return ret; @@ -6771,7 +6952,7 @@ glusterd_volume_defrag_restart (glusterd_volinfo_t *volinfo, char *op_errstr, case GF_DEFRAG_STATUS_STARTED: GLUSTERD_GET_DEFRAG_PID_FILE(pidfile, volinfo, priv); if (gf_is_service_running (pidfile, &pid)) { - glusterd_rebalance_rpc_create (volinfo); + glusterd_rebalance_rpc_create (volinfo, _gf_true); break; } case GF_DEFRAG_STATUS_NOT_STARTED: @@ -7208,21 +7389,16 @@ glusterd_append_gsync_status (dict_t *dst, dict_t *src) } -static int32_t +int32_t glusterd_append_status_dicts (dict_t *dst, dict_t *src) { - int dst_count = 0; - int src_count = 0; - int i = 0; - int ret = 0; - char mst[PATH_MAX] = {0,}; - char slv[PATH_MAX] = {0, }; - char sts[PATH_MAX] = {0, }; - char nds[PATH_MAX] = {0, }; - char *mst_val = NULL; - char *slv_val = NULL; - char *sts_val = NULL; - char *nds_val = NULL; + char sts_val_name[PATH_MAX] = {0, }; + int dst_count = 0; + int src_count = 0; + int i = 0; + int ret = 0; + gf_gsync_status_t *sts_val = NULL; + gf_gsync_status_t *dst_sts_val = NULL; GF_ASSERT (dst); @@ -7240,49 +7416,29 @@ glusterd_append_status_dicts (dict_t *dst, dict_t *src) goto out; } - for (i = 1; i <= src_count; i++) { - snprintf (nds, sizeof(nds), "node%d", i); - snprintf (mst, sizeof(mst), "master%d", i); - snprintf (slv, sizeof(slv), "slave%d", i); - snprintf (sts, sizeof(sts), "status%d", i); - - ret = dict_get_str (src, nds, &nds_val); - if (ret) - goto out; - - ret = dict_get_str (src, mst, &mst_val); - if (ret) - goto out; - - ret = dict_get_str (src, slv, &slv_val); - if (ret) - goto out; + for (i = 0; i < src_count; i++) { + memset (sts_val_name, '\0', sizeof(sts_val_name)); + snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i); - ret = dict_get_str (src, sts, &sts_val); + ret = dict_get_bin (src, sts_val_name, (void **) &sts_val); if (ret) goto out; - snprintf (nds, sizeof(nds), "node%d", i+dst_count); - snprintf (mst, sizeof(mst), "master%d", i+dst_count); - snprintf (slv, sizeof(slv), "slave%d", i+dst_count); - snprintf (sts, sizeof(sts), "status%d", i+dst_count); - - ret = dict_set_dynstr (dst, nds, gf_strdup (nds_val)); - if (ret) + dst_sts_val = GF_CALLOC (1, sizeof(gf_gsync_status_t), + gf_common_mt_gsync_status_t); + if (!dst_sts_val) { + gf_log ("", GF_LOG_ERROR, "Out Of Memory"); goto out; + } - ret = dict_set_dynstr (dst, mst, gf_strdup (mst_val)); - if (ret) - goto out; + memcpy (dst_sts_val, sts_val, sizeof(gf_gsync_status_t)); - ret = dict_set_dynstr (dst, slv, gf_strdup (slv_val)); - if (ret) - goto out; + memset (sts_val_name, '\0', sizeof(sts_val_name)); + snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i + dst_count); - ret = dict_set_dynstr (dst, sts, gf_strdup (sts_val)); + ret = dict_set_bin (dst, sts_val_name, dst_sts_val, sizeof(gf_gsync_status_t)); if (ret) goto out; - } ret = dict_set_int32 (dst, "gsync-count", dst_count+src_count); @@ -9146,72 +9302,15 @@ glusterd_remove_auxiliary_mount (char *volname) return ret; } -/* Just a minimal callback function to which logs if the request was successfull - * or not - */ -int -_gd_stop_rebalance_process_cbk (struct rpc_req *req, struct iovec *iov, - int count, void *call_frame) -{ - xlator_t *this = NULL; - struct syncargs *args = NULL; - gd1_mgmt_brick_op_rsp rsp = {0,}; - int ret = -1; - call_frame_t *frame = NULL; - - this = THIS; - GF_ASSERT (this); - - frame = call_frame; - args = frame->local; - frame->local = NULL; - - if (-1 == req->rpc_status) { - gf_log (this->name, GF_LOG_WARNING, "Failed to stop rebalance " - "process."); - goto out; - } - - ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp); - if (ret < 0) { - gf_log (this->name, GF_LOG_DEBUG, "Failed to decode stop " - "rebalance process response."); - goto out; - } - - gf_log (this->name, GF_LOG_INFO, "Stopping rebalance process was %s.", - (rsp.op_ret ? "unsuccessful" : "successful")); - -out: - if ((rsp.op_errstr) && (strcmp (rsp.op_errstr, "") != 0)) - free (rsp.op_errstr); - free (rsp.output.output_val); - - STACK_DESTROY (frame->root); - __wake (args); - - return 0; -} - -int -gd_stop_rebalance_process_cbk (struct rpc_req *req, struct iovec *iov, - int count, void *call_frame) -{ - return glusterd_big_locked_cbk (req, iov, count, call_frame, - _gd_stop_rebalance_process_cbk); -} -/* Stops the rebalance process of the given volume, gracefully +/* Stops the rebalance process of the given volume */ int gd_stop_rebalance_process (glusterd_volinfo_t *volinfo) { - int ret = -1; - xlator_t *this = NULL; - glusterd_conf_t *conf = NULL; - gd1_mgmt_brick_op_req *req = NULL; - dict_t *req_dict = NULL; - char *name = NULL; - struct syncargs args = {0,}; + int ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + char pidfile[PATH_MAX] = {0,}; GF_ASSERT (volinfo); @@ -9221,43 +9320,23 @@ gd_stop_rebalance_process (glusterd_volinfo_t *volinfo) conf = this->private; GF_ASSERT (conf); - req = GF_CALLOC (1, sizeof (*req), gf_gld_mt_mop_brick_req_t); - if (!req) { - ret = -1; - goto out; - } - - req->op = GLUSTERD_BRICK_XLATOR_DEFRAG; - - ret = gf_asprintf(&name, "%s-dht", volinfo->volname); - if (ret < 0) - goto out; - req->name = name; - - req_dict = dict_new(); - if (!req_dict) { - ret = -1; - goto out; - } - - ret = dict_set_int32 (req_dict, "rebalance-command", - GF_DEFRAG_CMD_STOP); - if (ret) - goto out; + GLUSTERD_GET_DEFRAG_PID_FILE (pidfile, volinfo, conf); + ret = glusterd_service_stop ("rebalance", pidfile, SIGTERM, _gf_true); - ret = dict_allocate_and_serialize (req_dict, &req->input.input_val, - &req->input.input_len); - if (ret) - goto out; + return ret; +} - GD_SYNCOP (volinfo->rebal.defrag->rpc, (&args), NULL, - gd_stop_rebalance_process_cbk, req, conf->gfs_mgmt, req->op, - (xdrproc_t)xdr_gd1_mgmt_brick_op_req); -out: +rpc_clnt_t * +glusterd_rpc_clnt_unref (glusterd_conf_t *conf, rpc_clnt_t *rpc) +{ + rpc_clnt_t *ret = NULL; - GF_FREE (name); - GF_FREE (req); - dict_unref (req_dict); + GF_ASSERT (conf); + GF_ASSERT (rpc); + synclock_unlock (&conf->big_lock); + ret = rpc_clnt_unref (rpc); + synclock_lock (&conf->big_lock); return ret; } + diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index 970b1f8a6..05d5c7172 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -137,6 +137,12 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, gf_boolean_t del_brick); +glusterd_volinfo_t * +glusterd_volinfo_ref (glusterd_volinfo_t *volinfo); + +glusterd_volinfo_t * +glusterd_volinfo_unref (glusterd_volinfo_t *volinfo); + int32_t glusterd_volinfo_delete (glusterd_volinfo_t *volinfo); @@ -583,6 +589,17 @@ glusterd_get_slave_details_confpath (glusterd_volinfo_t *volinfo, dict_t *dict, char **conf_path, char **op_errstr); int +glusterd_get_slave_info (char *slave, char **slave_ip, + char **slave_vol, char **op_errstr); + +int +glusterd_get_statefile_name (glusterd_volinfo_t *volinfo, char *slave, + char *conf_path, char **statefile); + +int +glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen); + +int glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave, dict_t *resp_dict, char *path_list, char *conf_path, gf_boolean_t is_force); @@ -624,4 +641,7 @@ glusterd_status_has_tasks (int cmd); int gd_stop_rebalance_process (glusterd_volinfo_t *volinfo); + +rpc_clnt_t * +glusterd_rpc_clnt_unref (glusterd_conf_t *conf, rpc_clnt_t *rpc); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index fe33c8d7d..a94a47af3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -3505,7 +3505,7 @@ out: if (brickinfo) glusterd_brickinfo_delete (brickinfo); if (volinfo) - glusterd_volinfo_delete (volinfo); + glusterd_volinfo_unref (volinfo); return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 41555230e..df2562ba6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -1696,7 +1696,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) out: GF_FREE(free_ptr); if (!vol_added && volinfo) - glusterd_volinfo_delete (volinfo); + glusterd_volinfo_unref (volinfo); return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index f209d1ad9..520b0f774 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -831,6 +831,16 @@ struct volopt_map_entry glusterd_volopt_map[] = { .option = "root-squash", .op_version = 2 }, + { .key = "server.anonuid", + .voltype = "protocol/server", + .option = "anonuid", + .op_version = 3 + }, + { .key = "server.anongid", + .voltype = "protocol/server", + .option = "anongid", + .op_version = 3 + }, { .key = "server.statedump-path", .voltype = "protocol/server", .option = "statedump-path", diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index c3fccf8e1..834a39968 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -594,7 +594,7 @@ configure_syncdaemon (glusterd_conf_t *conf) /* gluster-params */ runinit_gsyncd_setrx (&runner, conf); runner_add_args (&runner, "gluster-params", - "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", + "aux-gfid-mount", ".", ".", NULL); RUN_GSYNCD_CMD; @@ -608,6 +608,16 @@ configure_syncdaemon (glusterd_conf_t *conf) runner_add_args (&runner, ".", ".", NULL); RUN_GSYNCD_CMD; + /* ssh-command tar */ + runinit_gsyncd_setrx (&runner, conf); + runner_add_arg (&runner, "ssh-command-tar"); + runner_argprintf (&runner, + "ssh -oPasswordAuthentication=no " + "-oStrictHostKeyChecking=no " + "-i %s/tar_ssh.pem", georepdir); + runner_add_args (&runner, ".", ".", NULL); + RUN_GSYNCD_CMD; + /* pid-file */ runinit_gsyncd_setrx (&runner, conf); runner_add_arg (&runner, "pid-file"); @@ -615,6 +625,13 @@ configure_syncdaemon (glusterd_conf_t *conf) runner_add_args (&runner, ".", ".", NULL); RUN_GSYNCD_CMD; + /* geo-rep working dir */ + runinit_gsyncd_setrx (&runner, conf); + runner_add_arg (&runner, "georep-session-working-dir"); + runner_argprintf (&runner, "%s/${mastervol}_${remotehost}_${slavevol}/", georepdir); + runner_add_args (&runner, ".", ".", NULL); + RUN_GSYNCD_CMD; + /* state-file */ runinit_gsyncd_setrx (&runner, conf); runner_add_arg (&runner, "state-file"); @@ -701,7 +718,7 @@ configure_syncdaemon (glusterd_conf_t *conf) /* gluster-params */ runinit_gsyncd_setrx (&runner, conf); runner_add_args (&runner, "gluster-params", - "aux-gfid-mount xlator-option=*-dht.assert-no-child-down=true", + "aux-gfid-mount", ".", NULL); RUN_GSYNCD_CMD; @@ -1515,8 +1532,13 @@ struct volume_options options[] = { { .key = {"server-quorum-type"}, .type = GF_OPTION_TYPE_STR, .value = { "none", "server"}, - .description = "If set to server, enables the specified " - "volume to participate in quorum." + .description = "This feature is on the server-side i.e. in glusterd." + " Whenever the glusterd on a machine observes that " + "the quorum is not met, it brings down the bricks to " + "prevent data split-brains. When the network " + "connections are brought back up and the quorum is " + "restored the bricks in the volume are brought back " + "up." }, { .key = {"server-quorum-ratio"}, .type = GF_OPTION_TYPE_PERCENT, diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index d2c88609e..e704de44b 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -48,7 +48,7 @@ #define GLUSTERD_QUORUM_RATIO_KEY "cluster.server-quorum-ratio" #define GLUSTERD_GLOBAL_OPT_VERSION "global-option-version" #define GLUSTERD_COMMON_PEM_PUB_FILE "/geo-replication/common_secret.pem.pub" -#define GEO_CONF_MAX_OPT_VALS 5 +#define GEO_CONF_MAX_OPT_VALS 6 #define GLUSTERD_CREATE_HOOK_SCRIPT "/hooks/1/gsync-create/post/" \ "S56glusterd-geo-rep-create-post.sh" @@ -329,6 +329,8 @@ struct glusterd_volinfo_ { int op_version; int client_op_version; + pthread_mutex_t reflock; + int refcnt; }; typedef enum gd_node_type_ { @@ -457,13 +459,19 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); snprintf (path, PATH_MAX, "%s/rebalance",vol_path); \ } while (0) -#define GLUSTERD_GET_DEFRAG_SOCK_FILE(path, volinfo, priv) do { \ +#define GLUSTERD_GET_DEFRAG_SOCK_FILE_OLD(path, volinfo, priv) do { \ char defrag_path[PATH_MAX]; \ GLUSTERD_GET_DEFRAG_DIR(defrag_path, volinfo, priv); \ snprintf (path, PATH_MAX, "%s/%s.sock", defrag_path, \ uuid_utoa(MY_UUID)); \ } while (0) +#define GLUSTERD_GET_DEFRAG_SOCK_FILE(path, volinfo) do { \ + snprintf (path, UNIX_PATH_MAX, DEFAULT_VAR_RUN_DIRECTORY \ + "/gluster-rebalance-%s.sock", \ + uuid_utoa(volinfo->volume_id)); \ + } while (0) + #define GLUSTERD_GET_DEFRAG_PID_FILE(path, volinfo, priv) do { \ char defrag_path[PATH_MAX]; \ GLUSTERD_GET_DEFRAG_DIR(defrag_path, volinfo, priv); \ @@ -745,7 +753,8 @@ int glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr, size_t len, int cmd, defrag_cbk_fn_t cbk, glusterd_op_t op); int -glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo); +glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo, + gf_boolean_t reconnect); int glusterd_handle_cli_heal_volume (rpcsvc_request_t *req); |