diff options
author | Varun Shastry <vshastry@redhat.com> | 2013-04-19 12:34:51 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2013-07-29 18:25:24 +0530 |
commit | 3f9956ffb6e0faec1c4eea18916411d22a7e51d8 (patch) | |
tree | 8176256ff517ae2cefad7408c925567b63b696b9 /libglusterfs | |
parent | e9c583598b8ad58bbda15759067ff57eca619e95 (diff) |
features/quota: Improvements to quota
Old implementation
* Client side implementation of quota
- Not secure
- Increased traffic in updating the ctx
New Implementation
* 2 stages of quota implementation is done: Soft and hard quota
Upon reaching soft quota limit on the directory it logs/alerts in the quota
daemon log (ie DEFAULT_LOG_DIR/quotad.log) and no more writes allowed after
hard quota limit. After reaching the soft-limit the daemon alerts the
user/admin repeatively for every 'alert-time', which is configurable.
* Quota is moved to server-side.
There will be 2 quota xlators
i. Quota Server
It takes care of the enforcing the quota and maintains the context
specific to the brick. Since this doesn't have the complete picture of
the cluster, cluster wide usage is updated from the quota daemon. This
updated context is saved and used for the enforcement.
It updates its context by searching the QUOTA_UPDATE_KEY from the dict
in the setxattr call, and is updated from nowhere else.
The quota is always loaded in the server graph and is by passed if the
feature is not enabled.
Options specific to quota-server:
server-quota - Specifies whether the features is on/off. It is used
to by pass the quota if turned off.
deem-statfs - If set to on, it takes quota limits into
consideration while estimating fs size. (df command)
ii. Quota Daemon
This is the new xlator introduced with this patch. Its the
*gluster client* process with no mount point, started upon enabling
quota or restarting the volume. This is a single process for all the
volumes in the cluster. Its volfile stored in
GLUSTERD_DEFAULT_WORKI_DIR/quotad/quotad.vol.
It queries for the sizes on all the bricks, aggregates the size and
sends back the updated size, periodically. The timeout between
successive updation is configurable and typically/by default more for
below-soft-quota usage and less for above-soft-quota usage. It
maintains the timeout inside the limit structure based on the usage;
below soft limit and above soft limit.
There will be thread running per volume which iterates through the list
and decides whether the size to be queried in the current iteration
based on its timeout. It takes the next iteration time taking the least
of the timeouts in the list of entries.
Maintains a separate inode table for each volume in the quotad. In the
first iteration it builds the table for quota-dirs (dirs on which limit
is set) and its components.
Options specific to quotad:
hard-timeout - Timeout for updation of usage to the quota-server
when the usage is crosses the soft-limit.
soft-timeout - Timeout for the updation of usage to the
quota-server when the usage is below soft-limit.
alert-time - Frequency of logging after the usage reached
soft limit.
Options common to both:
default-soft-limit - This is used when individual paths are not
configured with soft-limit and default value of
this option is 90% of the hard-limit.
limit-set - String containing all the limits.
Thus in the current implementation we'll have 2 quota xlators: one in server
graph and one in trusted client (quota daemon) of which the sole
purpose will be to aggregate the quota size xattrs from all the bricks and
send the same to server quota xlator.
* Changes in glusterd and CLI
A single volfile is created for all the volumes, similar to nfs volfile.
All files related to quota client (volfile, pid etc) are stored in
GLUSTERD_DEFAULT_WORK_DIR/quotad/.
The new pattern of the quota limit stores in
limit-set = <single-dir-limit>[,<single-dir-limit>]
single-dir-limit = <abs-path>:<hard-limit>[:<soft-limit-in-percent>]
It also introduces new options:
volume quota <VOLNAME> {enable|disable|list [<path> ...]|remove <path>| default-soft-limit <percent>} |
volume quota <VOLNAME> {limit-usage <path> <size> |soft-limit <path> <percent>} |
volume quota <VOLNAME> {alert-time|soft-timeout|hard-timeout} {<time>}
Credit:
Raghavendra Bhat <rabhat@redhat.com>
Varun Shastry <vshastry@redhat.com>
Shishir Gowda <sgowda@redhat.com>
Kruthika Dhananjay <kdhananj@redhat.com>
Brian Foster <bfoster@redhat.com>
Krishnan Parthasarathi <kparthas@redhat.com>
Change-Id: I16ec5be0c2faaf42b14034b9ccaf17796adef082
BUG: 969461
Signed-off-by: Varun Shastry <vshastry@redhat.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/common-utils.c | 103 | ||||
-rw-r--r-- | libglusterfs/src/common-utils.h | 8 | ||||
-rw-r--r-- | libglusterfs/src/inode.h | 3 | ||||
-rw-r--r-- | libglusterfs/src/options.c | 3 | ||||
-rw-r--r-- | libglusterfs/src/options.h | 1 | ||||
-rw-r--r-- | libglusterfs/src/xlator.c | 1 |
6 files changed, 116 insertions, 3 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 6eb886b3..bec3249f 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -787,12 +787,44 @@ gf_string2time (const char *str, uint32_t *n) if (errno == 0) errno = old_errno; - if (!((tail[0] == '\0') || + if (((tail[0] == '\0') || ((tail[0] == 's') && (tail[1] == '\0')) || ((tail[0] == 's') && (tail[1] == 'e') && (tail[2] == 'c') && (tail[3] == '\0')))) + goto out; + + else if (((tail[0] == 'm') && (tail[1] == '\0')) || + ((tail[0] == 'm') && (tail[1] == 'i') && + (tail[2] == 'n') && (tail[3] == '\0'))) { + value = value * GF_MINUTE_IN_SECONDS; + goto out; + } + + else if (((tail[0] == 'h') && (tail[1] == '\0')) || + ((tail[0] == 'h') && (tail[1] == 'r') && + (tail[2] == '\0'))) { + value = value * GF_HOUR_IN_SECONDS; + goto out; + } + + else if (((tail[0] == 'd') && (tail[1] == '\0')) || + ((tail[0] == 'd') && (tail[1] == 'a') && + (tail[2] == 'y') && (tail[3] == 's') && + (tail[4] == '\0'))) { + value = value * GF_DAY_IN_SECONDS; + goto out; + } + + else if (((tail[0] == 'w') && (tail[1] == '\0')) || + ((tail[0] == 'w') && (tail[1] == 'k') && + (tail[2] == '\0'))) { + value = value * GF_WEEK_IN_SECONDS; + goto out; + } else { return -1; + } +out: *n = value; return 0; @@ -2283,6 +2315,9 @@ gf_canonicalize_path (char *path) if (!path || *path != '/') goto out; + if (!strcmp (path, "/")) + return 0; + tmppath = gf_strdup (path); if (!tmppath) goto out; @@ -2807,3 +2842,69 @@ out: } +int +gf_get_soft_limit (char *limit, char **soft_limit) +{ + int colon_count = 0; + int i = 0; + int len = 0; + char *sl = NULL; + + len = strlen (limit); + for (i = 0; i < len; i++) { + if (limit[i] == ':') + colon_count++; + if (colon_count == 2) + break; + } + + if (colon_count != 2) { + gf_log ("common-utils", GF_LOG_DEBUG, "Soft-limit absent"); + return 0; + } + + sl = GF_CALLOC (len - i, sizeof (char), gf_common_mt_char); + if (!sl) + return -1; + strncpy (sl, &limit[i+1], len - i - 1); + *soft_limit = sl; + + return 1; +} + +int +gf_get_hard_limit (char *limit, char **hard_limit) +{ + int i = 0; + int hlbegin = 0; + int len = 0; + char *hl = NULL; + + len = strlen (limit); + + for (i = 0; i < len; i++) { + if (limit[i] == ':') + break; + } + + if (i == len) { + gf_log ("common-utils", GF_LOG_ERROR, "Hard limit not found"); + return -1; + } + + hlbegin = i + 1; + i++; + + while ((limit[i] != '\0') && (limit[i] != ':')) { + i++; + } + + hl = GF_CALLOC (i - hlbegin + 1, sizeof (char), gf_common_mt_char); + if (!hl) + return -1; + + strncpy (hl, &limit[hlbegin], i - hlbegin); + *hard_limit = hl; + + return 0; +} diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index bf41444d..f8db8e30 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -81,6 +81,11 @@ void trap (void); #define GF_NFS3_PORT 2049 #define GF_CLIENT_PORT_CEILING 1024 +#define GF_MINUTE_IN_SECONDS 60 +#define GF_HOUR_IN_SECONDS (60*60) +#define GF_DAY_IN_SECONDS (24*60*60) +#define GF_WEEK_IN_SECONDS (7*24*60*60) + enum _gf_boolean { _gf_false = 0, @@ -587,4 +592,7 @@ gf_boolean_t gf_is_local_addr (char *hostname); gf_boolean_t gf_is_same_address (char *host1, char *host2); void md5_wrapper(const unsigned char *data, size_t len, char *md5); +int gf_get_soft_limit (char *limit, char **soft_limit); +int gf_get_hard_limit (char *limit, char **hard_limit); + #endif /* _COMMON_UTILS_H */ diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h index cf766a31..89a5f196 100644 --- a/libglusterfs/src/inode.h +++ b/libglusterfs/src/inode.h @@ -140,6 +140,9 @@ inode_rename (inode_table_t *table, inode_t *olddir, const char *oldname, inode_t *newdir, const char *newname, inode_t *inode, struct iatt *stbuf); +dentry_t * +__dentry_grep (inode_table_t *table, inode_t *parent, const char *name); + inode_t * inode_grep (inode_table_t *table, inode_t *parent, const char *name); diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index 842b6413..31e5a681 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -1110,7 +1110,7 @@ DEFINE_INIT_OPT(gf_boolean_t, bool, gf_string2boolean); DEFINE_INIT_OPT(xlator_t *, xlator, xl_by_name); DEFINE_INIT_OPT(char *, path, pass); DEFINE_INIT_OPT(double, double, gf_string2double); - +DEFINE_INIT_OPT(uint32_t, time, gf_string2time); DEFINE_RECONF_OPT(char *, str, pass); @@ -1125,3 +1125,4 @@ DEFINE_RECONF_OPT(gf_boolean_t, bool, gf_string2boolean); DEFINE_RECONF_OPT(xlator_t *, xlator, xl_by_name); DEFINE_RECONF_OPT(char *, path, pass); DEFINE_RECONF_OPT(double, double, gf_string2double); +DEFINE_RECONF_OPT(uint32_t, time, gf_string2time); diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h index e2a25baa..71a11c06 100644 --- a/libglusterfs/src/options.h +++ b/libglusterfs/src/options.h @@ -114,6 +114,7 @@ DECLARE_INIT_OPT(gf_boolean_t, bool); DECLARE_INIT_OPT(xlator_t *, xlator); DECLARE_INIT_OPT(char *, path); DECLARE_INIT_OPT(double, double); +DECLARE_INIT_OPT(uint32_t, time); #define DEFINE_INIT_OPT(type_t, type, conv) \ diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index b1c090c1..57360e1d 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -655,7 +655,6 @@ loc_copy (loc_t *dst, loc_t *src) uuid_copy (dst->gfid, src->gfid); uuid_copy (dst->pargfid, src->pargfid); - uuid_copy (dst->gfid, src->gfid); if (src->inode) dst->inode = inode_ref (src->inode); |