changeset 10281:4b663b9e63af HEAD

Added "size" setting type, which supports B/k/M/G/T suffixes.
author Timo Sirainen <tss@iki.fi>
date Mon, 09 Nov 2009 18:22:37 -0500
parents cd1ce06a0ee5
children 7215f4142901
files doc/example-config/conf.d/auth.conf doc/example-config/conf.d/imap.conf doc/example-config/conf.d/mail.conf doc/example-config/conf.d/master.conf src/auth/auth-settings.c src/auth/auth-settings.h src/auth/passdb-cache.c src/config/config-request.c src/imap/imap-settings.c src/imap/imap-settings.h src/lib-master/service-settings.h src/lib-settings/settings-parser.c src/lib-settings/settings-parser.h src/lib-storage/index/dbox-multi/mdbox-settings.c src/lib-storage/index/dbox-multi/mdbox-settings.h src/lib-storage/index/mbox/mbox-settings.c src/lib-storage/index/mbox/mbox-settings.h src/lib-storage/index/mbox/mbox-storage.c src/master/master-settings.c src/master/master-settings.h src/master/service-process.c src/master/service.c src/master/service.h
diffstat 23 files changed, 123 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/doc/example-config/conf.d/auth.conf	Mon Nov 09 15:12:01 2009 -0500
+++ b/doc/example-config/conf.d/auth.conf	Mon Nov 09 18:22:37 2009 -0500
@@ -2,9 +2,8 @@
 ## Authentication processes
 ##
 
-# Authentication cache size in kilobytes. 0 means it's disabled.
-# Note that bsdauth, PAM and vpopmail require cache_key to be set for caching
-# to be used.
+# Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
+# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used.
 #auth_cache_size = 0
 # Time to live in seconds for cached data. After this many seconds the cached
 # record is no longer used, *except* if the main database lookup returns
--- a/doc/example-config/conf.d/imap.conf	Mon Nov 09 15:12:01 2009 -0500
+++ b/doc/example-config/conf.d/imap.conf	Mon Nov 09 18:22:37 2009 -0500
@@ -3,10 +3,10 @@
 ##
 
 protocol imap {
-  # Maximum IMAP command line length in bytes. Some clients generate very long
-  # command lines with huge mailboxes, so you may need to raise this if you get
+  # Maximum IMAP command line length. Some clients generate very long command
+  # lines with huge mailboxes, so you may need to raise this if you get
   # "Too long argument" or "IMAP command line too large" errors often.
-  #imap_max_line_length = 65536
+  #imap_max_line_length = 64k
 
   # Maximum number of IMAP connections allowed for a user from each IP address.
   # NOTE: The username is compared case-sensitively.
--- a/doc/example-config/conf.d/mail.conf	Mon Nov 09 15:12:01 2009 -0500
+++ b/doc/example-config/conf.d/mail.conf	Mon Nov 09 18:22:37 2009 -0500
@@ -295,7 +295,7 @@
 # aren't immediately visible to other MUAs.
 #mbox_lazy_writes = yes
 
-# If mbox size is smaller than this (in kilobytes), don't write index files.
+# If mbox size is smaller than this (e.g. 100k), don't write index files.
 # If an index file already exists it's still read, just not updated.
 #mbox_min_index_size = 0
 
@@ -303,12 +303,11 @@
 ## mdbox-specific settings
 ##
 
-# Maximum dbox file size in kilobytes until it's rotated.
-#mdbox_rotate_size = 2048
+# Maximum dbox file size until it's rotated.
+#mdbox_rotate_size = 2M
 
-# Minimum dbox file size in kilobytes before it's rotated
-# (overrides mdbox_rotate_days)
-#mdbox_rotate_min_size = 16
+# Minimum dbox file size before it's rotated (overrides mdbox_rotate_days)
+#mdbox_rotate_min_size = 16k
 
 # Maximum dbox file age in days until it's rotated. Day always begins from
 # midnight, so 1 = today, 2 = yesterday, etc. 0 = check disabled.
--- a/doc/example-config/conf.d/master.conf	Mon Nov 09 15:12:01 2009 -0500
+++ b/doc/example-config/conf.d/master.conf	Mon Nov 09 18:22:37 2009 -0500
@@ -1,6 +1,6 @@
 #default_process_limit = 100
 #default_client_limit = 1000
-#default_vsz_limit = 256
+#default_vsz_limit = 256M
 
 service imap-login {
   inet_listener {
@@ -17,7 +17,7 @@
   #service_count = 1
 
   # If you set service_count=0, you probably need to grow this.
-  #vsz_limit = 64
+  #vsz_limit = 64M
 }
 
 service pop3-login {
@@ -39,7 +39,7 @@
 service imap {
   # Most of the memory goes to mmap()ing files. You may need to increase this
   # limit if you have huge mailboxes.
-  #vsz_limit = 256
+  #vsz_limit = 256M
 }
 
 service auth {
--- a/src/auth/auth-settings.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/auth/auth-settings.c	Mon Nov 09 18:22:37 2009 -0500
@@ -151,7 +151,7 @@
 	DEF(SET_STR, mechanisms),
 	DEF(SET_STR, realms),
 	DEF(SET_STR, default_realm),
-	DEF(SET_UINT, cache_size),
+	DEF(SET_SIZE, cache_size),
 	DEF(SET_UINT, cache_ttl),
 	DEF(SET_UINT, cache_negative_ttl),
 	DEF(SET_STR, username_chars),
--- a/src/auth/auth-settings.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/auth/auth-settings.h	Mon Nov 09 18:22:37 2009 -0500
@@ -20,7 +20,7 @@
 	const char *mechanisms;
 	const char *realms;
 	const char *default_realm;
-	unsigned int cache_size;
+	uoff_t cache_size;
 	unsigned int cache_ttl;
 	unsigned int cache_negative_ttl;
 	const char *username_chars;
--- a/src/auth/passdb-cache.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/auth/passdb-cache.c	Mon Nov 09 18:22:37 2009 -0500
@@ -127,7 +127,7 @@
 	if (set->cache_size == 0 || set->cache_ttl == 0)
 		return;
 
-	passdb_cache = auth_cache_new(set->cache_size * 1024UL, set->cache_ttl,
+	passdb_cache = auth_cache_new(set->cache_size, set->cache_ttl,
 				      set->cache_negative_ttl);
 }
 
--- a/src/config/config-request.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/config/config-request.c	Mon Nov 09 18:22:37 2009 -0500
@@ -128,6 +128,14 @@
 			}
 			break;
 		}
+		case SET_SIZE: {
+			const uoff_t *val = value, *dval = default_value;
+			if (dump_default || dval == NULL || *val != *dval) {
+				str_printfa(ctx->value, "%llu",
+					    (unsigned long long)*val);
+			}
+			break;
+		}
 		case SET_UINT: {
 			const unsigned int *val = value, *dval = default_value;
 			if (dump_default || dval == NULL || *val != *dval)
--- a/src/imap/imap-settings.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/imap/imap-settings.c	Mon Nov 09 18:22:37 2009 -0500
@@ -62,7 +62,7 @@
 	DEF(SET_BOOL, mail_debug),
 	DEF(SET_BOOL, verbose_proctitle),
 
-	DEF(SET_UINT, imap_max_line_length),
+	DEF(SET_SIZE, imap_max_line_length),
 	DEF(SET_UINT, imap_idle_notify_interval),
 	DEF(SET_STR, imap_capability),
 	DEF(SET_STR, imap_client_workarounds),
@@ -80,7 +80,7 @@
 	/* RFC-2683 recommends at least 8000 bytes. Some clients however don't
 	   break large message sets to multiple commands, so we're pretty
 	   liberal by default. */
-	MEMBER(imap_max_line_length) 65536,
+	MEMBER(imap_max_line_length) 64*1024,
 	MEMBER(imap_idle_notify_interval) 120,
 	MEMBER(imap_capability) "",
 	MEMBER(imap_client_workarounds) "outlook-idle",
--- a/src/imap/imap-settings.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/imap/imap-settings.h	Mon Nov 09 18:22:37 2009 -0500
@@ -16,7 +16,7 @@
 	bool verbose_proctitle;
 
 	/* imap: */
-	unsigned int imap_max_line_length;
+	uoff_t imap_max_line_length;
 	unsigned int imap_idle_notify_interval;
 	const char *imap_capability;
 	const char *imap_client_workarounds;
--- a/src/lib-master/service-settings.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-master/service-settings.h	Mon Nov 09 18:22:37 2009 -0500
@@ -42,7 +42,7 @@
 	unsigned int process_limit;
 	unsigned int client_limit;
 	unsigned int service_count;
-	unsigned int vsz_limit;
+	uoff_t vsz_limit;
 
 	ARRAY_TYPE(file_listener_settings) unix_listeners;
 	ARRAY_TYPE(file_listener_settings) fifo_listeners;
--- a/src/lib-settings/settings-parser.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-settings/settings-parser.c	Mon Nov 09 18:22:37 2009 -0500
@@ -13,6 +13,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <ctype.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
@@ -308,6 +309,61 @@
 	return 0;
 }
 
+static int
+get_size(struct setting_parser_context *ctx, const char *value,
+	 uoff_t *result_r)
+{
+	unsigned long long num, multiply;
+	char *p;
+
+	num = strtoull(value, &p, 10);
+	switch (i_toupper(*p)) {
+	case '\0':
+		multiply = 1;
+		break;
+	case 'B':
+		multiply = 1;
+		p += 1;
+		break;
+	case 'K':
+		multiply = 1024;
+		p += 1;
+		break;
+	case 'M':
+		multiply = 1024*1024;
+		p += 1;
+		break;
+	case 'G':
+		multiply = 1024*1024*1024;
+		p += 1;
+		break;
+	case 'T':
+		multiply = 1024ULL*1024*1024*1024;
+		p += 1;
+		break;
+	}
+
+	if (multiply > 1) {
+		/* Allow: k, ki, kiB */
+		if (i_toupper(*p) == 'I')
+			p++;
+		if (i_toupper(*p) == 'B')
+			p++;
+	}
+	if (*p != '\0') {
+		ctx->error = p_strconcat(ctx->parser_pool, "Invalid size: ",
+					 value, NULL);
+		return -1;
+	}
+	if (num > -1ULL / multiply) {
+		ctx->error = p_strconcat(ctx->parser_pool,
+					 "Size is too large: ", value, NULL);
+		return -1;
+	}
+	*result_r = num * multiply;
+	return 0;
+}
+
 static int get_enum(struct setting_parser_context *ctx, const char *value,
 		    char **result_r, const char *allowed_values)
 {
@@ -448,6 +504,10 @@
 		if (get_uint(ctx, value, (unsigned int *)ptr) < 0)
 			return -1;
 		break;
+	case SET_SIZE:
+		if (get_size(ctx, value, (uoff_t *)ptr) < 0)
+			return -1;
+		break;
 	case SET_STR:
 		*((char **)ptr) = p_strdup(ctx->set_pool, value);
 		break;
@@ -902,6 +962,7 @@
 		switch (def->type) {
 		case SET_BOOL:
 		case SET_UINT:
+		case SET_SIZE:
 		case SET_STR:
 		case SET_ENUM:
 		case SET_STRLIST:
@@ -971,6 +1032,7 @@
 		switch (def->type) {
 		case SET_BOOL:
 		case SET_UINT:
+		case SET_SIZE:
 		case SET_STR:
 		case SET_ENUM:
 		case SET_STRLIST:
@@ -1045,6 +1107,13 @@
 		*dest_uint = *src_uint;
 		break;
 	}
+	case SET_SIZE: {
+		const uoff_t *src_size = src;
+		uoff_t *dest_size = dest;
+
+		*dest_size = *src_size;
+		break;
+	}
 	case SET_STR_VARS:
 	case SET_STR:
 	case SET_ENUM: {
@@ -1139,6 +1208,7 @@
 		switch (def->type) {
 		case SET_BOOL:
 		case SET_UINT:
+		case SET_SIZE:
 		case SET_STR_VARS:
 		case SET_STR:
 		case SET_ENUM:
--- a/src/lib-settings/settings-parser.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-settings/settings-parser.h	Mon Nov 09 18:22:37 2009 -0500
@@ -19,6 +19,7 @@
 enum setting_type {
 	SET_BOOL,
 	SET_UINT,
+	SET_SIZE,
 	SET_STR,
 	SET_STR_VARS, /* string with %variables */
 	SET_ENUM,
@@ -47,6 +48,10 @@
 	{ SET_UINT + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
 		((struct struct_name *)0)->name, unsigned int), \
 	  #name, offsetof(struct struct_name, name), NULL }
+#define SETTING_DEFINE_STRUCT_SIZE(name, struct_name) \
+	{ SET_SIZE + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
+		((struct struct_name *)0)->name, uoff_t), \
+	  #name, offsetof(struct struct_name, name), NULL }
 #define SETTING_DEFINE_STRUCT_STR(name, struct_name) \
 	{ SET_STR + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \
 		((struct struct_name *)0)->name, const char *), \
@@ -185,5 +190,7 @@
 
 /* Return section name escaped */
 const char *settings_section_escape(const char *name);
+/* Parse a size string to actual size. */
+int settings_parse_size(const char *str, uoff_t *size_r, const char **error_r);
 
 #endif
--- a/src/lib-storage/index/dbox-multi/mdbox-settings.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-storage/index/dbox-multi/mdbox-settings.c	Mon Nov 09 18:22:37 2009 -0500
@@ -15,8 +15,8 @@
 				  const char **error_r);
 
 static const struct setting_define mdbox_setting_defines[] = {
-	DEF(SET_UINT, mdbox_rotate_size),
-	DEF(SET_UINT, mdbox_rotate_min_size),
+	DEF(SET_SIZE, mdbox_rotate_size),
+	DEF(SET_SIZE, mdbox_rotate_min_size),
 	DEF(SET_UINT, mdbox_rotate_days),
 	DEF(SET_UINT, mdbox_max_open_files),
 	DEF(SET_UINT, mdbox_purge_min_percentage),
@@ -25,7 +25,7 @@
 };
 
 static const struct mdbox_settings mdbox_default_settings = {
-	MEMBER(mdbox_rotate_size) 2048*1024,
+	MEMBER(mdbox_rotate_size) 2*1024*1024,
 	MEMBER(mdbox_rotate_min_size) 16*1024,
 	MEMBER(mdbox_rotate_days) 0,
 	MEMBER(mdbox_max_open_files) 64,
--- a/src/lib-storage/index/dbox-multi/mdbox-settings.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-storage/index/dbox-multi/mdbox-settings.h	Mon Nov 09 18:22:37 2009 -0500
@@ -2,8 +2,8 @@
 #define MDBOX_SETTINGS_H
 
 struct mdbox_settings {
-	unsigned int mdbox_rotate_size;
-	unsigned int mdbox_rotate_min_size;
+	uoff_t mdbox_rotate_size;
+	uoff_t mdbox_rotate_min_size;
 	unsigned int mdbox_rotate_days;
 	unsigned int mdbox_max_open_files;
 	unsigned int mdbox_purge_min_percentage;
--- a/src/lib-storage/index/mbox/mbox-settings.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-settings.c	Mon Nov 09 18:22:37 2009 -0500
@@ -16,7 +16,7 @@
 	DEF(SET_STR, mbox_write_locks),
 	DEF(SET_UINT, mbox_lock_timeout),
 	DEF(SET_UINT, mbox_dotlock_change_timeout),
-	DEF(SET_UINT, mbox_min_index_size),
+	DEF(SET_SIZE, mbox_min_index_size),
 	DEF(SET_BOOL, mbox_dirty_syncs),
 	DEF(SET_BOOL, mbox_very_dirty_syncs),
 	DEF(SET_BOOL, mbox_lazy_writes),
--- a/src/lib-storage/index/mbox/mbox-settings.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-settings.h	Mon Nov 09 18:22:37 2009 -0500
@@ -6,7 +6,7 @@
 	const char *mbox_write_locks;
 	unsigned int mbox_lock_timeout;
 	unsigned int mbox_dotlock_change_timeout;
-	unsigned int mbox_min_index_size;
+	uoff_t mbox_min_index_size;
 	bool mbox_dirty_syncs;
 	bool mbox_very_dirty_syncs;
 	bool mbox_lazy_writes;
--- a/src/lib-storage/index/mbox/mbox-storage.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Mon Nov 09 18:22:37 2009 -0500
@@ -329,7 +329,7 @@
 			return FALSE;
 		}
 	}
-	return st.st_size / 1024 < storage->set->mbox_min_index_size;
+	return (uoff_t)st.st_size < storage->set->mbox_min_index_size;
 }
 
 static struct mailbox *
--- a/src/master/master-settings.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/master/master-settings.c	Mon Nov 09 18:22:37 2009 -0500
@@ -111,7 +111,7 @@
 	DEF(SET_UINT, process_limit),
 	DEF(SET_UINT, client_limit),
 	DEF(SET_UINT, service_count),
-	DEF(SET_UINT, vsz_limit),
+	DEF(SET_SIZE, vsz_limit),
 
 	DEFLIST_UNIQUE(unix_listeners, "unix_listener",
 		       &file_listener_setting_parser_info),
@@ -140,7 +140,7 @@
 	MEMBER(process_limit) -1U,
 	MEMBER(client_limit) 0,
 	MEMBER(service_count) 0,
-	MEMBER(vsz_limit) -1U,
+	MEMBER(vsz_limit) (uoff_t)-1,
 
 	MEMBER(unix_listeners) ARRAY_INIT,
 	MEMBER(fifo_listeners) ARRAY_INIT,
@@ -174,7 +174,7 @@
 	DEF(SET_ENUM, ssl),
 	DEF(SET_UINT, default_process_limit),
 	DEF(SET_UINT, default_client_limit),
-	DEF(SET_UINT, default_vsz_limit),
+	DEF(SET_SIZE, default_vsz_limit),
 
 	DEF(SET_BOOL, version_ignore),
 	DEF(SET_BOOL, mail_debug),
@@ -198,7 +198,7 @@
 	MEMBER(ssl) "yes:no:required",
 	MEMBER(default_process_limit) 100,
 	MEMBER(default_client_limit) 1000,
-	MEMBER(default_vsz_limit) 256,
+	MEMBER(default_vsz_limit) 256*1024*1024,
 
 	MEMBER(version_ignore) FALSE,
 	MEMBER(mail_debug) FALSE,
--- a/src/master/master-settings.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/master/master-settings.h	Mon Nov 09 18:22:37 2009 -0500
@@ -11,7 +11,7 @@
 	const char *ssl;
 	unsigned int default_process_limit;
 	unsigned int default_client_limit;
-	unsigned int default_vsz_limit;
+	uoff_t default_vsz_limit;
 
 	bool version_ignore;
 	bool mail_debug;
--- a/src/master/service-process.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/master/service-process.c	Mon Nov 09 18:22:37 2009 -0500
@@ -137,7 +137,7 @@
 	unsigned int len;
 
 	if (service->vsz_limit != 0)
-		restrict_process_size(service->vsz_limit, -1U);
+		restrict_process_size(service->vsz_limit/1024, -1U);
 
 	restrict_access_init(&rset);
 	rset.uid = service->uid;
@@ -350,8 +350,8 @@
 		if (service->vsz_limit == 0)
 			return "Out of memory";
 		return t_strdup_printf("Out of memory (vsz_limit=%u MB, "
-				       "you may need to increase it)",
-				       service->vsz_limit);
+				"you may need to increase it)",
+				(unsigned int)(service->vsz_limit/1024/1024));
 	case FATAL_EXEC:
 		return "exec() failed";
 
--- a/src/master/service.c	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/master/service.c	Mon Nov 09 18:22:37 2009 -0500
@@ -176,7 +176,7 @@
 	    service->client_limit < set->service_count)
 		service->client_limit = set->service_count;
 
-	service->vsz_limit = set->vsz_limit != -1U ? set->vsz_limit :
+	service->vsz_limit = set->vsz_limit != (uoff_t)-1 ? set->vsz_limit :
 		set->master_set->default_vsz_limit;
 	service->type = service->set->parsed_type;
 
--- a/src/master/service.h	Mon Nov 09 15:12:01 2009 -0500
+++ b/src/master/service.h	Mon Nov 09 18:22:37 2009 -0500
@@ -65,7 +65,7 @@
 	/* Maximum number of client connections a process can handle. */
 	unsigned int client_limit;
 	/* set->vsz_limit or set->master_set->default_client_limit */
-	unsigned int vsz_limit;
+	uoff_t vsz_limit;
 
 	/* log process pipe file descriptors. */
 	int log_fd[2];