Mercurial > dovecot > core-2.2
changeset 3981:0d64f8888dcd HEAD
Removed immediate_stale_timeout and changed the stale_timeout behavior to
check both dotlock and the file it protects, and overwrite the lock file
whenever neither of them have been modified for stale_timeout seconds (ie.
also immediately if their timestamps are old enough).
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 05 Feb 2006 14:46:07 +0200 |
parents | 90638cc0d4e4 |
children | 15c48c43cc75 |
files | src/lib-index/mail-cache-private.h src/lib-index/mail-cache.c src/lib-index/mail-transaction-log.c src/lib-storage/index/dbox/dbox-sync.c src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/index/mbox/mbox-lock.c src/lib-storage/subscription-file/subscription-file.c src/lib/file-dotlock.c src/lib/file-dotlock.h src/plugins/convert/convert-storage.c |
diffstat | 10 files changed, 59 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-cache-private.h Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib-index/mail-cache-private.h Sun Feb 05 14:46:07 2006 +0200 @@ -31,7 +31,6 @@ #define MAIL_CACHE_LOCK_TIMEOUT 120 #define MAIL_CACHE_LOCK_CHANGE_TIMEOUT 60 -#define MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT (5*60) #define CACHE_RECORD(cache, offset) \ ((const struct mail_cache_record *) \
--- a/src/lib-index/mail-cache.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib-index/mail-cache.c Sun Feb 05 14:46:07 2006 +0200 @@ -278,8 +278,6 @@ cache->dotlock_settings.timeout = MAIL_CACHE_LOCK_TIMEOUT; cache->dotlock_settings.stale_timeout = MAIL_CACHE_LOCK_CHANGE_TIMEOUT; - cache->dotlock_settings.immediate_stale_timeout = - MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT; if (!MAIL_INDEX_IS_IN_MEMORY(index)) { if (index->mmap_disable || index->mmap_no_write)
--- a/src/lib-index/mail-transaction-log.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib-index/mail-transaction-log.c Sun Feb 05 14:46:07 2006 +0200 @@ -21,8 +21,7 @@ /* this lock should never exist for a long time.. */ #define LOG_DOTLOCK_TIMEOUT 60 -#define LOG_DOTLOCK_STALE_TIMEOUT 0 -#define LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT 60 +#define LOG_DOTLOCK_STALE_TIMEOUT 60 #define MAIL_TRANSACTION_LOG_SUFFIX ".log" #define LOG_NEW_DOTLOCK_SUFFIX ".newlock" @@ -230,8 +229,6 @@ log->dotlock_settings.timeout = LOG_DOTLOCK_TIMEOUT; log->dotlock_settings.stale_timeout = LOG_DOTLOCK_STALE_TIMEOUT; - log->dotlock_settings.immediate_stale_timeout = - LOG_DOTLOCK_IMMEDIATE_STALE_TIMEOUT; log->new_dotlock_settings = log->dotlock_settings; log->new_dotlock_settings.lock_suffix = LOG_NEW_DOTLOCK_SUFFIX;
--- a/src/lib-storage/index/dbox/dbox-sync.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-sync.c Sun Feb 05 14:46:07 2006 +0200 @@ -253,6 +253,9 @@ unsigned int first_flag_offset; int ret; + if (ctx->mbox->file->keyword_count == 0) + return 0; + t_push(); keyword_array = t_malloc(ctx->mbox->file->keyword_count); keyword_mask = t_malloc(ctx->mbox->file->keyword_count);
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Sun Feb 05 14:46:07 2006 +0200 @@ -17,7 +17,7 @@ #include <utime.h> /* how many seconds to wait before overriding uidlist.lock */ -#define UIDLIST_LOCK_STALE_TIMEOUT (60*5) +#define UIDLIST_LOCK_STALE_TIMEOUT (60*2) #define UIDLIST_IS_LOCKED(uidlist) \ ((uidlist)->lock_count > 0) @@ -148,10 +148,8 @@ maildir_hash, maildir_cmp); uidlist->next_uid = 1; - uidlist->dotlock_settings.timeout = UIDLIST_LOCK_STALE_TIMEOUT; + uidlist->dotlock_settings.timeout = UIDLIST_LOCK_STALE_TIMEOUT + 2; uidlist->dotlock_settings.stale_timeout = UIDLIST_LOCK_STALE_TIMEOUT; - uidlist->dotlock_settings.immediate_stale_timeout = - UIDLIST_LOCK_STALE_TIMEOUT; uidlist->dotlock_settings.temp_prefix = INDEX_STORAGE(mbox->storage)->temp_prefix;
--- a/src/lib-storage/index/mbox/mbox-lock.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib-storage/index/mbox/mbox-lock.c Sun Feb 05 14:46:07 2006 +0200 @@ -25,7 +25,7 @@ /* lock timeout */ #define DEFAULT_LOCK_TIMEOUT (10*60) /* assume stale dotlock if mbox file hasn't changed for n seconds */ -#define DEFAULT_DOTLOCK_CHANGE_TIMEOUT (5*60) +#define DEFAULT_DOTLOCK_CHANGE_TIMEOUT (10) enum mbox_lock_type { MBOX_LOCK_DOTLOCK,
--- a/src/lib-storage/subscription-file/subscription-file.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib-storage/subscription-file/subscription-file.c Sun Feb 05 14:46:07 2006 +0200 @@ -14,7 +14,6 @@ #define SUBSCRIPTION_FILE_LOCK_TIMEOUT 120 #define SUBSCRIPTION_FILE_CHANGE_TIMEOUT 30 -#define SUBSCRIPTION_FILE_IMMEDIATE_TIMEOUT (5*60) struct subsfile_list_context { pool_t pool; @@ -85,7 +84,6 @@ dotlock_set.temp_prefix = temp_prefix; dotlock_set.timeout = SUBSCRIPTION_FILE_LOCK_TIMEOUT; dotlock_set.stale_timeout = SUBSCRIPTION_FILE_CHANGE_TIMEOUT; - dotlock_set.immediate_stale_timeout = SUBSCRIPTION_FILE_IMMEDIATE_TIMEOUT; /* FIXME: set lock notification callback */ fd_out = file_dotlock_open(&dotlock_set, path, 0, &dotlock);
--- a/src/lib/file-dotlock.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib/file-dotlock.c Sun Feb 05 14:46:07 2006 +0200 @@ -32,22 +32,24 @@ time_t lock_time; }; +struct file_change_info { + dev_t dev; + ino_t ino; + off_t size; + time_t ctime, mtime; +}; + struct lock_info { const struct dotlock_settings *set; const char *path, *lock_path, *temp_path; int fd; - dev_t dev; - ino_t ino; - off_t size; - time_t ctime, mtime; - - off_t last_size; - time_t last_ctime, last_mtime; - time_t last_change; + struct file_change_info lock_info; + struct file_change_info file_info; bool have_pid; time_t last_pid_check; + time_t last_change; }; static struct dotlock * @@ -100,10 +102,33 @@ return (pid_t)strtoul(buf, NULL, 0); } +static bool +update_change_info(const struct stat *st, struct file_change_info *change, + time_t *last_change_r, time_t now) +{ + if (change->ino != st->st_ino || !CMP_DEV_T(change->dev, st->st_dev) || + change->ctime != st->st_ctime || change->mtime != st->st_mtime || + change->size != st->st_size) { + time_t change_time = now; + + if (change->ctime == 0) { + /* first check, set last_change to file's change time */ + change_time = I_MAX(st->st_ctime, st->st_mtime); + } + if (*last_change_r < change_time) + *last_change_r = change_time; + change->ino = st->st_ino; + change->dev = st->st_dev; + change->ctime = st->st_ctime; + change->mtime = st->st_mtime; + change->size = st->st_size; + return TRUE; + } + return FALSE; +} + static int check_lock(time_t now, struct lock_info *lock_info) { - time_t immediate_stale_timeout = - lock_info->set->immediate_stale_timeout; time_t stale_timeout = lock_info->set->stale_timeout; struct stat st; pid_t pid; @@ -116,32 +141,11 @@ return 1; } - if (lock_info->set->immediate_stale_timeout != 0 && - now > st.st_mtime + immediate_stale_timeout && - now > st.st_ctime + immediate_stale_timeout) { - /* old lock file */ - if (unlink(lock_info->lock_path) < 0 && errno != ENOENT) { - i_error("unlink(%s) failed: %m", lock_info->lock_path); - return -1; - } - return 1; - } - - if (lock_info->ino != st.st_ino || - !CMP_DEV_T(lock_info->dev, st.st_dev) || - lock_info->ctime != st.st_ctime || - lock_info->mtime != st.st_mtime || - lock_info->size != st.st_size) { + if (update_change_info(&st, &lock_info->lock_info, + &lock_info->last_change, now)) { /* either our first check or someone else got the lock file. */ - lock_info->dev = st.st_dev; - lock_info->ino = st.st_ino; - lock_info->ctime = st.st_ctime; - lock_info->mtime = st.st_mtime; - lock_info->size = st.st_size; - pid = read_local_pid(lock_info->lock_path); lock_info->have_pid = pid != -1; - lock_info->last_change = now; } else if (!lock_info->have_pid) { /* no pid checking */ pid = -1; @@ -181,7 +185,9 @@ return 0; } - if (lock_info->last_change != now) { + if (now > lock_info->last_change + stale_timeout) { + /* possibly stale lock file. check also the timestamp of the + file we're protecting. */ if (stat(lock_info->path, &st) < 0) { if (errno == ENOENT) { /* file doesn't exist. treat it as if @@ -190,13 +196,9 @@ i_error("stat(%s) failed: %m", lock_info->path); return -1; } - } else if (lock_info->last_size != st.st_size || - lock_info->last_ctime != st.st_ctime || - lock_info->last_mtime != st.st_mtime) { - lock_info->last_change = now; - lock_info->last_size = st.st_size; - lock_info->last_ctime = st.st_ctime; - lock_info->last_mtime = st.st_mtime; + } else { + (void)update_change_info(&st, &lock_info->file_info, + &lock_info->last_change, now); } } @@ -368,7 +370,6 @@ lock_info.path = path; lock_info.set = set; lock_info.lock_path = lock_path; - lock_info.last_change = now; lock_info.fd = -1; last_notify = 0; do_wait = FALSE;
--- a/src/lib/file-dotlock.h Sun Feb 05 14:08:13 2006 +0200 +++ b/src/lib/file-dotlock.h Sun Feb 05 14:46:07 2006 +0200 @@ -17,11 +17,9 @@ /* Abort after this many seconds. */ unsigned int timeout; - /* If file specified in path doesn't change in stale_timeout seconds - and it's still locked, override the lock file. */ + /* Override the lock file when it and the file we're protecting is + older than stale_timeout. */ unsigned int stale_timeout; - /* If file is older than this, override the lock immediately. */ - unsigned int immediate_stale_timeout; /* Callback is called once in a while. stale is set to TRUE if stale lock is detected and will be overridden in secs_left. If callback
--- a/src/plugins/convert/convert-storage.c Sun Feb 05 14:08:13 2006 +0200 +++ b/src/plugins/convert/convert-storage.c Sun Feb 05 14:46:07 2006 +0200 @@ -11,17 +11,16 @@ #define CONVERT_LOCK_FILENAME ".dovecot.convert" const struct dotlock_settings dotlock_settings = { - NULL, - NULL, + MEMBER(temp_prefix) NULL, + MEMBER(lock_suffix) NULL, - 60*5, - 0, - 60*5, + MEMBER(timeout) 60*5, + MEMBER(stale_timeout) 60*5, - NULL, - NULL, + MEMBER(callback) NULL, + MEMBER(context) NULL, - FALSE + MEMBER(use_excl_lock) FALSE }; static int sync_mailbox(struct mailbox *box)