From: Johannes Truschnigg Date: Sun, 26 Jun 2022 18:13:57 +0000 (+0200) Subject: Import netconsole-rx lua application and procd init script X-Git-Url: https://johannes.truschnigg.info/gitweb/?a=commitdiff_plain;h=7b3f43de1ba50616fb9f592e0f212045b0f298a2;p=netconsole-rx Import netconsole-rx lua application and procd init script --- 7b3f43de1ba50616fb9f592e0f212045b0f298a2 diff --git a/netconsole-rx.init b/netconsole-rx.init new file mode 100755 index 0000000..bb47912 --- /dev/null +++ b/netconsole-rx.init @@ -0,0 +1,23 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=98 + +USE_PROCD=1 +PROG=/root/netconsole-rx.lua + +OUTFILE=/tmp/netconsole.out +PIDFILE=/tmp/netconsole.pid +LISTENPORT=1514 + +start_service() { + procd_open_instance "netconsole_${LISTENPORT}" + procd_set_param command "$PROG" listenport="${LISTENPORT}" outfile="${OUTFILE}" pidfile="${PIDFILE}" + procd_set_param stderr 1 + procd_close_instance +} + +reload_service() { + stop + start +} diff --git a/netconsole-rx.lua b/netconsole-rx.lua new file mode 100755 index 0000000..fcd2407 --- /dev/null +++ b/netconsole-rx.lua @@ -0,0 +1,113 @@ +#!/usr/bin/env lua +local socket = require("socket") +local udpl = assert(socket.udp()) + + +function getpid() + local line + statfp = io.open("/proc/self/stat", "r") + if statfp == nil then + return "--unknown--" + end + line = statfp:read() + return line:match("%d+") +end + + +function args_parse() + local opt + for _, opt in ipairs(arg) do + if opt:find("port=", 1, true) then + listenport = tonumber(opt:match("%d+$", 5)) + elseif opt:find("pidfile=", 1, true) then + pidfile = opt:match("[^%c]+", 9) + elseif opt:find("outfile=", 1, true) then + outfile = opt:match("[^%c]+", 9) + else + io.stderr:write("FATAL: unsupported option: " .. opt .. "\n") + os.exit(1) + end + end +end + + +function args_validate() + local args_valid=true + + if listenport == nil or listenport < 1 or listenport > 65535 then + args_valid=false + io.stderr:write("FATAL: please set a valid 'listenport=...' parameter.\n") + end + + if outfile == nil then + args_valid=false + io.stderr:write("FATAL: please set a valid 'outfile=...' parameter (use `-` for stdout).\n") + elseif outfile == "-" then + outp = io.stdout + else + outp, err = io.open(outfile, "w+") + if err then + args_valid=false + io.stderr:write("FATAL: failed to open output stream at '", outfile, "'\n") + end + end + + if pidfile ~= nil then + pidf, err = io.open(pidfile, "w") + if err == nil then + pidf:write(mypid .. "\n") + pidf:close() + else + args_valid=false + io.stderr:write("FATAL: failed to record PID info in '", pidfile, "'\n") + end + end + + return args_valid +end + + +function isoutctime() + return os.date("!%Y-%m-%dT%TZ") +end + + +-- init -- + +mypid = getpid() +args_parse() + +if not args_validate() then + os.exit(1) +end + +udpl:setsockname("*", listenport) +udpl:settimeout(0.1) +outp:setvbuf("line") +io.stderr:write("netconsole-rx.lua / pid " .. mypid .. " / input UDP port " .. listenport .. " / output '" .. outfile .. "'\n") + +-- processing loop -- + +while(true) +do + data, peer, peerport = udpl:receivefrom() + if data and string.len(data) > 0 then + data, _ = string.gsub(data, "%c", "") + if string.byte(data) == 91 then + -- simple netconsole message, no ksmg-like metadata + outp:write(string.format("%s %s:%s \t%s\n", isoutctime(), peer, peerport, data)) + else + so = string.find(data, ";") + if so ~= nil then + mdata = string.sub(data, 1, (so - 1)) + data = string.sub(data, (so + 1)) + -- TODO: parse mdata, print it sensibly + -- ,,,; + -- outp:write(string.format("%s:%s \t%s\n", peer, peerport, mdata)) + outp:write(string.format("%s %s:%s \t%s\n", isoutctime(), peer, peerport, data)) + else + io.stderr:write("WARN: garbage input from peer " .. peer .. ":" .. peerport .. " discarded\n") + end + end + end +end