diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-utils.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 287 |
1 files changed, 225 insertions, 62 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 000a6b10..66f4c971 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -1538,89 +1538,85 @@ glusterd_sort_and_redirect (const char *src_filepath, int dest_fd) } int -glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo) -{ - int32_t ret = -1; - glusterd_conf_t *priv = NULL; - char path[PATH_MAX] = {0,}; - char cksum_path[PATH_MAX] = {0,}; - char filepath[PATH_MAX] = {0,}; - int fd = -1; - uint32_t cksum = 0; - char buf[4096] = {0,}; +glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo, char *cksum_path, + char *filepath, gf_boolean_t is_quota_conf, + uint32_t *cs) +{ + int32_t ret = -1; + uint32_t cksum = 0; + int fd = -1; + int sort_fd = 0; char sort_filepath[PATH_MAX] = {0}; - gf_boolean_t unlink_sortfile = _gf_false; - int sort_fd = 0; - xlator_t *this = NULL; + char *cksum_path_final = NULL; + char buf[4096] = {0,}; + gf_boolean_t unlink_sortfile = _gf_false; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; GF_ASSERT (volinfo); this = THIS; priv = THIS->private; GF_ASSERT (priv); - GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv); - - snprintf (cksum_path, sizeof (cksum_path), "%s/%s", - path, GLUSTERD_CKSUM_FILE); - fd = open (cksum_path, O_RDWR | O_APPEND | O_CREAT| O_TRUNC, 0600); if (-1 == fd) { - gf_log (this->name, GF_LOG_ERROR, "Unable to open %s, errno: %d", - cksum_path, errno); + gf_log (this->name, GF_LOG_ERROR, "Unable to open %s," + " errno: %d", cksum_path, errno); ret = -1; goto out; } - snprintf (filepath, sizeof (filepath), "%s/%s", path, - GLUSTERD_VOLUME_INFO_FILE); - snprintf (sort_filepath, sizeof (sort_filepath), "/tmp/%s.XXXXXX", - volinfo->volname); + if (!is_quota_conf) { + snprintf (sort_filepath, sizeof (sort_filepath), + "/tmp/%s.XXXXXX", volinfo->volname); - sort_fd = mkstemp (sort_filepath); - if (sort_fd < 0) { - gf_log (this->name, GF_LOG_ERROR, "Could not generate temp " - "file, reason: %s for volume: %s", strerror (errno), - volinfo->volname); - goto out; - } else { - unlink_sortfile = _gf_true; - } + sort_fd = mkstemp (sort_filepath); + if (sort_fd < 0) { + gf_log (this->name, GF_LOG_ERROR, "Could not generate " + "temp file, reason: %s for volume: %s", + strerror (errno), volinfo->volname); + goto out; + } else { + unlink_sortfile = _gf_true; + } - /* sort the info file, result in sort_filepath */ + /* sort the info file, result in sort_filepath */ - ret = glusterd_sort_and_redirect (filepath, sort_fd); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "sorting info file failed"); - goto out; - } + ret = glusterd_sort_and_redirect (filepath, sort_fd); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "sorting info file " + "failed"); + goto out; + } - ret = close (sort_fd); - if (ret) - goto out; + ret = close (sort_fd); + if (ret) + goto out; + } - ret = get_checksum_for_path (sort_filepath, &cksum); + cksum_path_final = is_quota_conf ? filepath : sort_filepath; + ret = get_checksum_for_path (cksum_path_final, &cksum); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Unable to get checksum" - " for path: %s", sort_filepath); + gf_log (this->name, GF_LOG_ERROR, "unable to get " + "checksum for path: %s", cksum_path_final); goto out; } - - snprintf (buf, sizeof (buf), "%s=%u\n", "info", cksum); - ret = write (fd, buf, strlen (buf)); - - if (ret <= 0) { - ret = -1; - goto out; + if (!is_quota_conf) { + snprintf (buf, sizeof (buf), "%s=%u\n", "info", cksum); + ret = write (fd, buf, strlen (buf)); + if (ret <= 0) { + ret = -1; + goto out; + } } ret = get_checksum_for_file (fd, &cksum); - if (ret) goto out; - volinfo->cksum = cksum; + *cs = cksum; out: if (fd > 0) @@ -1632,6 +1628,54 @@ out: return ret; } +int glusterd_compute_cksum (glusterd_volinfo_t *volinfo, + gf_boolean_t is_quota_conf) +{ + int ret = -1; + uint32_t cs = 0; + char cksum_path[PATH_MAX] = {0,}; + char path[PATH_MAX] = {0,}; + char filepath[PATH_MAX] = {0,}; + glusterd_conf_t *conf = NULL; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + conf = this->private; + GF_ASSERT (conf); + + GLUSTERD_GET_VOLUME_DIR (path, volinfo, conf); + + if (is_quota_conf) { + snprintf (cksum_path, sizeof (cksum_path), "%s/%s", path, + GLUSTERD_VOL_QUOTA_CKSUM_FILE); + snprintf (filepath, sizeof (filepath), "%s/%s", path, + GLUSTERD_VOLUME_QUOTA_CONFIG); + } else { + snprintf (cksum_path, sizeof (cksum_path), "%s/%s", path, + GLUSTERD_CKSUM_FILE); + snprintf (filepath, sizeof (filepath), "%s/%s", path, + GLUSTERD_VOLUME_INFO_FILE); + } + + ret = glusterd_volume_compute_cksum (volinfo, cksum_path, filepath, + is_quota_conf, &cs); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to compute checksum " + "for volume %s", volinfo->volname); + goto out; + } + + if (is_quota_conf) + volinfo->quota_conf_cksum = cs; + else + volinfo->cksum = cs; + + ret = 0; +out: + return ret; +} + int _add_dict_to_prdict (dict_t *this, char *key, data_t *value, void *data) { @@ -1977,6 +2021,18 @@ glusterd_vol_add_quota_conf_to_dict (glusterd_volinfo_t *volinfo, dict_t* load, if (ret) goto out; + snprintf (key, sizeof(key)-1, "volume%d.quota-cksum", vol_idx); + key[sizeof(key)-1] = '\0'; + ret = dict_set_uint32 (load, key, volinfo->quota_conf_cksum); + if (ret) + goto out; + + snprintf (key, sizeof(key)-1, "volume%d.quota-version", vol_idx); + key[sizeof(key)-1] = '\0'; + ret = dict_set_uint32 (load, key, volinfo->quota_conf_version); + if (ret) + goto out; + ret = 0; out: if (fp) @@ -2049,11 +2105,17 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status, glusterd_volinfo_t *volinfo = NULL; char *volname = NULL; uint32_t cksum = 0; + uint32_t quota_cksum = 0; + uint32_t quota_version = 0; int32_t version = 0; + xlator_t *this = NULL; GF_ASSERT (vols); GF_ASSERT (status); + this = THIS; + GF_ASSERT (this); + snprintf (key, sizeof (key), "volume%d.name", count); ret = dict_get_str (vols, key, &volname); if (ret) @@ -2076,7 +2138,7 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status, if (version > volinfo->version) { //Mismatch detected ret = 0; - gf_log ("", GF_LOG_ERROR, "Version of volume %s differ." + gf_log (this->name, GF_LOG_ERROR, "Version of volume %s differ." "local version = %d, remote version = %d on peer %s", volinfo->volname, volinfo->version, version, hostname); *status = GLUSTERD_VOL_COMP_UPDATE_REQ; @@ -2096,17 +2158,66 @@ glusterd_compare_friend_volume (dict_t *vols, int32_t count, int32_t *status, if (cksum != volinfo->cksum) { ret = 0; - gf_log ("", GF_LOG_ERROR, "Cksums of volume %s differ." + gf_log (this->name, GF_LOG_ERROR, "Cksums of volume %s differ." " local cksum = %u, remote cksum = %u on peer %s", volinfo->volname, volinfo->cksum, cksum, hostname); *status = GLUSTERD_VOL_COMP_RJT; goto out; } + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.quota-version", count); + ret = dict_get_uint32 (vols, key, "a_version); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "quota-version key absent for" + " volume %s in peer %s's response", volinfo->volname, + hostname); + ret = 0; + } else { + if (quota_version > volinfo->quota_conf_version) { + //Mismatch detected + ret = 0; + gf_log (this->name, GF_LOG_ERROR, "Quota configuration " + "versions of volume %s differ. " + "local version = %d, remote version = %d " + "on peer %s", volinfo->volname, + volinfo->quota_conf_version, quota_version, + hostname); + *status = GLUSTERD_VOL_COMP_UPDATE_REQ; + goto out; + } else if (quota_version < volinfo->quota_conf_version) { + *status = GLUSTERD_VOL_COMP_SCS; + goto out; + } + } + + //Now, versions are same, compare cksums. + // + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "volume%d.quota-cksum", count); + ret = dict_get_uint32 (vols, key, "a_cksum); + if (ret) { + gf_log (this->name, GF_LOG_DEBUG, "quota checksum absent for " + "volume %s in peer %s's response", volinfo->volname, + hostname); + ret = 0; + } else { + if (quota_cksum != volinfo->quota_conf_cksum) { + ret = 0; + gf_log (this->name, GF_LOG_ERROR, "Cksums of quota " + "configurations of volume %s differ. " + "local cksum = %u, remote cksum = %u on " + "peer %s", volinfo->volname, + volinfo->quota_conf_cksum, quota_cksum, + hostname); + *status = GLUSTERD_VOL_COMP_RJT; + goto out; + } + } *status = GLUSTERD_VOL_COMP_SCS; out: - gf_log ("", GF_LOG_DEBUG, "Returning with ret: %d, status: %d", + gf_log (this->name, GF_LOG_DEBUG, "Returning with ret: %d, status: %d", ret, *status); return ret; } @@ -2565,8 +2676,10 @@ glusterd_import_quota_conf (dict_t *vols, int vol_idx, char key[PATH_MAX] = {0}; char *gfid_str = NULL; - if (!glusterd_is_volume_quota_enabled (new_volinfo)) + if (!glusterd_is_volume_quota_enabled (new_volinfo)) { + (void) glusterd_clean_up_quota_store (new_volinfo); return 0; + } ret = glusterd_store_create_quota_conf_sh_on_absence (new_volinfo); if (ret) @@ -2583,6 +2696,19 @@ glusterd_import_quota_conf (dict_t *vols, int vol_idx, goto out; } + snprintf (key, sizeof (key)-1, "volume%d.quota-cksum", vol_idx); + key[sizeof(key)-1] = '\0'; + ret = dict_get_uint32 (vols, key, &new_volinfo->quota_conf_cksum); + if (ret) + gf_log (THIS->name, GF_LOG_DEBUG, "Failed to get quota cksum"); + + snprintf (key, sizeof (key)-1, "volume%d.quota-version", vol_idx); + key[sizeof(key)-1] = '\0'; + ret = dict_get_uint32 (vols, key, &new_volinfo->quota_conf_version); + if (ret) + gf_log (THIS->name, GF_LOG_DEBUG, "Failed to get quota " + "version"); + snprintf (key, sizeof (key)-1, "volume%d.gfid-count", vol_idx); key[sizeof(key)-1] = '\0'; ret = dict_get_int32 (vols, key, &gfid_count); @@ -2608,13 +2734,20 @@ glusterd_import_quota_conf (dict_t *vols, int vol_idx, ret = gf_store_rename_tmppath (new_volinfo->quota_conf_shandle); -out: - if (tmp_fp) { - fclose (tmp_fp); + ret = 0; - } else if (fd >= 0) { +out: + if (fd != -1) close (fd); + if (!ret) { + ret = glusterd_compute_cksum (new_volinfo, _gf_true); + if (ret) + goto out; + + ret = glusterd_store_save_quota_version_and_cksum (new_volinfo); + if (ret) + goto out; } if (ret && (fd > 0)) { @@ -8126,3 +8259,33 @@ glusterd_validate_and_set_gfid (dict_t *op_ctx, dict_t *req_dict, out: return ret; } + +void +glusterd_clean_up_quota_store (glusterd_volinfo_t *volinfo) +{ + char voldir[PATH_MAX] = {0,}; + char quota_confpath[PATH_MAX] = {0,}; + char cksum_path[PATH_MAX] = {0,}; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + + this = THIS; + GF_ASSERT (this); + conf = this->private; + GF_ASSERT (conf); + + GLUSTERD_GET_VOLUME_DIR (voldir, volinfo, conf); + + snprintf (quota_confpath, sizeof (quota_confpath), "%s/%s", voldir, + GLUSTERD_VOLUME_QUOTA_CONFIG); + snprintf (cksum_path, sizeof (cksum_path), "%s/%s", voldir, + GLUSTERD_VOL_QUOTA_CKSUM_FILE); + + unlink (quota_confpath); + unlink (cksum_path); + + gf_store_handle_destroy (volinfo->quota_conf_shandle); + volinfo->quota_conf_shandle = NULL; + volinfo->quota_conf_version = 0; + +} |