changeset 21504:ee051f0429b2

quota: When executing quota_warning/over_flag script, log the reason why.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 07 Feb 2017 18:26:50 +0200
parents 8aa60021b469
children 6c88e7e55768
files src/plugins/quota/quota-private.h src/plugins/quota/quota-util.c src/plugins/quota/quota.c
diffstat 3 files changed, 45 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/quota/quota-private.h	Tue Feb 07 13:19:17 2017 +0200
+++ b/src/plugins/quota/quota-private.h	Tue Feb 07 18:26:50 2017 +0200
@@ -208,7 +208,8 @@
 			   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);
 
--- a/src/plugins/quota/quota-util.c	Tue Feb 07 13:19:17 2017 +0200
+++ b/src/plugins/quota/quota-util.c	Tue Feb 07 18:26:50 2017 +0200
@@ -384,18 +384,44 @@
 
 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,
--- a/src/plugins/quota/quota.c	Tue Feb 07 13:19:17 2017 +0200
+++ b/src/plugins/quota/quota.c	Tue Feb 07 18:26:50 2017 +0200
@@ -874,14 +874,14 @@
 }
 
 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;
 	string_t *str;
 	int fd;
 
 	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) {
@@ -933,6 +933,7 @@
 	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)
@@ -950,8 +951,10 @@
 	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;
 		}
 	}
@@ -1087,8 +1090,11 @@
 	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");
+		}
 	}
 }