]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Index opening: If there's broken index and no .log, don't crash.
authorTimo Sirainen <tss@iki.fi>
Sun, 3 Aug 2008 22:41:39 +0000 (01:41 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 3 Aug 2008 22:41:39 +0000 (01:41 +0300)
--HG--
branch : HEAD

src/lib-index/mail-index-fsck.c

index 087a22bf18b4222fd089e99b921b771734de8e78..24d7e020474bf41ab4ed32e79319b7e4d436bb2d 100644 (file)
@@ -4,7 +4,7 @@
 #include "ioloop.h"
 #include "array.h"
 #include "mail-index-private.h"
-#include "mail-transaction-log.h"
+#include "mail-transaction-log-private.h"
 
 static void mail_index_fsck_error(struct mail_index *index,
                                  const char *fmt, ...) ATTR_FORMAT(2, 3);
@@ -26,17 +26,12 @@ static void mail_index_fsck_error(struct mail_index *index,
        }
 
 static void
-mail_index_fsck_header(struct mail_index *index, struct mail_index_map *map,
-                      struct mail_index_header *hdr)
+mail_index_fsck_log_pos(struct mail_index *index, struct mail_index_map *map,
+                       struct mail_index_header *hdr)
 {
        uint32_t file_seq;
        uoff_t file_offset;
 
-       /* mail_index_map_check_header() has already checked that the index
-          isn't completely broken. */
-       if (hdr->uid_validity == 0 && hdr->next_uid != 1)
-               hdr->uid_validity = ioloop_time;
-
        mail_transaction_log_get_head(index->log, &file_seq, &file_offset);
        if (hdr->log_file_seq < file_seq) {
                hdr->log_file_head_offset = hdr->log_file_tail_offset =
@@ -57,6 +52,19 @@ mail_index_fsck_header(struct mail_index *index, struct mail_index_map *map,
        }
 }
 
+static void
+mail_index_fsck_header(struct mail_index *index, struct mail_index_map *map,
+                      struct mail_index_header *hdr)
+{
+       /* mail_index_map_check_header() has already checked that the index
+          isn't completely broken. */
+       if (hdr->uid_validity == 0 && hdr->next_uid != 1)
+               hdr->uid_validity = ioloop_time;
+
+       if (index->log->head != NULL)
+               mail_index_fsck_log_pos(index, map, hdr);
+}
+
 static bool
 array_has_name(const ARRAY_TYPE(const_string) *names, const char *name)
 {
@@ -396,12 +404,13 @@ mail_index_fsck_map(struct mail_index *index, struct mail_index_map *map)
 {
        struct mail_index_header hdr;
 
-       /* Remember the log head position. If we go back in the index's head
-          offset, ignore errors in the log up to this offset. */
-       mail_transaction_log_get_head(index->log,
-                                     &index->fsck_log_head_file_seq,
-                                     &index->fsck_log_head_file_offset);
-
+       if (index->log->head != NULL) {
+               /* Remember the log head position. If we go back in the index's
+                  head offset, ignore errors in the log up to this offset. */
+               mail_transaction_log_get_head(index->log,
+                       &index->fsck_log_head_file_seq,
+                       &index->fsck_log_head_file_offset);
+       }
        hdr = map->hdr;
 
        mail_index_fsck_header(index, map, &hdr);
@@ -420,6 +429,13 @@ int mail_index_fsck(struct mail_index *index)
 
        i_warning("fscking index file %s", index->filepath);
 
+       if (index->log->head == NULL) {
+               /* we're trying to open the index files, but there wasn't
+                  any .log file. this should be rare, so just fsck it without
+                  locking. */
+               orig_locked = TRUE;
+       }
+
        if (!orig_locked) {
                if (mail_transaction_log_sync_lock(index->log, &file_seq,
                                                   &file_offset) < 0)