@@ -33,6 +33,7 @@
#include "progress.h"
#include "pctl.h"
#include "swupdate_vars.h"
+#include "lua_util.h"
/*
* function returns:
@@ -478,6 +479,13 @@ void cleanup_files(struct swupdate_cfg *software) {
dict_drop_db(&software->bootloader);
dict_drop_db(&software->vars);
+ /*
+ * Drop Lua State if instantiated
+ */
+ if (software->lua_state) {
+ lua_exit(software->lua_state);
+ software->lua_state = NULL;
+ }
if (asprintf(&fn, "%s%s", TMPDIR, BOOT_SCRIPT_SUFFIX) != ENOMEM_ASPRINTF) {
remove_sw_file(fn);
free(fn);
@@ -1517,7 +1517,7 @@ int lua_handlers_init(void)
return ret;
}
-lua_State *lua_parser_init(const char *buf, struct dict *bootenv)
+lua_State *lua_init(struct dict *bootenv)
{
lua_State *L = luaL_newstate(); /* opens Lua */
@@ -1533,14 +1533,18 @@ lua_State *lua_parser_init(const char *buf, struct dict *bootenv)
luaL_setfuncs(L, l_swupdate_bootenv, 1);
lua_pop(L, 1); /* remove unused copy left on stack */
+ return L;
+}
+
+int lua_load_buffer(lua_State *L, const char *buf)
+{
if (luaL_loadstring(L, buf) || lua_pcall(L, 0, 0, 0)) {
LUAstackDump(L);
- ERROR("ERROR preparing Lua embedded script in parser");
- lua_close(L);
- return NULL;
+ ERROR("ERROR loading Lua code");
+ return 1;
}
- return L;
+ return 0;
}
int lua_parser_fn(lua_State *L, const char *fcn, struct img_type *img)
@@ -21,7 +21,8 @@ typedef enum {
void LUAstackDump (lua_State *L);
int run_lua_script(const char *script, const char *function, char *parms);
-lua_State *lua_parser_init(const char *buf, struct dict *bootenv);
+lua_State *lua_init(struct dict *bootenv);
+int lua_load_buffer(lua_State *L, const char *buf);
int lua_parser_fn(lua_State *L, const char *fcn, struct img_type *img);
int lua_handlers_init(void);
@@ -34,7 +35,7 @@ int lua_notify_progress(lua_State *L);
int lua_get_swupdate_version(lua_State *L);
-#define lua_parser_exit(L) lua_close((lua_State *)L)
+#define lua_exit(L) lua_close((lua_State *)L)
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM == 501
#define LUA_OK 0
@@ -81,9 +82,10 @@ void luaL_pushresult(luaL_Buffer_52 *B);
#else
#define lua_State void
-#define lua_parser_exit(L)
-static inline lua_State *lua_parser_init(const char __attribute__ ((__unused__)) *buf,
- struct dict __attribute__ ((__unused__)) *bootenv) { return NULL;}
+#define lua_exit(L)
+static inline lua_State *lua_init(struct dict __attribute__ ((__unused__)) *bootenv) { return NULL;}
+static inline int lua_load_buffer(lua_State __attribute__ ((__unused__)) *L,
+ const char __attribute__ ((__unused__)) *buf) {return 1;}
static inline int lua_parser_fn(lua_State __attribute__ ((__unused__)) *L,
const char __attribute__ ((__unused__)) *fcn,
struct img_type __attribute__ ((__unused__)) *img) { return -1; }
@@ -59,6 +59,7 @@ struct swupdate_cfg {
char mtdblacklist[SWUPDATE_GENERAL_STRING_SIZE];
char forced_signer_name[SWUPDATE_GENERAL_STRING_SIZE];
char namespace_for_vars[SWUPDATE_GENERAL_STRING_SIZE];
+ void *lua_state;
bool syslog_enabled;
bool no_downgrading;
bool no_reinstalling;
@@ -1022,15 +1022,24 @@ static int parser(parsertype p, void *cfg, struct swupdate_cfg *swcfg)
swcfg->embscript = get_field_string(p, scriptnode, NULL);
}
+ L = lua_init(&swcfg->bootloader);
+
if (swcfg->embscript) {
+ if (!L) {
+ ERROR("Required embedded script but no Lua not available");
+ return -1;
+ }
if (loglevel >= DEBUGLEVEL)
TRACE("Found Lua Software:\n%s", swcfg->embscript);
- L = lua_parser_init(swcfg->embscript, &swcfg->bootloader);
- if (!L) {
+ if (lua_load_buffer(L, swcfg->embscript)) {
ERROR("Required embedded script that cannot be loaded");
+ lua_close(L);
return -1;
}
}
+
+ swcfg->lua_state = L;
+
if (get_hw_revision(&swcfg->hw) < 0) {
TRACE("Hardware compatibility not found");
}
@@ -1049,9 +1058,6 @@ static int parser(parsertype p, void *cfg, struct swupdate_cfg *swcfg)
*/
parse_partitions(p, cfg, swcfg, L);
- if (L)
- lua_parser_exit(L);
-
if (LIST_EMPTY(&swcfg->images) &&
LIST_EMPTY(&swcfg->scripts) &&
LIST_EMPTY(&swcfg->bootloader)) {
A Lua context is created and destroyed for each Lua scriptthat should run. This isolates each script, but it does not allow that a later script can benefit and load a function previously defined. It was decided that so high isolation is not necessary - instead of having a context for each script, create a Lua context for each installation request. The Lua context is then initialized when sw-description is parsed and removed when the installation has finished, independently from the state. Signed-off-by: Stefano Babic <stefano.babic@swupdate.org> --- core/installer.c | 8 ++++++++ corelib/lua_interface.c | 14 +++++++++----- include/lua_util.h | 12 +++++++----- include/swupdate.h | 1 + parser/parser.c | 16 +++++++++++----- 5 files changed, 36 insertions(+), 15 deletions(-) -- 2.34.1