diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-quota.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 184 |
1 files changed, 153 insertions, 31 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 24bd41ad..e67208cf 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -580,6 +580,8 @@ glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr) if (ret) goto out; + (void) glusterd_clean_up_quota_store (volinfo); + ret = 0; out: if (ret && op_errstr && !*op_errstr) @@ -671,6 +673,47 @@ out: return ret; } +#define QUOTA_CONF_HEADER \ + "GlusterFS Quota conf | version: v%d.%d\n" + +static int +glusterd_store_quota_conf_skip_header (xlator_t *this, int fd) +{ + char buf[PATH_MAX] = {0,}; + + snprintf (buf, sizeof(buf)-1, QUOTA_CONF_HEADER, 1, 1); + return gf_skip_header_section (fd, strlen (buf)); +} + +static int +glusterd_store_quota_conf_stamp_header (xlator_t *this, int fd) +{ + char buf[PATH_MAX] = {0,}; + int buf_len = 0; + ssize_t ret = -1; + ssize_t written = 0; + + snprintf (buf, sizeof(buf)-1, QUOTA_CONF_HEADER, 1, 1); + buf_len = strlen (buf); + for (written = 0; written != buf_len; written += ret) { + ret = write (fd, buf + written, buf_len - written); + if (ret == -1) { + goto out; + } + } + + ret = 0; +out: + return ret; +} + +static int +glusterd_update_quota_conf_version (glusterd_volinfo_t *volinfo) +{ + volinfo->quota_conf_version++; + return 0; +} + static int glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, char *gfid_str, int opcode, char **op_errstr) @@ -679,13 +722,13 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, int count = 0; xlator_t *this = NULL; glusterd_conf_t *conf = NULL; - char buf[256] = {0,}; + unsigned char buf[16] = {0,}; int fd = -1; - FILE *conf_filep = NULL; - FILE *tmp_filep = NULL; + int conf_fd = -1; + size_t entry_sz = 16; uuid_t gfid = {0,}; - uuid_t gfid_iter = {0,}; gf_boolean_t found = _gf_false; + gf_boolean_t modified = _gf_false; this = THIS; @@ -702,23 +745,67 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, ret = -1; goto out; } - tmp_filep = fdopen (fd, "r+"); - conf_filep = fopen (volinfo->quota_conf_shandle->path, "r"); - if (conf_filep == NULL) { + conf_fd = open (volinfo->quota_conf_shandle->path, O_RDONLY); + if (conf_fd == -1) { ret = -1; goto out; } - while (fscanf (conf_filep, "%s", buf) != EOF) { - count++; - uuid_parse (buf, gfid_iter); + ret = glusterd_store_quota_conf_skip_header (this, conf_fd); + if (ret) { + goto out; + } - if (uuid_compare (gfid, gfid_iter)) - fprintf (tmp_filep, "%s\n", buf); - else + ret = glusterd_store_quota_conf_stamp_header (this, fd); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to add header to tmp " + "file."); + goto out; + } + //gfid is stored as 16 bytes of 'raw' data + entry_sz = 16; + for (;;) { + ret = read (conf_fd, (void*)&buf, entry_sz) ; + if (ret <= 0) { + //Finished reading all entries in the conf file + break; + } + if (ret != 16) { + //This should never happen. We must have a multiple of + //entry_sz bytes in our configuration file. + gf_log (this->name, GF_LOG_CRITICAL, "Quota " + "configuration store may be corrupt."); + ret = -1; + goto out; + } + count++; + if (uuid_compare (gfid, buf)) { + /*If the gfids don't match, write @buf into tmp file. */ + ret = write (fd, (void*) buf, entry_sz); + if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "write %s into quota configuration.", + uuid_utoa (buf)); + goto out; + } + } else { + /*If a match is found, write @buf into tmp file for + * limit-usage only. + */ + if (opcode == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) { + ret = write (fd, (void *) buf, entry_sz); + if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to write %s into quota " + "configuration.", + uuid_utoa (buf)); + goto out; + } + } found = _gf_true; + } } switch (opcode) { @@ -727,15 +814,24 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, * count = 0 implies that the conf file is empty. * In this case, we directly go ahead and write gfid_str * into the tmp file. - * If count is non-zero and found is false, then we - * append gfid_str to the end of the file. - * If count is non-zero and found is true, then again + * If count is non-zero and found is false, limit is + * being set on a gfid for the first time. So * append gfid_str to the end of the file. - * - * In short, in all of the above cases, append gfid_str - * to the end of the file. */ - fprintf (tmp_filep, "%s\n", gfid_str); + if ((count == 0) || + ((count > 0) && (found == _gf_false))) { + memcpy (buf, gfid, 16); + ret = write (fd, (void *) buf, entry_sz); + if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, + "Failed to write %s into quota " + "configuration.", + uuid_utoa (buf)); + goto out; + } + modified = _gf_true; + } + break; case GF_QUOTA_OPTION_TYPE_REMOVE: @@ -757,12 +853,15 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, goto out; } else { if (!found) { - gf_asprintf (op_errstr, "Error. gfid %s for " - "path %s not found in store", - gfid_str, path); - ret = -1; - goto out; + gf_asprintf (op_errstr, "Error. gfid %s" + " for path %s not found in" + " store", gfid_str, path); + ret = -1; + goto out; + } else { + modified = _gf_true; } + } break; @@ -771,17 +870,40 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path, break; } + if (modified) + glusterd_update_quota_conf_version (volinfo); + ret = 0; out: - if (conf_filep) - fclose (conf_filep); - if (tmp_filep) - fclose (tmp_filep); + if (conf_fd != -1) { + close (conf_fd); + } + + if (fd != -1) { + close (fd); + } - if (ret && (fd > 0)) + if (ret && (fd > 0)) { gf_store_unlink_tmppath (volinfo->quota_conf_shandle); - else if (!ret) + } else if (!ret) { ret = gf_store_rename_tmppath (volinfo->quota_conf_shandle); + if (modified) { + ret = glusterd_compute_cksum (volinfo, _gf_true); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "compute cksum for quota conf file"); + goto out; + } + + ret = glusterd_store_save_quota_version_and_cksum + (volinfo); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "store quota version and cksum"); + goto out; + } + } + } return ret; } |