Esempio n. 1
0
/* easier to use string based interface */
gchar *
persist_state_lookup_string(PersistState *self, const gchar *key, gsize *length, guint8 *version)
{
  PersistEntryHandle handle;
  gpointer block;
  SerializeArchive *sa;
  gchar *result;
  gsize result_len, size;
  guint8 result_version;
  gboolean success;

  if (!(handle = persist_state_lookup_entry(self, key, &size, &result_version)))
    return NULL;
  block = persist_state_map_entry(self, handle);
  sa = serialize_buffer_archive_new(block, size);
  success = serialize_read_cstring(sa, &result, &result_len);
  serialize_archive_free(sa);
  persist_state_unmap_entry(self, handle);
  if (!success)
    return NULL;
  if (length)
    *length = result_len;
  if (version)
    *version = result_version;
  return result;
}
Esempio n. 2
0
static gboolean
_load_state(JournalReader *self)
{
  GlobalConfig *cfg = log_pipe_get_config(&self->super.super);

  gsize state_size;
  guint8 persist_version;

  self->persist_state = cfg->state;
  self->persist_handle = persist_state_lookup_entry(self->persist_state, self->persist_name, &state_size, &persist_version);
  return !!(self->persist_handle);
}
Esempio n. 3
0
void
test_persist_state_remove_entry(void)
{
    guint8 version;
    gsize size;

    PersistState *state = clean_and_create_persist_state_for_test("test_persist_state_remove_entry.persist");

    PersistEntryHandle handle = persist_state_alloc_entry(state, "test", sizeof(TestState));

    handle = persist_state_lookup_entry(state, "test", &size, &version);
    assert_true(handle != 0, "lookup failed before removing entry");

    persist_state_remove_entry(state, "test");

    state = restart_persist_state(state);

    handle = persist_state_lookup_entry(state, "test", &size, &version);
    assert_true(handle == 0, "lookup succeeded after removing entry");

    cancel_and_destroy_persist_state(state);
}
Esempio n. 4
0
int main(int argc, char** argv) {
	struct arguments args;

	set_default_args(&args);
	if (parse_args(argc, argv, &args)) {
		return 1;
	}

	PersistEntryHandle handle;
	struct journald_state* journald_state = NULL;

	msg_init(TRUE);
	PersistState* state = persist_state_new(args.filename);

	gsize state_size;
	guint8 persist_version;

	persist_state_start_dump(state);
	switch (args.action) {
	case LIST:
		persist_state_foreach_entry(state, &handle_entry, NULL);
	break;
	case SHOW_JOURNALD_CURSOR:
		handle = persist_state_lookup_entry(state, systemd_journal, &state_size, &persist_version);
		if (handle == 0)
			break;
		journald_state = persist_state_map_entry(state, handle);
		printf("journald cursor: %s\n", journald_state->cursor);
		persist_state_unmap_entry(state, handle);
	break;
	case SAVE_JOURNALD_CURSOR:
		handle = persist_state_alloc_entry(state, systemd_journal, sizeof(struct journald_state));
		if (handle == 0)
			break;
		journald_state = persist_state_map_entry(state, handle);
		journald_state->header.version = 0;
		journald_state->header.big_endian = (G_BYTE_ORDER == G_BIG_ENDIAN);
		strncpy(journald_state->cursor, args.action_arg.journald_cursor, MAX_CURSOR_LENGTH);
		persist_state_unmap_entry(state, handle);
		persist_state_commit(state);
	break;
	default:;
	}

	persist_state_free(state);
	msg_deinit();

	return 0;
}
Esempio n. 5
0
static guint32
load_hostid_from_persist(const gchar *persist_file)
{
  PersistState *state;
  PersistEntryHandle handle;
  HostIdState *host_id_state;
  gsize size;
  guint8 version;
  guint32 result;

  state = create_persist_state(persist_file);
  handle = persist_state_lookup_entry(state, HOST_ID_PERSIST_KEY, &size, &version);
  assert_true(handle != 0, "cannot find hostid in persist file");
  host_id_state = persist_state_map_entry(state, handle);
  result = host_id_state->host_id;
  persist_state_unmap_entry(state, handle);
  persist_state_free(state);
  return result;
}
Esempio n. 6
0
void
test_persist_state_not_in_use_handle_is_not_loaded(void)
{
    PersistState *state;
    guint8 version;
    gsize size;
    PersistEntryHandle handle;

    unlink("test_in_use.persist");
    write_test_file_for_test_in_use_handle(FALSE);

    state = create_persist_state_for_test("test_in_use.persist");

    handle = persist_state_lookup_entry(state, "alma", &size, &version);

    assert_true(handle == 0, "lookup succeeded when looking for simple entry with in_use = FALSE!");

    cancel_and_destroy_persist_state(state);
}
Esempio n. 7
0
void
test_persist_state_not_in_use_handle_is_loaded_in_dump_mode(void)
{
    PersistState *state;
    guint8 version;
    gsize size;
    PersistEntryHandle handle;

    unlink("test_in_use.persist");
    write_test_file_for_test_in_use_handle(FALSE);

    state = persist_state_new("test_in_use.persist");
    persist_state_start_dump(state);

    handle = persist_state_lookup_entry(state, "alma", &size, &version);

    assert_false(handle == 0, "lookup failed in dump mode when looking for simple entry with in_use = FALSE!");

    cancel_and_destroy_persist_state(state);
}
gboolean
log_proto_buffered_server_restart_with_state(LogProtoServer *s, PersistState *persist_state, const gchar *persist_name)
{
  LogProtoBufferedServer *self = (LogProtoBufferedServer *) s;
  guint8 persist_version;
  PersistEntryHandle old_state_handle;
  gpointer old_state;
  gsize old_state_size;
  PersistEntryHandle new_state_handle = 0;
  gpointer new_state = NULL;
  gboolean success;

  self->pos_tracking = TRUE;
  self->persist_state = persist_state;
  old_state_handle = persist_state_lookup_entry(persist_state, persist_name, &old_state_size, &persist_version);
  if (!old_state_handle)
    {
      new_state_handle = log_proto_buffered_server_alloc_state(self, persist_state, persist_name);
      if (!new_state_handle)
        goto fallback_non_persistent;
      log_proto_buffered_server_apply_state(self, new_state_handle, persist_name);
      return TRUE;
    }
  if (persist_version < 4)
    {
      new_state_handle = log_proto_buffered_server_alloc_state(self, persist_state, persist_name);
      if (!new_state_handle)
        goto fallback_non_persistent;

      old_state = persist_state_map_entry(persist_state, old_state_handle);
      new_state = persist_state_map_entry(persist_state, new_state_handle);
      success = log_proto_buffered_server_convert_state(self, persist_version, old_state, old_state_size, new_state);
      persist_state_unmap_entry(persist_state, old_state_handle);
      persist_state_unmap_entry(persist_state, new_state_handle);

      /* we're using the newly allocated state structure regardless if
       * conversion succeeded. If the conversion went wrong then
       * new_state is still in its freshly initialized form since the
       * convert function will not touch the state in the error
       * branches.
       */

      log_proto_buffered_server_apply_state(self, new_state_handle, persist_name);
      return success;
    }
  else if (persist_version == 4)
    {
      LogProtoBufferedServerState *state;

      old_state = persist_state_map_entry(persist_state, old_state_handle);
      state = old_state;
      if ((state->header.big_endian && G_BYTE_ORDER == G_LITTLE_ENDIAN) ||
          (!state->header.big_endian && G_BYTE_ORDER == G_BIG_ENDIAN))
        {

          /* byte order conversion in order to avoid the hassle with
             scattered byte order conversions in the code */

          state->header.big_endian = !state->header.big_endian;
          state->buffer_pos = GUINT32_SWAP_LE_BE(state->buffer_pos);
          state->pending_buffer_pos = GUINT32_SWAP_LE_BE(state->pending_buffer_pos);
          state->pending_buffer_end = GUINT32_SWAP_LE_BE(state->pending_buffer_end);
          state->buffer_size = GUINT32_SWAP_LE_BE(state->buffer_size);
          state->raw_stream_pos = GUINT64_SWAP_LE_BE(state->raw_stream_pos);
          state->raw_buffer_size = GUINT32_SWAP_LE_BE(state->raw_buffer_size);
          state->pending_raw_stream_pos = GUINT64_SWAP_LE_BE(state->pending_raw_stream_pos);
          state->pending_raw_buffer_size = GUINT32_SWAP_LE_BE(state->pending_raw_buffer_size);
          state->file_size = GUINT64_SWAP_LE_BE(state->file_size);
          state->file_inode = GUINT64_SWAP_LE_BE(state->file_inode);
        }

      if (state->header.version > 0)
        {
          msg_error("Internal error restoring log reader state, stored data is too new",
                    evt_tag_int("version", state->header.version));
          goto error;
        }
      persist_state_unmap_entry(persist_state, old_state_handle);
      log_proto_buffered_server_apply_state(self, old_state_handle, persist_name);
      return TRUE;
    }
  else
    {
      msg_error("Internal error restoring log reader state, stored data is too new",
                evt_tag_int("version", persist_version));
      goto error;
    }
  return TRUE;
 fallback_non_persistent:
  new_state = g_new0(LogProtoBufferedServerState, 1);
 error:
  if (!new_state)
    {
      new_state_handle = log_proto_buffered_server_alloc_state(self, persist_state, persist_name);
      if (!new_state_handle)
        goto fallback_non_persistent;
      new_state = persist_state_map_entry(persist_state, new_state_handle);
    }
  if (new_state)
    {
      LogProtoBufferedServerState *state = new_state;

      /* error happened,  restart the file from the beginning */
      state->raw_stream_pos = 0;
      state->file_inode = 0;
      state->file_size = 0;
      if (new_state_handle)
        log_proto_buffered_server_apply_state(self, new_state_handle, persist_name);
      else
        self->state1 = new_state;
    }
  if (new_state_handle)
    {
      persist_state_unmap_entry(persist_state, new_state_handle);
    }
  return FALSE;
}
Esempio n. 9
0
void
test_values(void)
{
    PersistState *state;
    gint i, j;
    gchar *data;

    state = clean_and_create_persist_state_for_test("test_values.persist");

    for (i = 0; i < 1000; i++)
    {
        gchar buf[16];
        PersistEntryHandle handle;

        g_snprintf(buf, sizeof(buf), "testkey%d", i);
        if (!(handle = persist_state_alloc_entry(state, buf, 128)))
        {
            fprintf(stderr, "Error allocating value in the persist file: %s\n", buf);
            exit(1);
        }
        data = persist_state_map_entry(state, handle);
        for (j = 0; j < 128; j++)
        {
            data[j] = (i % 26) + 'A';
        }
        persist_state_unmap_entry(state, handle);
    }
    for (i = 0; i < 1000; i++)
    {
        gchar buf[16];
        PersistEntryHandle handle;
        gsize size;
        guint8 version;

        g_snprintf(buf, sizeof(buf), "testkey%d", i);
        if (!(handle = persist_state_lookup_entry(state, buf, &size, &version)))
        {
            fprintf(stderr, "Error retrieving value from the persist file: %s\n", buf);
            exit(1);
        }
        data = persist_state_map_entry(state, handle);
        for (j = 0; j < 128; j++)
        {
            if (data[j] != (i % 26) + 'A')
            {
                fprintf(stderr, "Invalid data in persistent entry\n");
                exit(1);
            }
        }
        persist_state_unmap_entry(state, handle);
    }

    state = restart_persist_state(state);

    for (i = 0; i < 1000; i++)
    {
        gchar buf[16];
        PersistEntryHandle handle;
        gsize size;
        guint8 version;

        g_snprintf(buf, sizeof(buf), "testkey%d", i);
        if (!(handle = persist_state_lookup_entry(state, buf, &size, &version)))
        {
            fprintf(stderr, "Error retrieving value from the persist file: %s\n", buf);
            exit(1);
        }
        if (size != 128 || version != 4)
        {
            fprintf(stderr, "Error retrieving value from the persist file: %s, invalid size (%d) or version (%d)\n", buf, (gint) size, version);
            exit(1);
        }
        data = persist_state_map_entry(state, handle);
        for (j = 0; j < 128; j++)
        {
            if (data[j] != (i % 26) + 'A')
            {
                fprintf(stderr, "Invalid data in persistent entry\n");
                exit(1);
            }
        }
        persist_state_unmap_entry(state, handle);
    }
    cancel_and_destroy_persist_state(state);
}