static inline gboolean _has_movable_message(LogQueueDiskNonReliable *self) { return self->qoverflow->length > 0 && ((HAS_SPACE_IN_QUEUE(self->qout) && qdisk_get_length (self->super.qdisk) == 0) || qdisk_is_space_avail (self->super.qdisk, 4096)); }
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; }
gboolean qdisk_push_tail(QDisk *self, GString *record) { guint32 n = GUINT32_TO_BE(record->len); /* write follows read (e.g. we are appending to the file) OR * there's enough space between write and read. * * If write follows read we need to check two things: * - either we are below the maximum limit (GINT64_FROM_BE(self->hdr->write_head) < self->options->disk_buf_size) * - or we can wrap around (GINT64_FROM_BE(self->hdr->read_head) != QDISK_RESERVED_SPACE) * If neither of the above is true, the buffer is full. */ if (!qdisk_is_space_avail(self, record->len)) return FALSE; if (n == 0) { msg_error("Error writing empty message into the disk-queue file"); return FALSE; } if (!pwrite_strict(self->fd, (gchar *) &n, sizeof(n), self->hdr->write_head) || !pwrite_strict(self->fd, record->str, record->len, self->hdr->write_head + sizeof(n))) { msg_error("Error writing disk-queue file", evt_tag_errno("error", errno)); return FALSE; } self->hdr->write_head = self->hdr->write_head + record->len + sizeof(n); /* NOTE: we only wrap around if the read head is before the write, * otherwise we'd truncate the data the read head is still processing, e.g. * * start limit file size * | | | * ^ read ^write * * We can truncate in the scenario above, once we surpass the limit, * however if this is the case: * * start limit file size * | | | * ^write ^read * * In this case cannot wrap around, even if the limit is surpassed, as * in that case data still unprocessed by the read head would be lost. * This can happen if the size of the queue file got decreased while * it still had more data. * */ /* NOTE: if these were equal, that'd mean the queue is empty, so we spoiled something */ g_assert(self->hdr->write_head != self->hdr->backlog_head); if (self->hdr->write_head > MAX(self->hdr->backlog_head,self->hdr->read_head)) { if (self->file_size > self->hdr->write_head) { _truncate_file(self, self->hdr->write_head); } self->file_size = self->hdr->write_head; if (self->hdr->write_head > self->options->disk_buf_size && self->hdr->backlog_head != QDISK_RESERVED_SPACE) { /* we were appending to the file, we are over the limit, and space * is available before the read head. truncate and wrap. * * Otherwise we let the write_head over size limits for a bit and * for the next message, the condition at the beginning of this * function will cause the push to fail */ self->hdr->write_head = QDISK_RESERVED_SPACE; } } self->hdr->length++; return TRUE; }