From: Timo Sirainen Date: Tue, 7 Feb 2017 16:26:50 +0000 (+0200) Subject: quota: When executing quota_warning/over_flag script, log the reason why. X-Git-Tag: 2.3.0.rc1~2157 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f97866381675fe12cdab0f2d56a059fe7b88457a;p=thirdparty%2Fdovecot%2Fcore.git quota: When executing quota_warning/over_flag script, log the reason why. --- diff --git a/src/plugins/quota/quota-private.h b/src/plugins/quota/quota-private.h index 2048beb026..01eb5eb888 100644 --- a/src/plugins/quota/quota-private.h +++ b/src/plugins/quota/quota-private.h @@ -208,7 +208,8 @@ int quota_root_parse_grace(struct quota_root_settings *root_set, const char *value, const char **error_r); bool quota_warning_match(const struct quota_warning_rule *w, uint64_t bytes_before, uint64_t bytes_current, - uint64_t count_before, uint64_t count_current); + uint64_t count_before, uint64_t count_current, + const char **reason_r); bool quota_transaction_is_over(struct quota_transaction_context *ctx, uoff_t size); int quota_transaction_set_limits(struct quota_transaction_context *ctx); diff --git a/src/plugins/quota/quota-util.c b/src/plugins/quota/quota-util.c index 422d095704..3d783154bc 100644 --- a/src/plugins/quota/quota-util.c +++ b/src/plugins/quota/quota-util.c @@ -384,18 +384,44 @@ int quota_root_parse_grace(struct quota_root_settings *root_set, bool quota_warning_match(const struct quota_warning_rule *w, uint64_t bytes_before, uint64_t bytes_current, - uint64_t count_before, uint64_t count_current) + uint64_t count_before, uint64_t count_current, + const char **reason_r) { #define QUOTA_EXCEEDED(before, current, limit) \ ((before) < (uint64_t)(limit) && (current) >= (uint64_t)(limit)) if (!w->reverse) { /* over quota (default) */ - return QUOTA_EXCEEDED(bytes_before, bytes_current, w->rule.bytes_limit) || - QUOTA_EXCEEDED(count_before, count_current, w->rule.count_limit); + if (QUOTA_EXCEEDED(bytes_before, bytes_current, w->rule.bytes_limit)) { + *reason_r = t_strdup_printf("bytes=%llu -> %llu over limit %llu", + (unsigned long long)bytes_before, + (unsigned long long)bytes_current, + (unsigned long long)w->rule.bytes_limit); + return TRUE; + } + if (QUOTA_EXCEEDED(count_before, count_current, w->rule.count_limit)) { + *reason_r = t_strdup_printf("count=%llu -> %llu over limit %llu", + (unsigned long long)count_before, + (unsigned long long)count_current, + (unsigned long long)w->rule.count_limit); + return TRUE; + } } else { - return QUOTA_EXCEEDED(bytes_current, bytes_before, w->rule.bytes_limit) || - QUOTA_EXCEEDED(count_current, count_before, w->rule.count_limit); + if (QUOTA_EXCEEDED(bytes_current, bytes_before, w->rule.bytes_limit)) { + *reason_r = t_strdup_printf("bytes=%llu -> %llu below limit %llu", + (unsigned long long)bytes_before, + (unsigned long long)bytes_current, + (unsigned long long)w->rule.bytes_limit); + return TRUE; + } + if (QUOTA_EXCEEDED(count_current, count_before, w->rule.count_limit)) { + *reason_r = t_strdup_printf("count=%llu -> %llu below limit %llu", + (unsigned long long)count_before, + (unsigned long long)count_current, + (unsigned long long)w->rule.count_limit); + return TRUE; + } } + return FALSE; } bool quota_transaction_is_over(struct quota_transaction_context *ctx, diff --git a/src/plugins/quota/quota.c b/src/plugins/quota/quota.c index 7044c60642..143783162c 100644 --- a/src/plugins/quota/quota.c +++ b/src/plugins/quota/quota.c @@ -877,7 +877,7 @@ int quota_transaction_set_limits(struct quota_transaction_context *ctx) } static void quota_warning_execute(struct quota_root *root, const char *cmd, - const char *last_arg) + const char *last_arg, const char *reason) { const char *socket_path, *const *args, *error, *scheme, *ptr; @@ -889,7 +889,7 @@ static void quota_warning_execute(struct quota_root *root, const char *cmd, restrict_access_init(&set.restrict_set); if (root->quota->set->debug) - i_debug("quota: Executing warning: %s", cmd); + i_debug("quota: Executing warning: %s (because %s)", cmd, reason); args = t_strsplit_spaces(cmd, " "); if (last_arg != NULL) { @@ -938,6 +938,7 @@ static void quota_warnings_execute(struct quota_transaction_context *ctx, unsigned int i, count; uint64_t bytes_current, bytes_before, bytes_limit; uint64_t count_current, count_before, count_limit; + const char *reason; warnings = array_get_modifiable(&root->set->warning_rules, &count); if (count == 0) @@ -955,8 +956,10 @@ static void quota_warnings_execute(struct quota_transaction_context *ctx, for (i = 0; i < count; i++) { if (quota_warning_match(&warnings[i], bytes_before, bytes_current, - count_before, count_current)) { - quota_warning_execute(root, warnings[i].command, NULL); + count_before, count_current, + &reason)) { + quota_warning_execute(root, warnings[i].command, + NULL, reason); break; } } @@ -1092,8 +1095,11 @@ static void quota_over_flag_check_root(struct quota_root *root) if (cur_overquota != root->quota_over_flag_status) { name = t_strconcat(root->set->set_name, "_over_script", NULL); overquota_script = mail_user_plugin_getenv(root->quota->user, name); - if (overquota_script != NULL) - quota_warning_execute(root, overquota_script, root->quota_over_flag); + if (overquota_script != NULL) { + quota_warning_execute(root, overquota_script, + root->quota_over_flag, + "quota_over_flag mismatch"); + } } }