]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Add VOLATILEDIR setting to mail_location
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 21 Jun 2017 22:28:57 +0000 (01:28 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 3 Jul 2017 12:14:13 +0000 (15:14 +0300)
This is useful for creating temporary locks that could exist in tmpfs.
Currently this is used for .vsize.lock and dovecot.autoexpunge.lock.

src/lib-storage/mail-storage.c
src/lib-storage/mail-user.c
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h

index 93c620d65d80d9b8f6fc15153545a98c577c0371..c94a7ddf53f7b04f0e206d2def2988b7d9b33af1 100644 (file)
@@ -6,7 +6,9 @@
 #include "llist.h"
 #include "str.h"
 #include "str-sanitize.h"
+#include "sha1.h"
 #include "unichar.h"
+#include "hex-binary.h"
 #include "file-create-locked.h"
 #include "istream.h"
 #include "eacces-error.h"
@@ -2782,7 +2784,26 @@ int mailbox_lock_file_create(struct mailbox *box, const char *lock_fname,
        set.gid = perm->file_create_gid;
        set.gid_origin = perm->file_create_gid_origin;
 
-       lock_path = t_strdup_printf("%s/%s", box->index->dir, lock_fname);
+       if (box->list->set.volatile_dir == NULL)
+               lock_path = t_strdup_printf("%s/%s", box->index->dir, lock_fname);
+       else {
+               unsigned char box_name_sha1[SHA1_RESULTLEN];
+               string_t *str = t_str_new(128);
+
+               /* Keep this simple: Use the lock_fname with a SHA1 of the
+                  mailbox name as the suffix. The mailbox name itself could
+                  be too large as a filename and creating the full directory
+                  structure would be pretty troublesome. It would also make
+                  it more difficult to perform the automated deletion of empty
+                  lock directories. */
+               str_printfa(str, "%s/%s.", box->list->set.volatile_dir,
+                           lock_fname);
+               sha1_get_digest(box->name, strlen(box->name), box_name_sha1);
+               binary_to_hex_append(str, box_name_sha1, sizeof(box_name_sha1));
+               lock_path = str_c(str);
+               set.mkdir_mode = 0700;
+       }
+
        if (file_create_locked(lock_path, &set, lock_r, &created, error_r) == -1) {
                *error_r = t_strdup_printf("file_create_locked(%s) failed: %s",
                                           lock_path, *error_r);
index 958bcae73bfd626163a4b8f715109e4cbbff7fc3..d90ae5535d0aca298b61c81554401479e8153ebb 100644 (file)
@@ -23,6 +23,7 @@
 #include "mail-storage-service.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
+#include "mailbox-list-private.h"
 #include "mail-autoexpunge.h"
 #include "mail-user.h"
 
@@ -523,7 +524,16 @@ int mail_user_lock_file_create(struct mail_user *user, const char *lock_fname,
                .lock_timeout_secs = lock_secs,
                .lock_method = mail_set->parsed_lock_method,
        };
-       path = t_strdup_printf("%s/%s", home, lock_fname);
+       struct mailbox_list *inbox_list =
+               mail_namespace_find_inbox(user->namespaces)->list;
+       if (inbox_list->set.volatile_dir == NULL)
+               path = t_strdup_printf("%s/%s", home, lock_fname);
+       else {
+               path = t_strdup_printf("%s/%s", inbox_list->set.volatile_dir,
+                                      lock_fname);
+               lock_set.mkdir_mode = 0700;
+       }
+
        if (file_create_locked(path, &lock_set, lock_r, &created, &error) == -1) {
                *error_r = t_strdup_printf("file_create_locked(%s) failed: %s", path, error);
                return errno == EAGAIN ? 0 : -1;
index d11fe3bf7b8b462e4ec9276ad8f03a0dd974d04f..3ee2e21f59c4f77e3fc1e802e741a9a66e0778f0 100644 (file)
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "abspath.h"
 #include "ioloop.h"
+#include "file-create-locked.h"
 #include "mkdir-parents.h"
 #include "str.h"
 #include "sha1.h"
@@ -171,6 +172,7 @@ int mailbox_list_create(const char *driver, struct mail_namespace *ns,
                p_strdup(list->pool, set->mailbox_dir_name);
        list->set.alt_dir = p_strdup(list->pool, set->alt_dir);
        list->set.alt_dir_nocheck = set->alt_dir_nocheck;
+       list->set.volatile_dir = p_strdup(list->pool, set->volatile_dir);
        list->set.index_control_use_maildir_name =
                set->index_control_use_maildir_name;
 
@@ -336,6 +338,8 @@ mailbox_list_settings_parse_full(struct mail_user *user, const char *data,
                        dest = &set_r->maildir_name;
                else if (strcmp(key, "MAILBOXDIR") == 0)
                        dest = &set_r->mailbox_dir_name;
+               else if (strcmp(key, "VOLATILEDIR") == 0)
+                       dest = &set_r->volatile_dir;
                else if (strcmp(key, "LISTINDEX") == 0)
                        dest = &set_r->list_index_fname;
                else if (strcmp(key, "FULLDIRNAME") == 0) {
index b6835d03de7b1fe51865914f49ddb6b3ac5a9182..3232e17260e6170ada8ae52a84583c11658e4869 100644 (file)
@@ -98,6 +98,11 @@ struct mailbox_list_settings {
        const char *index_pvt_dir;
        const char *control_dir;
        const char *alt_dir; /* FIXME: dbox-specific.. */
+       /* Backend-local directory where volatile data, such as lock files,
+          can be temporarily created. This setting allows specifying a
+          separate directory for them to reduce disk I/O on the real storage.
+          The volatile_dir can point to an in-memory filesystem. */
+       const char *volatile_dir;
 
        const char *inbox_path;
        const char *subscription_fname;