]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added "size" setting type, which supports B/k/M/G/T suffixes.
authorTimo Sirainen <tss@iki.fi>
Mon, 9 Nov 2009 23:22:37 +0000 (18:22 -0500)
committerTimo Sirainen <tss@iki.fi>
Mon, 9 Nov 2009 23:22:37 +0000 (18:22 -0500)
--HG--
branch : HEAD

23 files changed:
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

index a89787d6ad0e4795da136e6738a6a51c106f125a..1edda31ddc1321f73fdf33212fb60f4cffb5e495 100644 (file)
@@ -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
index c7699828ba8a48aee1e228714c9a7d1e2084c7c5..708326ea9a93baf620dc5909e3de4ed5a7b931d7 100644 (file)
@@ -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.
index cf3b7e875ecea1b38cc9fb8d8eb5114ea5f83d25..d50e9ffe930797bcfdaf11171e1412d3ce6f0250 100644 (file)
 # 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
 
 ## 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.
index ac0141c128d46a45bc1b5e93e50df51a3b0fafd9..95e44fe0fee7d92a14f725c710a61a55006f6d75 100644 (file)
@@ -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 imap-login {
   #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 lmtp {
 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 {
index 5ac8f1fd155e8d4382eb6fc5022d80f7b84132c2..5b45b7055d6ff3b9fffce5f3a372117c420f77d3 100644 (file)
@@ -151,7 +151,7 @@ static const struct setting_define auth_setting_defines[] = {
        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),
index 7f504b024df59907f56d20fc12cc75200ed86521..86853b08843572a50ef17d7537da6d84358ce411 100644 (file)
@@ -20,7 +20,7 @@ struct auth_settings {
        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;
index ef2366a31bcb56925cc3a846e8c9eb8b65d79e80..e5094fffc3229c709e9a22fa0dfe149186f9e44f 100644 (file)
@@ -127,7 +127,7 @@ void passdb_cache_init(const struct auth_settings *set)
        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);
 }
 
index 4eab8e782cdc937156d5c51006bf70472275d40d..33111b9163310eb55adf466e9549d30738190ed0 100644 (file)
@@ -128,6 +128,14 @@ settings_export(struct settings_export_context *ctx,
                        }
                        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)
index bbde4f10643c105060d8ab49b4acf520e7659e9b..7ba2667377e74a5a71cba39c9e0b84cd5f5f5a15 100644 (file)
@@ -62,7 +62,7 @@ static const struct setting_define imap_setting_defines[] = {
        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 @@ static const struct imap_settings imap_default_settings = {
        /* 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",
index 09bd52b8b7ec1f77c9aa873520063fc7d0943163..e8bdf7e585fa6ed01b39905503799e7e33c88cff 100644 (file)
@@ -16,7 +16,7 @@ struct imap_settings {
        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;
index 0d66fa6b0875d1aa7b012d179ae722b08eff3b33..77fc6d3b1208ca67aaa676f6a389dee6adba3307 100644 (file)
@@ -42,7 +42,7 @@ struct service_settings {
        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;
index f38904b1fc605ff87dff1c52287d1e3a54c7371e..a1435469f3a724d763b914199fd615116c7eb7bd 100644 (file)
@@ -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 @@ get_uint(struct setting_parser_context *ctx, const char *value,
        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 @@ settings_parse(struct setting_parser_context *ctx, struct setting_link *link,
                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 @@ settings_var_expand_info(const struct setting_parser_info *info,
                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 @@ bool settings_vars_have_key(const struct setting_parser_info *info, void *set,
                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 @@ setting_copy(enum setting_type type, const void *src, void *dest, pool_t pool)
                *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 @@ settings_changes_dup(const struct setting_parser_info *info,
                switch (def->type) {
                case SET_BOOL:
                case SET_UINT:
+               case SET_SIZE:
                case SET_STR_VARS:
                case SET_STR:
                case SET_ENUM:
index 5f05648f2c6fe9bef1866da784f22240b03dadd4..f9bab64cc8ac29710c089a2a239c89d954a6c51a 100644 (file)
@@ -19,6 +19,7 @@ struct var_expand_table;
 enum setting_type {
        SET_BOOL,
        SET_UINT,
+       SET_SIZE,
        SET_STR,
        SET_STR_VARS, /* string with %variables */
        SET_ENUM,
@@ -47,6 +48,10 @@ struct setting_define {
        { 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 @@ int settings_parser_apply_changes(struct setting_parser_context *dest,
 
 /* 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
index ba564412f7e37c724bfedb6f6d08d4c0c60fb301..5b63f0d9e1e9f6af554022cdd205323b7c466b73 100644 (file)
@@ -15,8 +15,8 @@ static bool mdbox_settings_verify(void *_set, pool_t pool ATTR_UNUSED,
                                  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 setting_define mdbox_setting_defines[] = {
 };
 
 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,
index 5425e309c4d5ff6e3a96380f54fc808474325674..ef265340fc2f32a7dcc5caefa3b8e84eb60a0022 100644 (file)
@@ -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;
index 6c32af2e93951fa5f04ab6e45a5c4b6edabe46e9..48f7031731cec21cefb78d6100cb6c0750d1133b 100644 (file)
@@ -16,7 +16,7 @@ static const struct setting_define mbox_setting_defines[] = {
        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),
index 7c3188c4be878bfa5ff823fb68fd354d0f6f9242..19322afadc7b4f32b8af36946527c48838f8f32e 100644 (file)
@@ -6,7 +6,7 @@ struct mbox_settings {
        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;
index 49b01eeab51ec62bd6c09b44afb1bd4c07d220b5..15ebffa83397fcfbdb77c78bed52629b40699bf6 100644 (file)
@@ -329,7 +329,7 @@ static bool want_memory_indexes(struct mbox_storage *storage, const char *path)
                        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 *
index f7ee1e0d924b55e1d50113f851b7938df3eba4b4..1fbd489d26424e8e14d870eef7b41241eb737691 100644 (file)
@@ -111,7 +111,7 @@ static const struct setting_define service_setting_defines[] = {
        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 @@ static const struct service_settings service_default_settings = {
        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 @@ static const struct setting_define master_setting_defines[] = {
        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 @@ static const struct master_settings master_default_settings = {
        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,
index 25c1d8eab5c10b0b5c20d7ea03167903ab7d3aee..bff8f356eb9a9bf19d1adbb25005a28861015c6e 100644 (file)
@@ -11,7 +11,7 @@ struct master_settings {
        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;
index b786bbee43906c0e917775f36e43983a32ad82ad..07340cb3b8d7630b9bde38e65e046690e7d42f18 100644 (file)
@@ -137,7 +137,7 @@ drop_privileges(struct service *service)
        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 @@ get_exit_status_message(struct service *service, enum fatal_exit_status status)
                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";
 
index ce24f4626c4f269043bca1be42ad81a09218a4c1..a70c716a94144ab5c7fc161b5fd2c903eda9392a 100644 (file)
@@ -176,7 +176,7 @@ service_create(pool_t pool, const struct service_settings *set,
            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;
 
index 5fc9d71c0cf89c935b0ce829604a48370b7cd5fe..e2e4870f8b002de2a2e1a049fd314609070caaab 100644 (file)
@@ -65,7 +65,7 @@ struct service {
        /* 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];