diff options
author | vmallika <vmallika@redhat.com> | 2015-05-22 14:04:31 +0530 |
---|---|---|
committer | Krishnan Parthasarathi <kparthas@redhat.com> | 2015-05-28 18:57:37 -0700 |
commit | b7f05e64f615a12e6487eab64544b8f92a6037ae (patch) | |
tree | 3610be7c1a6ddeddc061574d693f6af2c5aa88e9 /xlators/mgmt | |
parent | 19818254fa7d2b227d212e0a62c37846aef3fc24 (diff) |
quota: quota.conf backward compatibility fix
In release-3.7 the format of quota.conf is changed.
There is a backward compatibility issues during upgrade
1) There can be an issue when peer sync between node-3.6 and node-3.7
2) If the user sets/removes limit, there is will different format of
file in node-3.6 and node-3.7
This patch fixes the issue:
1) restrict the user to execute command quota enable, limit-usage, remove
2) write quota.conf in older format if op-version is less than 3.6
Change-Id: Ib76f5a0a85394642159607a105cacda743e7d26b
BUG: 1223739
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/10889
Tested-by: NetBSD Build System
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
Diffstat (limited to 'xlators/mgmt')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 88 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 77 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.h | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 5 |
4 files changed, 163 insertions, 13 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 7176e683fd9..ff6ece9bbca 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -87,6 +87,15 @@ glusterd_is_quota_supported (int32_t type, char **op_errstr) (type > GF_QUOTA_OPTION_TYPE_VERSION_OBJECTS)) goto out; + /* Quota Operations that change quota.conf shouldn't + * be allowed as the quota.conf format changes in 3.7 + */ + if ((conf->op_version < GD_OP_VERSION_3_7_0) && + (type == GF_QUOTA_OPTION_TYPE_ENABLE || + type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE || + type == GF_QUOTA_OPTION_TYPE_REMOVE)) + goto out; + supported = _gf_true; out: @@ -635,14 +644,60 @@ glusterd_update_quota_conf_version (glusterd_volinfo_t *volinfo) * and continue the search. */ static gf_boolean_t -glusterd_find_gfid_match (uuid_t gfid, char gfid_type, unsigned char *buf, - size_t bytes_read, int opcode, - size_t *write_byte_count) +glusterd_find_gfid_match_3_6 (uuid_t gfid, unsigned char *buf, + size_t bytes_read, int opcode, + size_t *write_byte_count) { int gfid_index = 0; int shift_count = 0; unsigned char tmp_buf[17] = {0,}; - char type = 0; + + /* This function if for backward compatibility */ + + while (gfid_index != bytes_read) { + memcpy ((void *)tmp_buf, (void *)&buf[gfid_index], 16); + if (!gf_uuid_compare (gfid, tmp_buf)) { + if (opcode == GF_QUOTA_OPTION_TYPE_REMOVE) { + shift_count = bytes_read - (gfid_index + 16); + memmove ((void *)&buf[gfid_index], + (void *)&buf[gfid_index+16], + shift_count); + *write_byte_count = bytes_read - 16; + } else { + *write_byte_count = bytes_read; + } + return _gf_true; + } else { + gfid_index += 16; + } + } + if (gfid_index == bytes_read) + *write_byte_count = bytes_read; + + return _gf_false; +} + +static gf_boolean_t +glusterd_find_gfid_match (uuid_t gfid, char gfid_type, unsigned char *buf, + size_t bytes_read, int opcode, + size_t *write_byte_count) +{ + int gfid_index = 0; + int shift_count = 0; + unsigned char tmp_buf[17] = {0,}; + char type = 0; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + + this = THIS; + GF_VALIDATE_OR_GOTO ("glusterd", this, out); + + conf = this->private; + GF_VALIDATE_OR_GOTO (this->name, conf, out); + + if (conf->op_version < GD_OP_VERSION_3_7_0) + return glusterd_find_gfid_match_3_6 (gfid, buf, bytes_read, + opcode, write_byte_count); while (gfid_index != bytes_read) { memcpy ((void *)tmp_buf, (void *)&buf[gfid_index], 16); @@ -667,6 +722,8 @@ glusterd_find_gfid_match (uuid_t gfid, char gfid_type, unsigned char *buf, if (gfid_index == bytes_read) *write_byte_count = bytes_read; +out: + return _gf_false; } @@ -737,7 +794,7 @@ glusterd_store_quota_conf_upgrade (glusterd_volinfo_t *volinfo) if (ret) goto out; - ret = quota_conf_write_header (fd); + ret = glusterd_quota_conf_write_header (fd); if (ret) goto out; @@ -748,7 +805,7 @@ glusterd_store_quota_conf_upgrade (glusterd_volinfo_t *volinfo) else if (ret < 0) goto out; - ret = quota_conf_write_gfid (fd, gfid, + ret = glusterd_quota_conf_write_gfid (fd, gfid, GF_QUOTA_CONF_TYPE_USAGE); if (ret < 0) goto out; @@ -803,6 +860,7 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, glusterd_conf_t *conf = NULL; float version = 0.0f; char type = 0; + int quota_conf_line_sz = 16; this = THIS; GF_ASSERT (this); @@ -821,7 +879,8 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, if (ret) goto out; - if (version < 1.2f) { + if (version < 1.2f && conf->op_version >= GD_OP_VERSION_3_7_0) { + /* Upgrade quota.conf file to newer format */ close (conf_fd); ret = glusterd_store_quota_conf_upgrade(volinfo); if (ret) @@ -838,13 +897,20 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, goto out; } + /* If op-ver is gt 3.7, then quota.conf will be upgraded, and 17 bytes + * storted in the new format. 16 bytes uuid and + * 1 byte type (usage/object) + */ + if (conf->op_version >= GD_OP_VERSION_3_7_0) + quota_conf_line_sz++; + fd = gf_store_mkstemp (volinfo->quota_conf_shandle); if (fd < 0) { ret = -1; goto out; } - ret = quota_conf_write_header (fd); + ret = glusterd_quota_conf_write_header (fd); if (ret) goto out; @@ -882,7 +948,7 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, is_file_empty = _gf_true; break; } - if ((bytes_read % 17) != 0) { + if ((bytes_read % quota_conf_line_sz) != 0) { gf_log (this->name, GF_LOG_ERROR, "quota.conf " "corrupted"); ret = -1; @@ -915,7 +981,7 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, switch (opcode) { case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE: if (!found) { - ret = quota_conf_write_gfid (fd, gfid, + ret = glusterd_quota_conf_write_gfid (fd, gfid, GF_QUOTA_CONF_TYPE_USAGE); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, @@ -929,7 +995,7 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, break; case GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS: if (!found) { - ret = quota_conf_write_gfid (fd, gfid, + ret = glusterd_quota_conf_write_gfid (fd, gfid, GF_QUOTA_CONF_TYPE_OBJECTS); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index c3cb4e490d9..cb312ae9a63 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -41,6 +41,7 @@ #include "rpc-clnt.h" #include "common-utils.h" +#include "quota-common-utils.h" #include <sys/resource.h> #include <inttypes.h> @@ -4301,3 +4302,79 @@ out: gf_store_handle_destroy (shandle); return ret; } + +int32_t +glusterd_quota_conf_write_header (int fd) +{ + int header_len = 0; + int ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + + this = THIS; + GF_VALIDATE_OR_GOTO ("quota", this, out); + + conf = this->private; + GF_VALIDATE_OR_GOTO (this->name, conf, out); + + + if (conf->op_version < GD_OP_VERSION_3_7_0) { + header_len = strlen (QUOTA_CONF_HEADER_1_1); + ret = gf_nwrite (fd, QUOTA_CONF_HEADER_1_1, header_len); + } else { + header_len = strlen (QUOTA_CONF_HEADER); + ret = gf_nwrite (fd, QUOTA_CONF_HEADER, header_len); + } + + if (ret != header_len) { + ret = -1; + goto out; + } + + ret = 0; + +out: + if (ret < 0) + gf_log_callingfn ("quota", GF_LOG_ERROR, "failed to write " + "header to a quota conf"); + + return ret; +} + +int32_t +glusterd_quota_conf_write_gfid (int fd, void *buf, char type) +{ + int ret = -1; + xlator_t *this = NULL; + glusterd_conf_t *conf = NULL; + + this = THIS; + GF_VALIDATE_OR_GOTO ("quota", this, out); + + conf = this->private; + GF_VALIDATE_OR_GOTO (this->name, conf, out); + + + ret = gf_nwrite (fd, buf, 16); + if (ret != 16) { + ret = -1; + goto out; + } + + if (conf->op_version >= GD_OP_VERSION_3_7_0) { + ret = gf_nwrite (fd, &type, 1); + if (ret != 1) { + ret = -1; + goto out; + } + } + + ret = 0; + +out: + if (ret < 0) + gf_log_callingfn ("quota", GF_LOG_ERROR, "failed to write " + "gfid %s to a quota conf", uuid_utoa (buf)); + + return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index 0a243d399a1..5ba0add32c3 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -181,4 +181,10 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap); int glusterd_restore_op_version (xlator_t *this); +int32_t +glusterd_quota_conf_write_header (int fd); + +int32_t +glusterd_quota_conf_write_gfid (int fd, void *buf, char type); + #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 387e0a6e8ae..f90abc19b2e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -2998,7 +2998,7 @@ glusterd_import_quota_conf (dict_t *peer_data, int vol_idx, if (ret) goto out; - ret = quota_conf_write_header (fd); + ret = glusterd_quota_conf_write_header (fd); if (ret) goto out; @@ -3018,7 +3018,8 @@ glusterd_import_quota_conf (dict_t *peer_data, int vol_idx, gfid_type = GF_QUOTA_CONF_TYPE_USAGE; gf_uuid_parse (gfid_str, gfid); - ret = quota_conf_write_gfid (fd, gfid, (char)gfid_type); + ret = glusterd_quota_conf_write_gfid (fd, gfid, + (char)gfid_type); if (ret < 0) { gf_log (this->name, GF_LOG_CRITICAL, "Unable to write " "gfid %s into quota.conf for %s", gfid_str, |