Пример #1
0
static void
log_reader_update_watches(LogReader *self)
{
  GIOCondition cond;
  gboolean free_to_send;
  gboolean line_is_ready_in_buffer;

  main_loop_assert_main_thread();

  if (!log_reader_is_opened(self))
    return;

  log_reader_start_watches_if_stopped(self);

  free_to_send = log_source_free_to_send(&self->super);
  if (!free_to_send)
    {
      log_reader_suspend_until_awoken(self);
      return;
    }

  line_is_ready_in_buffer = log_proto_server_prepare(self->proto, &cond);
  if (self->immediate_check || line_is_ready_in_buffer)
    {
      log_reader_force_check_in_next_poll(self);
      return;
    }
  poll_events_update_watches(self->poll_events, cond);
}
Пример #2
0
static void
log_reader_update_watches(LogReader *self)
{
  GIOCondition cond;
  gint idle_timeout = -1;

  main_loop_assert_main_thread();

  log_reader_stop_idle_timer(self);

  if (!log_reader_is_opened(self))
    return;

  log_reader_start_watches_if_stopped(self);

  gboolean free_to_send = log_source_free_to_send(&self->super);
  if (!free_to_send)
    {
      log_reader_suspend_until_awoken(self);
      return;
    }

  LogProtoPrepareAction prepare_action = log_proto_server_prepare(self->proto, &cond, &idle_timeout);

  if (idle_timeout > 0)
    {
      iv_validate_now();

      self->idle_timer.expires = iv_now;
      self->idle_timer.expires.tv_sec += idle_timeout;

      iv_timer_register(&self->idle_timer);
    }

  if (self->immediate_check)
    {
      log_reader_force_check_in_next_poll(self);
      return;
    }

  switch (prepare_action)
    {
    case LPPA_POLL_IO:
      poll_events_update_watches(self->poll_events, cond);
      break;
    case LPPA_FORCE_SCHEDULE_FETCH:
      log_reader_force_check_in_next_poll(self);
      break;
    case LPPA_SUSPEND:
      log_reader_suspend_until_awoken(self);
      break;
    default:
      g_assert_not_reached();
      break;
    }
}
Пример #3
0
static void
_update_watches(JournalReader *self)
{
    gboolean free_to_send;

    main_loop_assert_main_thread();

    _start_watches_if_stopped(self);

    free_to_send = log_source_free_to_send(&self->super);
    if (!free_to_send)
    {
        _suspend_until_awoken(self);
        return;
    }

    if (self->immediate_check)
    {
        _force_check_in_next_poll(self);
        return;
    }
    poll_events_update_watches(self->poll_events, G_IO_IN);
}
Пример #4
0
/* follow timer callback. Check if the file has new content, or deleted or
 * moved.  Ran every follow_freq seconds.  */
static void
poll_file_changes_check_file(gpointer s)
{
  PollFileChanges *self = (PollFileChanges *) s;
  struct stat st, followed_st;
  off_t pos = -1;
  gint fd = self->fd;

  msg_trace("Checking if the followed file has new lines",
            evt_tag_str("follow_filename", self->follow_filename));
  if (fd >= 0)
    {
      pos = lseek(fd, 0, SEEK_CUR);
      if (pos == (off_t) -1)
        {
          msg_error("Error invoking seek on followed file",
                    evt_tag_errno("error", errno));
          goto reschedule;
        }

      if (fstat(fd, &st) < 0)
        {
          if (errno == ESTALE)
            {
              msg_trace("log_reader_fd_check file moved ESTALE",
                        evt_tag_str("follow_filename", self->follow_filename));
              log_pipe_notify(self->control, NC_FILE_MOVED, self);
              return;
            }
          else
            {
              msg_error("Error invoking fstat() on followed file",
                        evt_tag_errno("error", errno));
              goto reschedule;
            }
        }

      msg_trace("log_reader_fd_check",
                evt_tag_int("pos", pos),
                evt_tag_int("size", st.st_size));

      if (pos < st.st_size || !S_ISREG(st.st_mode))
        {
          /* we have data to read */
          poll_events_invoke_callback(s);
          return;
        }
      else if (pos == st.st_size)
        {
          /* we are at EOF */
          log_pipe_notify(self->control, NC_FILE_EOF, self);
        }
      else if (pos > st.st_size)
        {
          /* the last known position is larger than the current size of the file. it got truncated. Restart from the beginning. */
          log_pipe_notify(self->control, NC_FILE_MOVED, self);

          /* we may be freed by the time the notification above returns */
          return;
        }
    }

  if (self->follow_filename)
    {
      if (stat(self->follow_filename, &followed_st) != -1)
        {
          if (fd < 0 || (st.st_ino != followed_st.st_ino && followed_st.st_size > 0))
            {
              msg_trace("log_reader_fd_check file moved eof",
                        evt_tag_int("pos", pos),
                        evt_tag_int("size", followed_st.st_size),
                        evt_tag_str("follow_filename", self->follow_filename));
              /* file was moved and we are at EOF, follow the new file */
              log_pipe_notify(self->control, NC_FILE_MOVED, self);
              /* we may be freed by the time the notification above returns */
              return;
            }
        }
      else
        {
          msg_verbose("Follow mode file still does not exist",
                      evt_tag_str("filename", self->follow_filename));
        }
    }
reschedule:
  poll_events_update_watches(s, G_IO_IN);
}