]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Move autoexpunge lock creation to a generic mail_user_lock_file_create()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 21 Jun 2017 23:44:12 +0000 (02:44 +0300)
committerGitLab <gitlab@git.dovecot.net>
Wed, 28 Jun 2017 18:59:03 +0000 (21:59 +0300)
src/lib-storage/mail-autoexpunge.c
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h

index 4c2fae4f5c29dc04736d2b1af81e71a9b4aed485..13fbda0f9ef1d889210537845e86a67b8af408fa 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "ioloop.h"
-#include "file-create-locked.h"
 #include "mailbox-list-iter.h"
 #include "mail-storage-private.h"
 #include "mail-namespace.h"
@@ -14,9 +13,7 @@
 static bool
 mailbox_autoexpunge_lock(struct mail_user *user, struct file_lock **lock)
 {
-       struct file_create_settings lock_set;
-       bool created;
-       const char *home, *path, *error;
+       const char *error;
        int ret;
 
        if (*lock != NULL)
@@ -30,33 +27,19 @@ mailbox_autoexpunge_lock(struct mail_user *user, struct file_lock **lock)
           so that multiple processes won't do the same work unnecessarily,
           and 2) it helps to avoid duplicate mails being added with
           lazy_expunge. */
-       if ((ret = mail_user_get_home(user, &home)) < 0) {
-               /* home lookup failed - shouldn't really happen */
-               return TRUE;
-       }
-       if (ret == 0) {
-               i_warning("autoexpunge: User has no home directory, can't lock");
-               return TRUE;
-       }
-
-       const struct mail_storage_settings *mail_set =
-               mail_user_set_get_storage_set(user);
-       i_zero(&lock_set);
-       lock_set.lock_method = mail_set->parsed_lock_method;
-       path = t_strdup_printf("%s/"AUTOEXPUNGE_LOCK_FNAME, home);
-       if (file_create_locked(path, &lock_set, lock, &created, &error) == -1) {
-               if (errno == EAGAIN) {
-                       /* another process is autoexpunging, so we don't
-                          need to. */
-                       return FALSE;
-               }
-               i_error("autoexpunge: Couldn't lock %s: %s", path, error);
+       ret = mail_user_lock_file_create(user, AUTOEXPUNGE_LOCK_FNAME,
+                                        0, lock, &error);
+       if (ret < 0) {
+               i_error("autoexpunge: Couldn't create %s lock: %s",
+                       AUTOEXPUNGE_LOCK_FNAME, error);
                /* do autoexpunging anyway */
                return TRUE;
+       } else if (ret == 0) {
+               /* another process is autoexpunging, so we don't need to. */
+               return FALSE;
+       } else {
+               return TRUE;
        }
-       file_lock_set_unlink_on_free(*lock, TRUE);
-       file_lock_set_close_on_free(*lock, TRUE);
-       return TRUE;
 }
 
 static int
index 9ddfe083ef2babacb54e06f98d44ffb1a52e87af..b84113b24c1a75b16927faaa32a7b752839915cb 100644 (file)
@@ -7,6 +7,7 @@
 #include "net.h"
 #include "module-dir.h"
 #include "home-expand.h"
+#include "file-create-locked.h"
 #include "safe-mkstemp.h"
 #include "str.h"
 #include "strescape.h"
@@ -537,6 +538,42 @@ void mail_user_set_get_temp_prefix(string_t *dest,
        str_append_c(dest, '.');
 }
 
+int mail_user_lock_file_create(struct mail_user *user, const char *lock_fname,
+                              unsigned int lock_secs,
+                              struct file_lock **lock_r, const char **error_r)
+{
+       bool created;
+       const char *home, *path, *error;
+       int ret;
+
+       if ((ret = mail_user_get_home(user, &home)) < 0) {
+               /* home lookup failed - shouldn't really happen */
+               *error_r = "Failed to lookup home directory";
+               errno = EINVAL;
+               return -1;
+       }
+       if (ret == 0) {
+               *error_r = "User has no home directory";
+               errno = EINVAL;
+               return -1;
+       }
+
+       const struct mail_storage_settings *mail_set =
+               mail_user_set_get_storage_set(user);
+       struct file_create_settings lock_set = {
+               .lock_timeout_secs = lock_secs,
+               .lock_method = mail_set->parsed_lock_method,
+       };
+       path = t_strdup_printf("%s/%s", home, lock_fname);
+       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;
+       }
+       file_lock_set_unlink_on_free(*lock_r, TRUE);
+       file_lock_set_close_on_free(*lock_r, TRUE);
+       return 1;
+}
+
 const char *mail_user_get_anvil_userip_ident(struct mail_user *user)
 {
        if (user->remote_ip == NULL)
index 47bf4ba4eaf40b02020bdd70a9bf8da12b1a406b..3b3b0c11098b20fe6b1c4c235ba02fcec82fc513 100644 (file)
@@ -152,6 +152,10 @@ int mail_user_get_home(struct mail_user *user, const char **home_r);
    The file prefix doesn't contain any uniqueness. */
 void mail_user_set_get_temp_prefix(string_t *dest,
                                   const struct mail_user_settings *set);
+/* Returns 1 on success, 0 if lock_secs is reached, -1 on error */
+int mail_user_lock_file_create(struct mail_user *user, const char *lock_fname,
+                              unsigned int lock_secs,
+                              struct file_lock **lock_r, const char **error_r);
 
 /* Returns TRUE if plugin is loaded for the user. */
 bool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module);