From patchwork Tue Dec 17 07:50:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Storm, Christian" X-Patchwork-Id: 1211181 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4864:20::13a; helo=mail-lf1-x13a.google.com; envelope-from=swupdate+bncbdd6bwv65qpbbs4r4lxqkgqefcjypea@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=siemens.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b="onivTxUE"; dkim-atps=neutral Received: from mail-lf1-x13a.google.com (mail-lf1-x13a.google.com [IPv6:2a00:1450:4864:20::13a]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47cVgN2yjfz9sRl for ; Tue, 17 Dec 2019 18:50:40 +1100 (AEDT) Received: by mail-lf1-x13a.google.com with SMTP id f18sf900326lfm.2 for ; Mon, 16 Dec 2019 23:50:40 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1576569036; cv=pass; d=google.com; s=arc-20160816; b=fyiwywX2cRJ1kQs+yFUjbkekc73VVsj+RgELFHqJgStG65AUWBO2I61QQ09oCChztQ K2rMR4P9IRH1gmZQCXD56pZm98wG1T60mawIZL5//3T63oA+SAj745TjTC24lViFDVk/ 3BG155wLtrSQ8SEzx4WTJCcEXb8M1pvm2m4yaU+WMQT9p40F8phhEAOZybr+Vxl99RgW YymdtmE4xzEMxLJGhD52lFHR5zzItUpaHz+fPb7ZOm3D6AumUsHEgCT/zlK6fl1dQEiB m3U/UFIM4y29d90r/SQDFlUmfi1H1NHrIDijPWMBhYebEdaYTAMzXagPAxj16IXE6BRx HyIA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:dkim-signature; bh=hllqz1aoqgrDj0pfuBab1VeqLfKlZvy/gGXasz1OQxg=; b=iiAzjSVo5Hvmaq6o9ve7IEUWLRNmW1ySjLrXyyC5bJ9NAA5ZEQBI7HuhjEa5FCsnZ7 wivNTYOXrEJz1P0OWsAm84JUzdEW4p2qWCTbHKtjQ9XU0NgOalzdwmlScbLEfVge0w9D qWDj6xdRaLIdoss5MSCNDfSO7Xfzx35LtZE7OIfNmVqRyF3W4d8DTTphuAc4MuO3M61Y zdmF72HmkCg2ZaRr6uUUQqb28z0eor0oXyDtMBa8QhCAv9WNEb1Jc/OPtTC0KSyijqA9 t+K1you2fV0X4JNkf24Q8KmftfkU5EheGm9DYvcj3r7Vw7HOKMrno4EbuucBfX/9gPkc ygAw== ARC-Authentication-Results: i=2; gmr-mx.google.com; spf=pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.2 as permitted sender) smtp.mailfrom=christian.storm@siemens.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=hllqz1aoqgrDj0pfuBab1VeqLfKlZvy/gGXasz1OQxg=; b=onivTxUE0S13CuA6/0bzLnQD4vd/q+TuqXrWis3vBGpPE3FIwJjACcoWPtQAwZh8Kf ftJTsnzzIIgEhnkMCgdhXtb1HGY6fMzK7mIN7XMYR1F1lekh/sqzqkxcrg/Ck+rnS7ht Pk6YhWAQhVBUO97uYZim8BvXPa/20QSXrpVBPNTxYjt1fP1wz3VW+iPpDX/t5Z2S7kBY 68BGgHxHi+on3IK2D1Ml9MehtBh5BDoF1dD/eHE42hri4ZFwhOrQtQ/HOLxPYxhgTCgk qwDHCQhBLvzxoiFqILv1yYKnLzwqAVlPvzIGiz/Zgkd+FARFzHHhGQwOMR+EQ3PzbFtW yHBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-spam-checked-in-group:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=hllqz1aoqgrDj0pfuBab1VeqLfKlZvy/gGXasz1OQxg=; b=PAjsKQ9iqlDWOUuLr6y7Fr14yiy9vAW+zNjG9ydOtkhRNBBMvEN/yJP/LjZBUo86wi TkmPjvpiitPIXe9//hHzsKAo+zkqZuumqZK0+41fk/o2UvrtjppMexq9fGQu8jydG6Zz 31YQ9rAMCvwERrXW7QBFGCui4fEKxeOzLskDWrTqgo/WfJRIAN4CCfjzFiLaB556sv4m CHdOzaBntjHLGIe8/l4LO2aHFFWZnSluToA0kryNyRh84sYk7CSisAKH2VqFKYkIV6b5 bV49uTRTNCsweDDrJbvwMA4On71beb2dNgM8b4KhiyEAUFgreoQUk5CRrbkbhujhO8op grTg== Sender: swupdate@googlegroups.com X-Gm-Message-State: APjAAAXv744LdZh7YeZKLMhPjjGPPha3Tm+hrLYEOqpuTAzwUF9DEWEt vRMCJYOazqRc70/TWm0Vgog= X-Google-Smtp-Source: APXvYqyXuQBD9JCR8uEFqqG0/UR1a7cW1Mwb5/hx0//odv9RuzptsDx1mTylYuEDwovEXQ/gzlW9ew== X-Received: by 2002:a2e:9015:: with SMTP id h21mr2181810ljg.69.1576569035663; Mon, 16 Dec 2019 23:50:35 -0800 (PST) X-BeenThere: swupdate@googlegroups.com Received: by 2002:ac2:5219:: with SMTP id a25ls1727135lfl.16.gmail; Mon, 16 Dec 2019 23:50:34 -0800 (PST) X-Received: by 2002:ac2:53a8:: with SMTP id j8mr1967490lfh.28.1576569034934; Mon, 16 Dec 2019 23:50:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1576569034; cv=none; d=google.com; s=arc-20160816; b=Pjyn4U1MhLVcQBL1jG/iyuY89F8vv+wEpX0BTZ6ZaWAo06gxi00ssvtCXnZ8cHgFKB Ik9B/ag/utlFmLVKl/5792abLMC1gLqTYfFrrvpttrn8GPwnUR6URMlXTx5DaHW0fN/X QbL9PeukAGQZX7+7duvllg75UUq+AyTBfBeLxziyDaig2dpxuLVdEVnep889kD2f0haI vOo67u06KWgjBXfCJqq/G7s2hwz1GuqWky5sJ5jlLAQ1E6E974R/WNfHDRgNDXrqszl4 nu+RKs5GIl/wkBhgvPSOdIHNCpmmIDeJeAf1AYfFnGdpIWmE1adZOKaJXeUBFsCaaqp1 H9vw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=7EZjIBx8I9xU0jZn1tk5rcUnCPa2PpcNoRwjLnIAKww=; b=kUR1GZhvFWOVHYfn+yONjJrJ7A6OC5o0tt3O+iVL/EPc8e94g3Ke49VjS9smrYMveX YDiS/u6LIUA98PhJsZYOxG+gCwbgZ3Q9cWcHTVhxpp9fJ5kAL4P6kWsgyyYm2LQ8Hiy5 QeJXIJJJ8tjfAZMpPER/6xiMdl+63yFyYQYidD+F3pHB2XvFJ0JxiIAE2gnZxSsJBLS6 XErSXyK5EIyif1DC2sen5qOGDi+UHlJLmddJmy+0zCWogJKYKt7xPLyuJEreMvIcQ3Ck 3yvd3zAPdsJaIeYBnN5GZkG3O6lhM5vsg863XhYIQui0nGV+P58vCcGW64hGuvfsQ7Vi srNg== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.2 as permitted sender) smtp.mailfrom=christian.storm@siemens.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: from thoth.sbs.de (thoth.sbs.de. [192.35.17.2]) by gmr-mx.google.com with ESMTPS id x5si793751ljh.5.2019.12.16.23.50.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Dec 2019 23:50:34 -0800 (PST) Received-SPF: pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.2 as permitted sender) client-ip=192.35.17.2; Received: from mail3.siemens.de (mail3.siemens.de [139.25.208.14]) by thoth.sbs.de (8.15.2/8.15.2) with ESMTPS id xBH7oYmf020697 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 17 Dec 2019 08:50:34 +0100 Received: from MD1ZFJVC.ad001.siemens.net ([139.25.69.82]) by mail3.siemens.de (8.15.2/8.15.2) with ESMTP id xBH7oX18022025; Tue, 17 Dec 2019 08:50:34 +0100 From: Christian Storm To: swupdate@googlegroups.com Cc: Christian Storm Subject: [swupdate] [PATCH 2/3] Bindings: Implement control socket binding for Lua Date: Tue, 17 Dec 2019 08:50:54 +0100 Message-Id: <20191217075055.3172-2-christian.storm@siemens.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191217075055.3172-1-christian.storm@siemens.com> References: <20191217075055.3172-1-christian.storm@siemens.com> MIME-Version: 1.0 X-Original-Sender: christian.storm@siemens.com X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of christian.storm@siemens.com designates 192.35.17.2 as permitted sender) smtp.mailfrom=christian.storm@siemens.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Implements the binding to SWUpdate's control socket for Lua. This allows to operate SWUpdate from within pure Lua along the lines of, e.g., local artifact = io.open("/some/path/to/artifact.swu", "rb" ) local ctrl = swupdate.control() if not ctrl:connect() then -- Deliberately neglecting error message. io.stderr:write("Error connecting to SWUpdate control socket.\n") return end while true do local chunk = artifact:read(1024) if not chunk then break end if not ctrl:write(chunk) then -- Deliberately neglecting error message. io.stderr:write("Error writing to SWUpdate control socket.\n") break end end local res, msg = ctrl:close() if not res then io.stderr:write(string.format("Error finalizing update: %s\n", msg)) end Signed-off-by: Christian Storm --- bindings/lua_swupdate.c | 161 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/bindings/lua_swupdate.c b/bindings/lua_swupdate.c index dd164e3..ce512a7 100644 --- a/bindings/lua_swupdate.c +++ b/bindings/lua_swupdate.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "auxiliar.h" @@ -54,6 +56,12 @@ static int progress_connect(lua_State *L); static int progress_receive(lua_State *L); static int progress_close(lua_State *L); +static int ctrl(lua_State *L); +static int ctrl_connect(lua_State *L); +static int ctrl_write(lua_State *L); +static int ctrl_close(lua_State *L); +static int ctrl_close_socket(lua_State *L); + int luaopen_lua_swupdate(lua_State *L); /* @@ -99,6 +107,157 @@ static int netif(lua_State *L) return 1; } +struct ctrl_obj { + int socket; +}; + +/* control object methods */ +static luaL_Reg ctrl_methods[] = { + {"__gc", ctrl_close_socket}, + {"__tostring", auxiliar_tostring}, + {"connect", ctrl_connect}, + {"write", ctrl_write}, + {"close", ctrl_close}, + {NULL, NULL} +}; + +/** + * @brief Connect to SWUpdate control socket. + * + * @param [Lua] The swupdate_control class instance. + * @return [Lua] The connection handle (mostly for information), or, + * in case of errors, nil plus an error message. + */ +static int ctrl_connect(lua_State *L) { + struct ctrl_obj *p = (struct ctrl_obj *) auxiliar_checkclass(L, "swupdate_control", 1); + if (p->socket != -1) { + lua_pop(L, 1); + lua_pushnil(L); + lua_pushstring(L, "Already connected to SWUpdate control socket."); + return 2; + } + + int connfd = ipc_inst_start_ext(SOURCE_LOCAL, 0, NULL, false); + if (connfd < 0) { + lua_pop(L, 1); + lua_pushnil(L); + lua_pushstring(L, "Cannot connect to SWUpdate control socket."); + return 2; + } + + p->socket = connfd; + + lua_pop(L, 1); + lua_pushnumber(L, connfd); + lua_pushnil(L); + + return 2; +} + +/** + * @brief Write data chunk to SWUpdate's control socket. + * + * @param [Lua] The swupdate_control class instance. + * @param [Lua] Lua String chunk data to write to SWUpdate's control socket. + * @return [Lua] True, or, in case of errors, nil plus an error message. + */ +static int ctrl_write(lua_State *L) { + struct ctrl_obj *p = (struct ctrl_obj *) auxiliar_checkclass(L, "swupdate_control", 1); + luaL_checktype(L, 2, LUA_TSTRING); + + if (p->socket == -1) { + lua_pushnil(L); + lua_pushstring(L, "Not connected to SWUpdate control socket."); + goto ctrl_write_exit; + } + + size_t len = 0; + const char* buf = lua_tolstring(L, 2, &len); + if (!buf) { + lua_pushnil(L); + lua_pushstring(L, "Error converting Lua chunk data."); + goto ctrl_write_exit; + } + if ((len = ipc_send_data(p->socket, (char *)buf, len)) < 0) { + lua_pushnil(L); + lua_pushstring(L, "Error writing to SWUpdate control socket."); + goto ctrl_write_exit; + } + + lua_pushboolean(L, true); + lua_pushnil(L); + +ctrl_write_exit: + lua_remove(L, 1); + lua_remove(L, 1); + return 2; +} + +static int ctrl_close_socket(lua_State *L) { + struct ctrl_obj *p = (struct ctrl_obj *) auxiliar_checkclass(L, "swupdate_control", 1); + (void)ipc_end(p->socket); + p->socket = -1; + lua_remove(L, 1); + return 0; +} + +static char *ipc_wait_error_msg = NULL; +static int ipc_wait_get_msg(ipc_message *msg) +{ + if (msg->data.status.error != 0 && msg->data.status.current == FAILURE) { + free(ipc_wait_error_msg); + ipc_wait_error_msg = strdup(msg->data.status.desc); + } + return 0; +} + +/** + * @brief Close connection to SWUpdate control socket. + * + * @param [Lua] The swupdate_control class instance. + * @return [Lua] True, or, in case of errors, nil plus an error message. + */ +static int ctrl_close(lua_State *L) { + struct ctrl_obj *p = (struct ctrl_obj *) auxiliar_checkclass(L, "swupdate_control", 1); + if (p->socket == -1) { + lua_pop(L, 1); + lua_pushboolean(L, true); + lua_pushnil(L); + return 2; + } + + (void)ctrl_close_socket(L); + + if ((RECOVERY_STATUS)ipc_wait_for_complete(ipc_wait_get_msg) == FAILURE) { + lua_pushnil(L); + lua_pushstring(L, ipc_wait_error_msg); + free(ipc_wait_error_msg); + ipc_wait_error_msg = NULL; + return 2; + } + + ipc_message msg; + if (ipc_postupdate(&msg) != 0) { + lua_pushnil(L); + lua_pushstring(L, "SWUpdate succeeded but post-update action failed."); + return 2; + } + + lua_pushboolean(L, true); + lua_pushnil(L); + return 2; +} + +static int ctrl(lua_State *L) { + /* allocate control object */ + struct ctrl_obj *p = (struct ctrl_obj *) lua_newuserdata(L, sizeof(*p)); + p->socket = -1; + + /* set its type as master object */ + auxiliar_setclass(L, "swupdate_control", -1); + + return 1; +} struct prog_obj { RECOVERY_STATUS status; @@ -185,6 +344,7 @@ static int progress(lua_State *L) { static const luaL_Reg lua_swupdate[] = { {"progress", progress}, + {"control", ctrl}, {"ipv4", netif}, {NULL, NULL} }; @@ -195,5 +355,6 @@ static const luaL_Reg lua_swupdate[] = { int luaopen_lua_swupdate(lua_State *L){ luaL_newlib(L, lua_swupdate); auxiliar_newclass(L, "swupdate_progress", progress_methods); + auxiliar_newclass(L, "swupdate_control", ctrl_methods); return 1; }