dovecot-2.0: quota: Use the new "script" service for executing q...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jun 2 20:52:15 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/a179fcbbf960
changeset: 11462:a179fcbbf960
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jun 02 18:52:12 2010 +0100
description:
quota: Use the new "script" service for executing quota warnings.
This improves the performance, especially when the process is handling
multiple users, because it no longer has to fork a process and wait for
the script to finish.

Example configuration:

plugin {
  quota_warning = storage=90%% quota-warning 90 %u
}
service quota-warning {
  executable = script /usr/local/bin/quota-warning.sh
  user = vmail
  unix_listener quota-warning {
  }
}

The quota-warning.sh will be executed with parameters 90 and username.

diffstat:

 src/plugins/quota/quota.c |  42 ++++++++++++++++++++++++++++++++----------
 1 files changed, 32 insertions(+), 10 deletions(-)

diffs (71 lines):

diff -r 19c661891964 -r a179fcbbf960 src/plugins/quota/quota.c
--- a/src/plugins/quota/quota.c	Wed Jun 02 18:46:26 2010 +0100
+++ b/src/plugins/quota/quota.c	Wed Jun 02 18:52:12 2010 +0100
@@ -3,6 +3,9 @@
 #include "lib.h"
 #include "array.h"
 #include "hash.h"
+#include "str.h"
+#include "network.h"
+#include "write-full.h"
 #include "mailbox-list-private.h"
 #include "quota-private.h"
 #include "quota-fs.h"
@@ -634,7 +637,7 @@
 	int ret;
 
 	p = strchr(rule_def, ' ');
-	if (p == NULL) {
+	if (p == NULL || p[1] == '\0') {
 		*error_r = "No command specified";
 		return -1;
 	}
@@ -901,20 +904,39 @@
 
 static void quota_warning_execute(struct quota_root *root, const char *cmd)
 {
-	int ret;
+	const char *socket_path, *const *args;
+	string_t *str;
+	int fd;
 
 	if (root->quota->set->debug)
 		i_debug("quota: Executing warning: %s", cmd);
 
-	ret = system(cmd);
-	if (ret < 0) {
-		i_error("system(%s) failed: %m", cmd);
-	} else if (WIFSIGNALED(ret)) {
-		i_error("system(%s) died with signal %d", cmd, WTERMSIG(ret));
-	} else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
-		i_error("system(%s) exited with status %d",
-			cmd, WIFEXITED(ret) ? WEXITSTATUS(ret) : ret);
+	args = t_strsplit(cmd, " ");
+	socket_path = args[0];
+	args++;
+
+	if (*socket_path != '/') {
+		socket_path = t_strconcat(root->quota->user->set->base_dir, "/",
+					  socket_path, NULL);
 	}
+	if ((fd = net_connect_unix_with_retries(socket_path, 1000)) < 0) {
+		i_error("quota: connect(%s) failed: %m", socket_path);
+		return;
+	}
+
+	str = t_str_new(1024);
+	str_append(str, "VERSION\tscript\t1\t0\n");
+	for (; *args != NULL; args++) {
+		str_append(str, *args);
+		str_append_c(str, '\n');
+	}
+	str_append_c(str, '\n');
+
+	net_set_nonblock(fd, FALSE);
+	if (write_full(fd, str_data(str), str_len(str)) < 0)
+		i_error("write(%s) failed: %m", socket_path);
+	if (close(fd) < 0)
+		i_error("close(%s) failed: %m", socket_path);
 }
 
 static void quota_warnings_execute(struct quota_transaction_context *ctx,


More information about the dovecot-cvs mailing list