summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2015-05-22 14:04:31 +0530
committerKrishnan Parthasarathi <kparthas@redhat.com>2015-05-28 18:57:37 -0700
commitb7f05e64f615a12e6487eab64544b8f92a6037ae (patch)
tree3610be7c1a6ddeddc061574d693f6af2c5aa88e9 /xlators
parent19818254fa7d2b227d212e0a62c37846aef3fc24 (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')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.c88
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c77
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c5
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,