Skip to content

Commit

Permalink
lua: introduce xlog.meta() method
Browse files Browse the repository at this point in the history
This commit introduces the new method for xlog module: xlog.meta().
It opens an xlog file, reads and returns the meta block of the file,
which includes its filetype, instance_uuid and vclocks.

It's needed in order to introduce names cheking in the following
commit.

@TarantoolBot document
Title: xlog.meta([file-name]) method

Description: Open an xlog file, and return its meta block.
Possible errors: File does not contain properly formatted snapshot
or write-ahead-log information.

Needed for tarantool#8978

Example:

```lua
tarantool> xlog = require('xlog')
---
...

tarantool> xlog.meta('00000000000000000000.snap')
---
- filetype: SNAP
  prev_vclock: {}
  instance_uuid: 87b2e60f-275c-4efa-9b0e-e9562e309692
  vclock: {}
...
```
  • Loading branch information
Serpentian committed Oct 12, 2023
1 parent 00bdb13 commit 8259abc
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 1 deletion.
3 changes: 3 additions & 0 deletions changelogs/unreleased/lua-xlog-meta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## feature/lua/xlog

* Introduced the xlog.meta() method for reading a meta block from an xlog file.
55 changes: 55 additions & 0 deletions src/box/lua/xlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,63 @@ lbox_xlog_parser_open_pairs(struct lua_State *L)
return 3;
}

/** Opens an xlog file and returns its meta block. */
static int
lbox_xlog_parser_open_meta(struct lua_State *L)
{
int args_n = lua_gettop(L);
if (args_n != 1 || !lua_isstring(L, 1))
luaL_error(L, "Usage: parser.open(log_filename)");

const char *filename = luaL_checkstring(L, 1);

/* Construct xlog cursor and object */
struct xlog_cursor *cur = xcalloc(1, sizeof(struct xlog_cursor));
if (xlog_cursor_open(cur, filename) < 0) {
return luaT_error(L);
}
if (strncmp(cur->meta.filetype, "SNAP", 4) != 0 &&
strncmp(cur->meta.filetype, "XLOG", 4) != 0 &&
strncmp(cur->meta.filetype, "RUN", 3) != 0 &&
strncmp(cur->meta.filetype, "INDEX", 5) != 0 &&
strncmp(cur->meta.filetype, "DATA", 4) != 0 &&
strncmp(cur->meta.filetype, "VYLOG", 4) != 0) {
char buf[1024];
snprintf(buf, sizeof(buf), "'%.*s' file type",
(int)strlen(cur->meta.filetype),
cur->meta.filetype);
diag_set(ClientError, ER_UNSUPPORTED, "xlog reader", buf);
xlog_cursor_close(cur, false);
free(cur);
return luaT_error(L);
}

lua_newtable(L);

lua_pushstring(L, "filetype");
lua_pushstring(L, cur->meta.filetype);
lua_settable(L, -3);

lua_pushstring(L, "instance_uuid");
luaT_pushuuidstr(L, &cur->meta.instance_uuid);
lua_settable(L, -3);

lua_pushstring(L, "vclock");
luaT_pushvclock(L, &cur->meta.vclock);
lua_settable(L, -3);

lua_pushstring(L, "prev_vclock");
luaT_pushvclock(L, &cur->meta.prev_vclock);
lua_settable(L, -3);

xlog_cursor_close(cur, false);
free(cur);
return 1;
}

static const struct luaL_Reg lbox_xlog_parser_lib [] = {
{ "pairs", lbox_xlog_parser_open_pairs },
{ "meta", lbox_xlog_parser_open_meta },
{ NULL, NULL }
};

Expand Down
5 changes: 5 additions & 0 deletions src/box/lua/xlog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ local function xlog_pairs(...)
return fun.wrap(internal.pairs(...))
end

local function xlog_meta(...)
return internal.meta(...)
end

return {
pairs = xlog_pairs,
meta = xlog_meta,
}
15 changes: 14 additions & 1 deletion test/box-luatest/xlog_reader_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ local fio = require('fio')
local server = require('luatest.server')
local t = require('luatest')
local xlog = require('xlog')
local uuid = require('uuid')

local g = t.group()

g.before_all(function(cg)
cg.server = server:new()
g.box_cfg = { instance_uuid = uuid() }
cg.server = server:new({box_cfg = g.box_cfg})
cg.server:start()
end)

Expand Down Expand Up @@ -150,3 +152,14 @@ g.test_bad_xlog = function(cg)
},
})
end

g.test_xlog_meta = function(cg)
local glob = fio.glob(fio.pathjoin(cg.server.workdir, '*.snap'))
local snap_path = glob[#glob]

local meta = xlog.meta(snap_path)
t.assert_equals(meta.filetype, 'SNAP')
t.assert_equals(meta.instance_uuid, cg.box_cfg.instance_uuid)
t.assert_not_equals(meta.vclock, nil)
t.assert_not_equals(meta.prev_vclock, nil)
end

0 comments on commit 8259abc

Please sign in to comment.