static gboolean _load_queue (LogQueueDisk *s, const gchar *filename) { /* qdisk portion is not yet started when this happens */ g_assert(!qdisk_initialized (s->qdisk)); return _start(s, filename); }
static gint64 _get_length(LogQueue *s) { LogQueueDisk *self = (LogQueueDisk *) s; gint64 qdisk_length = 0; if (qdisk_initialized(self->qdisk) && self->get_length) { qdisk_length = self->get_length(self); } return qdisk_length; }
gboolean log_queue_disk_load_queue(LogQueue *s, const gchar *filename) { LogQueueDisk *self = (LogQueueDisk *) s; /* qdisk portion is not yet started when this happens */ g_assert(!qdisk_initialized(self->qdisk)); if (self->load_queue) return self->load_queue(self, filename); return FALSE; }
gboolean log_queue_disk_save_queue(LogQueue *s, gboolean *persistent) { LogQueueDisk *self = (LogQueueDisk *) s; if (!qdisk_initialized(self->qdisk)) { *persistent = FALSE; return TRUE; } if (self->save_queue) return self->save_queue(self, persistent); return FALSE; }
static gboolean _write_message(LogQueueDisk *self, LogMessage *msg) { GString *serialized; SerializeArchive *sa; gboolean consumed = FALSE; if (qdisk_initialized(self->qdisk) && qdisk_is_space_avail(self->qdisk, 64)) { serialized = g_string_sized_new(64); sa = serialize_string_archive_new(serialized); log_msg_serialize(msg, sa); consumed = qdisk_push_tail(self->qdisk, serialized); serialize_archive_free(sa); g_string_free(serialized, TRUE); } return consumed; }
static gboolean _pop_disk(LogQueueDisk *self, LogMessage **msg) { GString *serialized; SerializeArchive *sa; *msg = NULL; if (!qdisk_initialized(self->qdisk)) return FALSE; serialized = g_string_sized_new(64); if (!qdisk_pop_head(self->qdisk, serialized)) { g_string_free(serialized, TRUE); return FALSE; } sa = serialize_string_archive_new(serialized); *msg = log_msg_new_empty(); if (!log_msg_deserialize(*msg, sa)) { g_string_free(serialized, TRUE); serialize_archive_free(sa); log_msg_unref(*msg); *msg = NULL; msg_error("Can't read correct message from disk-queue file",evt_tag_str("filename",qdisk_get_filename(self->qdisk)),NULL); return TRUE; } serialize_archive_free(sa); g_string_free(serialized, TRUE); return TRUE; }
gboolean qdisk_start(QDisk *self, const gchar *filename, GQueue *qout, GQueue *qbacklog, GQueue *qoverflow) { gboolean new_file = FALSE; gpointer p = NULL; int openflags = 0; /* * If qdisk_start is called for already initialized qdisk file * it can cause message loosing. * We need this assert to detect programming error as soon as possible. */ g_assert(!qdisk_initialized(self)); if (self->options->disk_buf_size <= 0) return TRUE; if (self->options->read_only && !filename) return FALSE; if (!filename) { new_file = TRUE; /* NOTE: this'd be a security problem if we were not in our private directory. But we are. */ filename = _next_filename(self); } else { struct stat st; if (stat(filename,&st) == -1) { new_file = TRUE; } } self->filename = g_strdup(filename); /* assumes self is zero initialized */ openflags = self->options->read_only ? (O_RDONLY | O_LARGEFILE) : (O_RDWR | O_LARGEFILE | (new_file ? O_CREAT : 0)); self->fd = open(filename, openflags, 0600); if (self->fd < 0) { msg_error("Error opening disk-queue file", evt_tag_str("filename", self->filename), evt_tag_errno("error", errno)); return FALSE; } p = mmap(0, sizeof(QDiskFileHeader), self->options->read_only ? (PROT_READ) : (PROT_READ | PROT_WRITE), MAP_SHARED, self->fd, 0); if (p == MAP_FAILED) { msg_error("Error returned by mmap", evt_tag_errno("errno", errno), evt_tag_str("filename", self->filename)); return FALSE; } else { madvise(p, sizeof(QDiskFileHeader), MADV_RANDOM); } if (self->options->read_only) { self->hdr = g_malloc(sizeof(QDiskFileHeader)); memcpy(self->hdr, p, sizeof(QDiskFileHeader)); munmap(p, sizeof(QDiskFileHeader) ); p = NULL; } else { self->hdr = p; } /* initialize new file */ if (new_file) { QDiskFileHeader tmp; memset(&tmp, 0, sizeof(tmp)); if (!pwrite_strict(self->fd, &tmp, sizeof(tmp), 0)) { msg_error("Error occured while initalizing the new queue file",evt_tag_str("filename",self->filename),evt_tag_errno("error",errno)); munmap((void *)self->hdr, sizeof(QDiskFileHeader)); self->hdr = NULL; close(self->fd); self->fd = -1; return FALSE; } self->hdr->version = 1; self->hdr->big_endian = (G_BYTE_ORDER == G_BIG_ENDIAN); self->hdr->read_head = QDISK_RESERVED_SPACE; self->hdr->write_head = QDISK_RESERVED_SPACE; self->hdr->backlog_head = self->hdr->read_head; self->hdr->length = 0; if (!qdisk_save_state(self, qout, qbacklog, qoverflow)) { munmap((void *)self->hdr, sizeof(QDiskFileHeader)); self->hdr = NULL; close(self->fd); self->fd = -1; return FALSE; } } else { struct stat st; if (fstat(self->fd, &st) != 0 || st.st_size == 0) { msg_error("Error loading disk-queue file", evt_tag_str("filename", self->filename), evt_tag_errno("fstat error", errno), evt_tag_int("size", st.st_size)); munmap((void *)self->hdr, sizeof(QDiskFileHeader)); self->hdr = NULL; close(self->fd); self->fd = -1; return FALSE; } if (self->hdr->version == 0) { self->hdr->big_endian = TRUE; self->hdr->version = 1; self->hdr->backlog_head = self->hdr->read_head; self->hdr->backlog_len = 0; } if ((self->hdr->big_endian && G_BYTE_ORDER == G_LITTLE_ENDIAN) || (!self->hdr->big_endian && G_BYTE_ORDER == G_BIG_ENDIAN)) { self->hdr->read_head = GUINT64_SWAP_LE_BE(self->hdr->read_head); self->hdr->write_head = GUINT64_SWAP_LE_BE(self->hdr->write_head); self->hdr->length = GUINT64_SWAP_LE_BE(self->hdr->length); self->hdr->qout_ofs = GUINT64_SWAP_LE_BE(self->hdr->qout_ofs); self->hdr->qout_len = GUINT32_SWAP_LE_BE(self->hdr->qout_len); self->hdr->qout_count = GUINT32_SWAP_LE_BE(self->hdr->qout_count); self->hdr->qbacklog_ofs = GUINT64_SWAP_LE_BE(self->hdr->qbacklog_ofs); self->hdr->qbacklog_len = GUINT32_SWAP_LE_BE(self->hdr->qbacklog_len); self->hdr->qbacklog_count = GUINT32_SWAP_LE_BE(self->hdr->qbacklog_count); self->hdr->qoverflow_ofs = GUINT64_SWAP_LE_BE(self->hdr->qoverflow_ofs); self->hdr->qoverflow_len = GUINT32_SWAP_LE_BE(self->hdr->qoverflow_len); self->hdr->qoverflow_count = GUINT32_SWAP_LE_BE(self->hdr->qoverflow_count); self->hdr->backlog_head = GUINT64_SWAP_LE_BE(self->hdr->backlog_head); self->hdr->backlog_len = GUINT64_SWAP_LE_BE(self->hdr->backlog_len); self->hdr->big_endian = (G_BYTE_ORDER == G_BIG_ENDIAN); } if (!_load_state(self, qout, qbacklog, qoverflow)) { munmap((void *)self->hdr, sizeof(QDiskFileHeader)); self->hdr = NULL; close(self->fd); self->fd = -1; return FALSE; } } return TRUE; }