]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quota: When executing quota_warning/over_flag script, log the reason why.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 7 Feb 2017 16:26:50 +0000 (18:26 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 7 Feb 2017 18:40:13 +0000 (20:40 +0200)
src/plugins/quota/quota-private.h
src/plugins/quota/quota-util.c
src/plugins/quota/quota.c

index 2048beb0269ab503fdc5919c968cfe50870f6f5f..01eb5eb8880f33fc7c9a94981701120a2789a947 100644 (file)
@@ -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);
 
index 422d09570417525b59431234ce425d3a46f65fa6..3d783154bccc6dd4ff729474a336b2cbe665d162 100644 (file)
@@ -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,
index 7044c60642b8fed951756f4a99e715e34b00b484..143783162cc7d22100b1667256b7c08214a6d9a9 100644 (file)
@@ -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");
+               }
        }
 }