diff --git a/configure.ac b/configure.ac index a609630d..bbe9292e 100644 --- a/configure.ac +++ b/configure.ac @@ -90,6 +90,7 @@ AC_PLUGIN([modprobe], [yes], [Coldplug modules using modalias magic]) AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf]) AC_PLUGIN([x11-common], [no], [Console setup (for X)]) AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.]) +AC_PLUGIN([hook-scripts], [no], [Trigger script execution from hook points]) 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]) @@ -146,6 +147,11 @@ AC_ARG_WITH(watchdog, AS_HELP_STRING([--with-watchdog=[DEV]], [Enable built-in watchdog, default: /dev/watchdog]), [watchdog=$withval], [with_watchdog=no watchdog=]) +AC_ARG_WITH(hook-scripts-path, + AS_HELP_STRING([--with-hook-scripts-path=DIR], [Base directory for hook scripts, default $libexecdir/finit/hook]), + [hook_scripts_path=$withval], [hook_scripts_path=yes]) + + ### Enable features ########################################################################### # Create config.h from selected features and fallback defaults @@ -240,6 +246,11 @@ AS_IF([test "x$with_watchdog" != "xno"], [ AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])], [ watchdog=]) +AS_IF([test "x$enable_hook_scripts_plugin" = "xyes" -a "x$with_hook_scripts_path" != "xno"], [ + AS_IF([test "x$hook_scripts_path" = "xyes"], [hook_scripts_path=$libexecdir/finit/hook]) + AC_EXPAND_DIR(hook_scripts_path, "$hook_scripts_path") + AC_DEFINE_UNQUOTED(PLUGIN_HOOK_SCRIPTS_PATH, "$hook_scripts_path", [Built-in default: $libexecdir/finit])]) + # Control build with automake flags AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"]) AM_CONDITIONAL(KEVENTD, [test "x$with_keventd" != "xno"]) diff --git a/doc/plugins.md b/doc/plugins.md index c89b8d26..c8e83a0b 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -34,6 +34,12 @@ For your convenience a set of *optional* plugins are available: * *dbus.so*: Setup and start system message bus, D-Bus, at boot. _Optional plugin._ +* *hook-scripts.so*: Trigger the execution of scripts from plugin hook + points (see [Hooks](#hooks)). Scripts are located in + `/libexec/finit/hook` by default, this can be build-time customized + by using the `--with-hook-scripts-path=PATH` argument to + `configure`. _Optional plugin._ + * *hotplug.so*: Setup and start either udev or mdev hotplug daemon, if available. Enabled by default. diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 4360cd55..b9b6b1d2 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -64,6 +64,10 @@ if BUILD_DBUS_PLUGIN pkglib_LTLIBRARIES += dbus.la endif +if BUILD_HOOK_SCRIPTS_PLUGIN +pkglib_LTLIBRARIES += hook-scripts.la +endif + if BUILD_HOTPLUG_PLUGIN pkglib_LTLIBRARIES += hotplug.la endif diff --git a/plugins/hook-scripts.c b/plugins/hook-scripts.c new file mode 100644 index 00000000..afd3382f --- /dev/null +++ b/plugins/hook-scripts.c @@ -0,0 +1,116 @@ +/* Trigger scripts to run from finit's hooks + * + * Copyright (c) 2022 Tobias Waldekranz + * + * 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 "finit.h" +#include "helpers.h" +#include "plugin.h" +#include "config.h" + +#define CHOOSE(x, y) y +static const char *hscript_paths[] = HOOK_TYPES; +#undef CHOOSE + +static void hscript_run_parts(hook_point_t hook) +{ + char path[CMD_SIZE] = ""; + + strlcat(path, PLUGIN_HOOK_SCRIPTS_PATH, sizeof(path)); + strlcat(path, hscript_paths[hook] + 4, sizeof(path)); + + run_parts(path, NULL); +} + +static void hscript_banner(void *arg) +{ + hscript_run_parts(HOOK_BANNER); +} + +static void hscript_rootfs_up(void *arg) +{ + hscript_run_parts(HOOK_ROOTFS_UP); +} + +static void hscript_mount_error(void *arg) +{ + hscript_run_parts(HOOK_MOUNT_ERROR); +} + +static void hscript_mount_post(void *arg) +{ + hscript_run_parts(HOOK_MOUNT_POST); +} + +static void hscript_basefs_up(void *arg) +{ + hscript_run_parts(HOOK_BASEFS_UP); +} + +static void hscript_network_up(void *arg) +{ + hscript_run_parts(HOOK_NETWORK_UP); +} + +static void hscript_svc_up(void *arg) +{ + hscript_run_parts(HOOK_SVC_UP); +} + +static void hscript_system_up(void *arg) +{ + hscript_run_parts(HOOK_SYSTEM_UP); +} + +static void hscript_shutdown(void *arg) +{ + hscript_run_parts(HOOK_SHUTDOWN); +} + +static plugin_t plugin = { + .name = __FILE__, + .hook[HOOK_BANNER] = { .cb = hscript_banner }, + .hook[HOOK_ROOTFS_UP] = { .cb = hscript_rootfs_up }, + .hook[HOOK_MOUNT_ERROR] = { .cb = hscript_mount_error }, + .hook[HOOK_MOUNT_POST] = { .cb = hscript_mount_post }, + .hook[HOOK_BASEFS_UP] = { .cb = hscript_basefs_up }, + .hook[HOOK_NETWORK_UP] = { .cb = hscript_network_up }, + .hook[HOOK_SVC_UP] = { .cb = hscript_svc_up }, + .hook[HOOK_SYSTEM_UP] = { .cb = hscript_system_up }, + .hook[HOOK_SHUTDOWN] = { .cb = hscript_shutdown }, +}; + +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: + */