diff --git a/configure.ac b/configure.ac index 491ee3ee..57a70500 100644 --- a/configure.ac +++ b/configure.ac @@ -96,6 +96,7 @@ AC_PLUGIN([hotplug], [yes], [Setup and start udev or mdev hotplug daemon]) AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock]) AC_PLUGIN([tty], [yes], [Automatically activate new TTYs, e.g. USB-to-serial]) AC_PLUGIN([urandom], [yes], [Setup and save random seed at boot/shutdown]) +AC_PLUGIN([testserv], [no], [Test plugin to start test serv daemon]) # Check for extra arguments or packages AC_ARG_WITH(fstab, diff --git a/plugins/Makefile.am b/plugins/Makefile.am index a2b69c53..c5581ac0 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -41,6 +41,10 @@ if BUILD_RTC_PLUGIN libplug_la_SOURCES += rtc.c endif +if BUILD_TESTSERV_PLUGIN +libplug_la_SOURCES += testserv.c +endif + if BUILD_TTY_PLUGIN libplug_la_SOURCES += tty.c endif @@ -92,6 +96,10 @@ if BUILD_RTC_PLUGIN pkglib_LTLIBRARIES += rtc.la endif +if BUILD_TESTSERV_PLUGIN +pkglib_LTLIBRARIES += testserv.la +endif + if BUILD_TTY_PLUGIN pkglib_LTLIBRARIES += tty.la endif diff --git a/plugins/testserv.c b/plugins/testserv.c new file mode 100644 index 00000000..bdaee6f7 --- /dev/null +++ b/plugins/testserv.c @@ -0,0 +1,98 @@ +/* Test plugin, only used for `make check`, not for public use + * + * Copyright (c) 2023 Joachim Wiberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#ifdef _LIBITE_LITE +# include +#else +# include +#endif + +#include "finit.h" +#include "config.h" +#include "helpers.h" +#include "plugin.h" +#include "service.h" +#include "conf.h" + +#define SERV_DAEMON "serv" +#define SERV_ARGS "-n -p" +#define SERV_DESC "Test serv daemon" + +static void setup(void *arg) +{ + char line[256]; + mode_t prev; + char *cmd; + + if (rescue) { + dbg("Skipping %s plugin in rescue mode.", __FILE__); + return; + } + + cmd = which(SERV_DAEMON); + if (!cmd) { + dbg("Skipping plugin, %s is not installed.", SERV_DAEMON); + return; + } + + /* Clean up from any previous pre-bootstrap run */ + remove("/run/serv.pid"); + + prev = umask(0); + mksubsys("/var/run/serv", 0755, "root", "root"); + mksubsys("/var/run/lock/subsys", 0755, "root", "root"); + mksubsys("/var/lib/serv", 0755, "root", "root"); + mksubsys("/tmp/serv", 0755, "root", "root"); + umask(prev); + + snprintf(line, sizeof(line), "[S123456789] pid:!/run/serv.pid cgroup.system %s %s -- %s", + cmd, SERV_ARGS, SERV_DESC); + + if (service_register(SVC_TYPE_SERVICE, line, global_rlimit, NULL)) + err(1, "Failed registering %s", SERV_DAEMON); + + free(cmd); +} + +static plugin_t plugin = { + .name = __FILE__, + .hook[HOOK_SVC_PLUGIN] = { .cb = setup }, +}; + +PLUGIN_INIT(plugin_init) +{ + plugin_register(&plugin); +} + +PLUGIN_EXIT(plugin_exit) +{ + plugin_unregister(&plugin); +} + +/** + * Local Variables: + * indent-tabs-mode: t + * c-file-style: "linux" + * End: + */ diff --git a/test/tenv/lib.sh b/test/tenv/lib.sh index acdf983b..cf08ea8b 100755 --- a/test/tenv/lib.sh +++ b/test/tenv/lib.sh @@ -57,6 +57,11 @@ assert_restarts() assert "Finit has registered restarts" "$(texec initctl status "$2" | awk '/Restarts/{print $3;}')" -ge "$1" } +assert_norestart() +{ + assert "Service $1 is stable, no restarts" "$(texec initctl status "$1" | awk '/Restarts/{print $3;}')" -eq "0" +} + assert_desc() { assert "Service description == $1" "$(texec initctl status "$2" | grep 'Description' | sed 's/Description : //')" = "$1" diff --git a/test/testserv.sh b/test/testserv.sh new file mode 100755 index 00000000..608aed84 --- /dev/null +++ b/test/testserv.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# Verify service readiness notification + +set -eu +#set -x +TEST_DIR=$(dirname "$0") +#DEBUG=true + +# shellcheck source=/dev/null +. "$TEST_DIR/tenv/lib.sh" + +sleep 1 +retry 'assert_norestart serv' 1 1 + +return 0