mail-lockdir.c revision b045ca1be3be3c034584665f64ec3823c28c1229
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen/* 0.1 .. 0.2msec */
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen#define LOCK_RANDOM_USLEEP_TIME (100000 + (unsigned int)rand() % 100000)
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen/* The dirlock should be used only while creating the index file. After the
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen header is written, the file itself should be locked and dirlock dropped
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen before index is built. So, this value shouldn't be very large, probably
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen even a few seconds would more than enough but we'll use a safe 10 seconds
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen by default. */
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen/* Non-local locks have a life time of 30 minutes, just to be sure that
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen small clock differences won't break things. */
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainenstatic int mail_index_cleanup_dir_locks(const char *dir)
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen hostprefix = t_strconcat(DIRLOCK_FILE_PREFIX ".",
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen unlink_lockfiles(dir, hostprefix, DIRLOCK_FILE_PREFIX ".",
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen /* if hard link count has dropped to 1, we've unlocked the file */
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen path = t_strconcat(dir, "/" DIRLOCK_FILE_PREFIX, NULL);
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen if (stat(path, &st) == 0 && st.st_nlink == 1) {
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen /* only itself, safe to delete */
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainenstatic int mail_index_unlock_dir(MailIndex *index, const char *private_path,
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen return index_file_set_syscall_error(index, lockpath, "stat()");
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen /* make sure we're really the one who's locked it */
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen return index_file_set_syscall_error(index, private_path,
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen index_set_error(index, "Unlocking file %s failed: "
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen "we're not the lock owner "
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen /* first unlink the actual lock file */
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen index_file_set_syscall_error(index, lockpath, "unlink()");
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen /* non-fatal */
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen index_file_set_syscall_error(index, private_path, "unlink()");
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainenint mail_index_lock_dir(MailIndex *index, MailLockType lock_type)
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen /* use .dirlock.host.pid as our lock indicator file and
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen .dirlock as the real lock */
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen private_path = t_strconcat(index->dir, "/" DIRLOCK_FILE_PREFIX ".",
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen lockpath = t_strconcat(index->dir, "/" DIRLOCK_FILE_PREFIX, NULL);
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen return mail_index_unlock_dir(index, private_path, lockpath);
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen fd = open(private_path, O_RDWR | O_CREAT | O_EXCL, 0660);
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen index_file_set_syscall_error(index, private_path, "open()");
return FALSE;
return FALSE;
if (first) {
return FALSE;
return TRUE;