Skip to content

Commit e9663d3

Browse files
committed
Implementation of put state function
1 parent 9277e14 commit e9663d3

File tree

9 files changed

+132
-11
lines changed

9 files changed

+132
-11
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ccflags-y += -D_LUNATIK -D_KERNEL -I$(src) -D_CONFIG_FULL_PANIC -DLUNATIK_UNUSED \
1+
ccflags-y += -D_LUNATIK -D_KERNEL -I$(src) -D_CONFIG_FULL_PANIC -DLUNATIK_UNUSED -DDEBUG\
22
-I$(src)/lua -I$(src)/deps/lua-memory/src
33
asflags-y += -D_LUNATIK -D_KERNEL
44

lib/lunatik.c

+24
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,9 @@ static int response_state_handler(struct nl_msg *msg, void *arg)
546546
} else if (attrs_tb[OP_ERROR] && nla_get_u8(attrs_tb[OP_ERROR])) {
547547
state->cb_result = CB_ERROR;
548548
return NL_OK;
549+
} else if (attrs_tb[NOT_IN_USE] && nla_get_u8(attrs_tb[NOT_IN_USE])) {
550+
state->cb_result = CB_ERROR;
551+
return NL_OK;
549552
}
550553

551554
if (attrs_tb[CURR_ALLOC]) {
@@ -810,3 +813,24 @@ int lunatik_getcurralloc(struct lunatik_nl_state *state)
810813
printf("Failed to put attribute to get current alloc of state %s\n", state->name);
811814
return -1;
812815
}
816+
817+
int lunatik_putstate(struct lunatik_nl_state *state)
818+
{
819+
struct nl_msg *msg;
820+
821+
int err = -1;
822+
823+
if ((msg = prepare_message(PUT_STATE, 0)) == NULL)
824+
return err;
825+
826+
NLA_PUT_STRING(msg, STATE_NAME, state->name);
827+
828+
if ((err = nl_send_auto(state->control_sock, msg)) < 0)
829+
return err;
830+
831+
return receive_state_op_result(state);
832+
833+
nla_put_failure:
834+
printf("Failed to put attribute to put state\n");
835+
return -1;
836+
}

lib/lunatik.h

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <sys/user.h>
2424
#include <stdint.h>
25+
#include <stdbool.h>
2526
#include <netlink/genl/genl.h>
2627
#include "../netlink_common.h"
2728
#include "../lunatik_conf.h"
@@ -53,6 +54,7 @@ struct lunatik_nl_state {
5354
enum callback_result cb_result;
5455
uint32_t maxalloc;
5556
uint32_t curralloc;
57+
bool isvalid;
5658
char name[LUNATIK_NAME_MAXSIZE];
5759
};
5860

@@ -113,4 +115,6 @@ int lunatik_datasend(struct lunatik_nl_state *state,
113115

114116
int lunatik_getcurralloc(struct lunatik_nl_state *state);
115117

118+
int lunatik_putstate(struct lunatik_nl_state *state);
119+
116120
#endif /* LUNATIK_H */

lib/lunatik_module.c

+47-4
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ static int lsession_newstate(lua_State *L)
135135
strcpy(state->name, name);
136136
state->maxalloc = maxalloc;
137137
state->session = session;
138+
state->isvalid = true;
139+
138140

139141
if (lunatikS_newstate(session, state)) {
140142
pusherrmsg(L, "Failed to create the state\n");
@@ -154,6 +156,10 @@ static int lsession_newstate(lua_State *L)
154156
static int lstate_close(lua_State *L)
155157
{
156158
struct lunatik_nl_state *state = getnlstate(L);
159+
160+
if (!state->isvalid)
161+
return luaL_error(L, "invalid state");
162+
157163
if (lunatik_closestate(state)){
158164
lua_pushnil(L);
159165
return 1;
@@ -170,10 +176,12 @@ static int lstate_dostring(lua_State *L)
170176
const char *payload = luaL_checklstring(L, 2, &len);
171177
const char *script_name = luaL_optstring(L, 3, "Lunatik");
172178

173-
if (strlen(script_name) > LUNATIK_SCRIPTNAME_MAXSIZE) {
174-
printf("script name too long\n");
175-
goto error;
176-
}
179+
if (strlen(script_name) > LUNATIK_SCRIPTNAME_MAXSIZE)
180+
return luaL_argerror(L, 3, "script name too long");
181+
182+
if (!s->isvalid)
183+
return luaL_error(L, "invalid state");
184+
177185
int status = lunatik_dostring(s, payload, script_name, len);
178186

179187
if (status)
@@ -189,12 +197,20 @@ static int lstate_dostring(lua_State *L)
189197

190198
static int lstate_getname(lua_State *L) {
191199
struct lunatik_nl_state *s = getnlstate(L);
200+
201+
if (!s->isvalid)
202+
return luaL_error(L, "invalid state");
203+
192204
lua_pushstring(L, s->name);
193205
return 1;
194206
}
195207

196208
static int lstate_getmaxalloc(lua_State *L) {
197209
struct lunatik_nl_state *s = getnlstate(L);
210+
211+
if (!s->isvalid)
212+
return luaL_error(L, "invalid state");
213+
198214
lua_pushinteger(L, s->maxalloc);
199215
return 1;
200216
}
@@ -240,6 +256,7 @@ static int lsession_getstate(lua_State *L)
240256
}
241257

242258
*state = *received_state;
259+
state->isvalid = true;
243260

244261
if (lunatik_initstate(state)) {
245262
pusherrmsg(L, "Failed to initialize the state\n");
@@ -277,6 +294,10 @@ static int lstate_datasend(lua_State *L)
277294

278295
if (buffer == NULL) luaL_argerror(L, 2, "expected non NULL memory object");
279296

297+
if (!state->isvalid)
298+
return luaL_error(L, "invalid state");
299+
300+
280301
err = lunatik_datasend(state, buffer, size);
281302
err ? lua_pushnil(L) : lua_pushboolean(L, true);
282303

@@ -290,6 +311,9 @@ static int lstate_datareceive(lua_State *L)
290311
struct lunatik_nl_state *state = getnlstate(L);
291312
char *memory;
292313

314+
if (!state->isvalid)
315+
return luaL_error(L, "invalid state");
316+
293317
if (lunatik_receive(state))
294318
goto error;
295319

@@ -309,6 +333,9 @@ static int lstate_getcurralloc(lua_State *L)
309333
{
310334
struct lunatik_nl_state *state = getnlstate(L);
311335

336+
if (!state->isvalid)
337+
return luaL_error(L, "invalid state");
338+
312339
if (lunatik_getcurralloc(state)) {
313340
lua_pushnil(L);
314341
return 1;
@@ -319,6 +346,21 @@ static int lstate_getcurralloc(lua_State *L)
319346
return 1;
320347
}
321348

349+
static int lstate_put(lua_State *L)
350+
{
351+
struct lunatik_nl_state *state = getnlstate(L);
352+
353+
if (lunatik_putstate(state)) {
354+
lua_pushnil(L);
355+
return 1;
356+
}
357+
358+
lua_pushboolean(L, true);
359+
state->isvalid = false;
360+
361+
return 1;
362+
}
363+
322364
static const luaL_Reg session_mt[] = {
323365
{"close", lsession_close},
324366
{"getfd", lsession_getfd},
@@ -337,6 +379,7 @@ static const luaL_Reg state_mt[] = {
337379
{"close", lstate_close},
338380
{"send", lstate_datasend},
339381
{"receive", lstate_datareceive},
382+
{"put", lstate_put},
340383
{NULL, NULL}
341384
};
342385

lib/tests/send.lua

+2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ local session = lunatik.session()
55
local buffer = memory.create(3)
66
memory.set(buffer, 1, 0x1, 0x2, 0x3)
77

8+
-- TODO the kscript variable starts with \n, if such variable starts with \t then a kernel panic along with a deadlock will occour
89
local kscript = [[
10+
911
function receive_callback(mem)
1012
print'A memory has been received'
1113
memory.tostring(mem)

lunatik.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ int lunatik_close(const char *name);
5656
lunatik_State *lunatik_statelookup(const char *name);
5757

5858
bool lunatik_getstate(lunatik_State *s);
59-
void lunatik_putstate(lunatik_State *s);
59+
int lunatik_putstate(lunatik_State *s);
6060

6161
lunatik_State *lunatik_netnewstate(const char *name, size_t maxalloc, struct net *net);
6262
int lunatik_netclosestate(const char *name, struct net *net);

netlink.c

+41
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static int lunatikN_data(struct sk_buff *buff, struct genl_info *info);
5151
static int lunatikN_datainit(struct sk_buff *buff, struct genl_info *info);
5252
static int lunatikN_sendstate(struct sk_buff *buff, struct genl_info *info);
5353
static int lunatikN_getcurralloc(struct sk_buff *buff, struct genl_info *info);
54+
static int lunatikN_putstate(struct sk_buff *buff, struct genl_info *info);
5455

5556
struct nla_policy lunatik_policy[ATTRS_COUNT] = {
5657
[STATE_NAME] = { .type = NLA_STRING },
@@ -123,8 +124,16 @@ static const struct genl_ops l_ops[] = {
123124
.doit = lunatikN_getcurralloc,
124125
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
125126
.policy = lunatik_policy
127+
#endif
128+
},
129+
{
130+
.cmd = PUT_STATE,
131+
.doit = lunatikN_putstate,
132+
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
133+
.policy = lunatik_policy
126134
#endif
127135
}
136+
128137
};
129138

130139
struct genl_family lunatik_family = {
@@ -714,6 +723,38 @@ static int lunatikN_getcurralloc(struct sk_buff *buff, struct genl_info *info)
714723
return 0;
715724
}
716725

726+
static int lunatikN_putstate(struct sk_buff *buff, struct genl_info *info)
727+
{
728+
struct lunatik_state *s;
729+
char *state_name;
730+
731+
pr_debug("Received a PUT_STATE command\n");
732+
733+
state_name = (char*)nla_data(info->attrs[STATE_NAME]);
734+
s = lunatik_netstatelookup(state_name, genl_info_net(info));
735+
736+
if (s == NULL)
737+
goto error;
738+
739+
if (!s->inuse) {
740+
reply_with(NOT_IN_USE, PUT_STATE, info);
741+
return 0;
742+
}
743+
744+
if (lunatik_putstate(s))
745+
goto error;
746+
747+
748+
s->inuse = false;
749+
reply_with(OP_SUCESS, PUT_STATE, info);
750+
751+
return 0;
752+
753+
error:
754+
reply_with(OP_ERROR, PUT_STATE, info);
755+
return 0;
756+
}
757+
717758
/* Note: Most of the function below is copied from NFLua: https://github.com/cujoai/nflua
718759
* Copyright (C) 2017-2019 CUJO LLC
719760
*

netlink_common.h

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ enum lunatik_operations {
4444
DATA_INIT,
4545
GET_STATE,
4646
GET_CURRALLOC,
47+
PUT_STATE,
4748
};
4849

4950
enum lunatik_attrs {
@@ -63,6 +64,7 @@ enum lunatik_attrs {
6364
LUNATIK_DATA_LEN,
6465
CURR_ALLOC,
6566
STATE_NOT_FOUND,
67+
NOT_IN_USE,
6668
ATTRS_COUNT
6769
#define ATTRS_MAX (ATTRS_COUNT - 1)
6870
};

states.c

+10-5
Original file line numberDiff line numberDiff line change
@@ -146,24 +146,29 @@ inline bool lunatik_getstate(lunatik_State *s)
146146
return refcount_inc_not_zero(&s->users);
147147
}
148148

149-
void lunatik_putstate(lunatik_State *s)
149+
int lunatik_putstate(lunatik_State *s)
150150
{
151151
refcount_t *users = &s->users;
152152
spinlock_t *refcnt_lock = &(s->instance.rfcnt_lock);
153153

154154
if (WARN_ON(s == NULL))
155-
return;
155+
return 1;
156156

157157
if (refcount_dec_not_one(users))
158-
return;
158+
return 1;
159159

160160
spin_lock_bh(refcnt_lock);
161161
if (!refcount_dec_and_test(users))
162-
goto out;
162+
goto error_and_unlock;
163163

164+
hash_del_rcu(&s->node);
164165
kfree(s);
165-
out:
166166
spin_unlock_bh(refcnt_lock);
167+
return 0;
168+
169+
error_and_unlock:
170+
spin_unlock_bh(refcnt_lock);
171+
return 1;
167172
}
168173

169174
lunatik_State *lunatik_netstatelookup(const char *name, struct net *net)

0 commit comments

Comments
 (0)