Lines Matching defs:log
10 #include "mail-transaction-log-private.h"
17 mail_transaction_log_set_head(struct mail_transaction_log *log,
20 i_assert(log->head != file);
23 log->head = file;
25 i_assert(log->files != NULL);
26 i_assert(log->files->next != NULL || log->files == file);
32 struct mail_transaction_log *log;
34 log = i_new(struct mail_transaction_log, 1);
35 log->index = index;
36 return log;
39 static void mail_transaction_log_2_unlink_old(struct mail_transaction_log *log)
42 uint32_t log2_rotate_time = log->index->map->hdr.log2_rotate_time;
44 if (MAIL_INDEX_IS_IN_MEMORY(log->index))
48 if (nfs_safe_stat(log->filepath2, &st) == 0)
53 mail_index_set_error(log->index,
54 "stat(%s) failed: %m", log->filepath2);
60 ioloop_time - (time_t)log2_rotate_time >= (time_t)log->index->optimization_set.log.log2_max_age_secs &&
61 !log->index->readonly) {
62 i_unlink_if_exists(log->filepath2);
66 if (log2_rotate_time != log->index->map->hdr.log2_rotate_time) {
71 log->index->pending_log2_rotate_time = log2_rotate_time;
75 int mail_transaction_log_open(struct mail_transaction_log *log)
81 i_free(log->filepath);
82 i_free(log->filepath2);
83 log->filepath = i_strconcat(log->index->filepath,
85 log->filepath2 = i_strconcat(log->filepath, ".2", NULL);
89 log->nfs_flush =
90 (log->index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0;
92 if (log->open_file != NULL)
93 mail_transaction_log_file_free(&log->open_file);
95 if (MAIL_INDEX_IS_IN_MEMORY(log->index))
98 file = mail_transaction_log_file_alloc(log, log->filepath);
101 log->open_file = file;
104 mail_transaction_log_set_head(log, file);
108 int mail_transaction_log_create(struct mail_transaction_log *log, bool reset)
112 if (MAIL_INDEX_IS_IN_MEMORY(log->index)) {
113 file = mail_transaction_log_file_alloc_in_memory(log);
114 mail_transaction_log_set_head(log, file);
118 file = mail_transaction_log_file_alloc(log, log->filepath);
119 if (log->open_file != NULL) {
122 file->st_ino = log->open_file->st_ino;
123 file->st_dev = log->open_file->st_dev;
124 file->last_size = log->open_file->last_size;
125 file->last_mtime = log->open_file->last_mtime;
126 mail_transaction_log_file_free(&log->open_file);
134 mail_transaction_log_set_head(log, file);
138 void mail_transaction_log_close(struct mail_transaction_log *log)
140 i_assert(log->views == NULL);
142 if (log->open_file != NULL)
143 mail_transaction_log_file_free(&log->open_file);
144 if (log->head != NULL)
145 log->head->refcount--;
146 mail_transaction_logs_clean(log);
147 i_assert(log->files == NULL);
152 struct mail_transaction_log *log = *_log;
156 mail_transaction_log_close(log);
157 log->index->log = NULL;
158 i_free(log->filepath);
159 i_free(log->filepath2);
160 i_free(log);
163 int mail_transaction_log_move_to_memory(struct mail_transaction_log *log)
167 if (!log->index->initial_mapped && log->files != NULL &&
168 log->files->hdr.prev_file_seq != 0) {
170 .log file, so just start from scratch */
171 mail_transaction_log_close(log);
174 i_free(log->filepath);
175 i_free(log->filepath2);
176 log->filepath = i_strconcat(log->index->filepath,
178 log->filepath2 = i_strconcat(log->filepath, ".2", NULL);
180 if (log->head != NULL)
181 return mail_transaction_log_file_move_to_memory(log->head);
183 file = mail_transaction_log_file_alloc_in_memory(log);
184 mail_transaction_log_set_head(log, file);
189 void mail_transaction_log_indexid_changed(struct mail_transaction_log *log)
193 mail_transaction_logs_clean(log);
195 for (file = log->files; file != NULL; file = file->next) {
196 if (file->hdr.indexid != log->index->indexid) {
199 file->hdr.indexid, log->index->indexid);
203 if (log->head != NULL &&
204 log->head->hdr.indexid != log->index->indexid) {
205 if (--log->head->refcount == 0)
206 mail_transaction_log_file_free(&log->head);
207 (void)mail_transaction_log_create(log, FALSE);
211 void mail_transaction_logs_clean(struct mail_transaction_log *log)
218 for (file = log->files; file != NULL; file = next) {
231 i_assert(log->head == NULL || log->files != NULL);
234 bool mail_transaction_log_want_rotate(struct mail_transaction_log *log)
236 struct mail_transaction_log_file *file = log->head;
244 /* upgrade immediately to a new log file format */
248 if (file->sync_offset > log->index->optimization_set.log.max_size) {
252 if (file->sync_offset < log->index->optimization_set.log.min_size) {
258 ioloop_time - log->index->optimization_set.log.min_age_secs;
261 int mail_transaction_log_rotate(struct mail_transaction_log *log, bool reset)
264 const char *path = log->head->filepath;
268 i_assert(log->head->locked);
270 if (MAIL_INDEX_IS_IN_MEMORY(log->index)) {
271 file = mail_transaction_log_file_alloc_in_memory(log);
279 if (fstat(log->head->fd, &st) < 0) {
280 mail_index_file_set_syscall_error(log->index,
281 log->head->filepath, "fstat()");
285 file = mail_transaction_log_file_alloc(log, path);
297 mail_index_set_error(log->index,
298 "Transaction log %s was recreated while we had it locked - "
300 file_lock_method_to_str(log->index->lock_method));
307 if (--log->head->refcount == 0)
308 mail_transaction_logs_clean(log);
310 /* the newly created log file is already locked */
311 mail_transaction_log_file_unlock(log->head,
312 !log->index->log_sync_locked ? "rotating" :
315 mail_transaction_log_set_head(log, file);
320 mail_transaction_log_refresh(struct mail_transaction_log *log, bool nfs_flush,
326 i_assert(log->head != NULL);
328 if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(log->head)) {
333 if (nfs_flush && log->nfs_flush)
334 nfs_flush_file_handle_cache(log->filepath);
335 if (nfs_safe_stat(log->filepath, &st) < 0) {
337 mail_index_file_set_syscall_error(log->index,
338 log->filepath,
340 *reason_r = t_strdup_printf("stat(%s) failed: %m", log->filepath);
343 /* We shouldn't lose dovecot.index.log unless the mailbox was
345 opening code figure out whether to create a new log file
349 log->index->index_deleted = TRUE;
350 *reason_r = "Trasnaction log lost while it was open";
352 } else if (log->head->st_ino == st.st_ino &&
353 CMP_DEV_T(log->head->st_dev, st.st_dev)) {
354 /* NFS: log files get rotated to .log.2 files instead
363 file = mail_transaction_log_file_alloc(log, log->filepath);
371 if (--log->head->refcount == 0)
372 mail_transaction_logs_clean(log);
373 mail_transaction_log_set_head(log, file);
378 void mail_transaction_log_get_mailbox_sync_pos(struct mail_transaction_log *log,
382 *file_seq_r = log->head->hdr.file_seq;
383 *file_offset_r = log->head->max_tail_offset;
386 void mail_transaction_log_set_mailbox_sync_pos(struct mail_transaction_log *log,
390 i_assert(file_seq == log->head->hdr.file_seq);
391 i_assert(file_offset >= log->head->saved_tail_offset);
393 if (file_offset >= log->head->max_tail_offset)
394 log->head->max_tail_offset = file_offset;
397 int mail_transaction_log_find_file(struct mail_transaction_log *log,
406 if (file_seq > log->head->hdr.file_seq) {
407 /* see if the .log file has been recreated */
408 if (log->head->locked) {
409 /* transaction log is locked. there's no way a newer
411 *reason_r = "Log is locked - newer log can't exist";
415 if (mail_transaction_log_refresh(log, FALSE, &reason) < 0) {
419 if (file_seq > log->head->hdr.file_seq) {
420 if (!nfs_flush || !log->nfs_flush) {
422 "Requested newer log than exists: %s", reason);
426 if (mail_transaction_log_refresh(log, TRUE, &reason) < 0) {
431 if (file_seq > log->head->hdr.file_seq) {
433 "Requested newer log than exists - "
440 for (file = log->files; file != NULL; file = file->next) {
448 open .log.2 that most likely doesn't even exist. */
454 if (MAIL_INDEX_IS_IN_MEMORY(log->index)) {
459 /* see if we have it in log.2 file */
460 file = mail_transaction_log_file_alloc(log, log->filepath2);
468 *reason_r = t_strdup_printf(".log.2 contains file_seq=%u",
477 int mail_transaction_log_lock_head(struct mail_transaction_log *log,
486 since by the time we have it locked a new log file may have been
489 creating new log file requires locking the head file, so if we
491 creating a new log at the moment */
495 file = log->head;
500 ret = mail_transaction_log_refresh(log, TRUE, &reason);
504 mail_transaction_logs_clean(log);
508 if (ret == 0 && log->head == file) {
525 i_warning("Locking transaction log file %s took %ld seconds (%s)",
526 log->head->filepath, (long)lock_secs, lock_reason);
529 i_assert(ret < 0 || log->head != NULL);
533 int mail_transaction_log_sync_lock(struct mail_transaction_log *log,
539 i_assert(!log->index->log_sync_locked);
541 if (!log->log_2_unlink_checked) {
542 /* we need to check once in a while if .log.2 should be deleted
548 log->log_2_unlink_checked = TRUE;
549 mail_transaction_log_2_unlink_old(log);
552 if (mail_transaction_log_lock_head(log, lock_reason) < 0)
556 if (mail_transaction_log_file_map(log->head, log->head->sync_offset,
558 mail_index_set_error(log->index,
559 "Failed to map transaction log %s at "
561 log->head->filepath, log->head->sync_offset, reason);
562 mail_transaction_log_file_unlock(log->head, t_strdup_printf(
567 log->index->log_sync_locked = TRUE;
568 *file_seq_r = log->head->hdr.file_seq;
569 *file_offset_r = log->head->sync_offset;
573 void mail_transaction_log_sync_unlock(struct mail_transaction_log *log,
576 i_assert(log->index->log_sync_locked);
578 log->index->log_sync_locked = FALSE;
579 mail_transaction_log_file_unlock(log->head, lock_reason);
582 void mail_transaction_log_get_head(struct mail_transaction_log *log,
585 *file_seq_r = log->head->hdr.file_seq;
586 *file_offset_r = log->head->sync_offset;
589 void mail_transaction_log_get_tail(struct mail_transaction_log *log,
592 struct mail_transaction_log_file *tail, *file = log->files;
601 bool mail_transaction_log_is_head_prev(struct mail_transaction_log *log,
604 return log->head->hdr.prev_file_seq == file_seq &&
605 log->head->hdr.prev_file_offset == file_offset;
608 int mail_transaction_log_unlink(struct mail_transaction_log *log)
610 if (unlink(log->filepath) < 0 &&
612 mail_index_file_set_syscall_error(log->index, log->filepath,
619 void mail_transaction_log_get_dotlock_set(struct mail_transaction_log *log,
622 struct mail_index *index = log->index;