diff --git a/init/init.c b/init/init.c index 16b83881..fbf61d3c 100644 --- a/init/init.c +++ b/init/init.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -242,6 +243,7 @@ struct daemon_config int argc; char** argv; enum exit_code_meaning exit_code_meaning; + bool per_if; bool need_tty; enum log_method log_method; enum log_format log_format; @@ -1197,6 +1199,14 @@ static bool daemon_process_command(struct daemon_config* daemon_config, else daemon_config->log_size = (off_t) value; } + else if ( !strcmp(argv[0], "per") ) + { + if ( !strcmp(argv[1], "if") ) + daemon_config->per_if = true; + else + warning("%s:%ji: unknown %s: %s", + path, (intmax_t) line_number, argv[0], argv[1]); + } else if ( !strcmp(argv[0], "need") ) { if ( !strcmp(argv[1], "tty") ) @@ -1310,6 +1320,17 @@ static bool daemon_process_command(struct daemon_config* daemon_config, default_config.log_rotate_on_start; else if ( !strcmp(argv[1], "log-size") ) daemon_config->log_line_size = default_config.log_line_size; + else if ( !strcmp(argv[1], "per") ) + { + if ( argc < 3 ) + warning("%s:%ji: expected parameter: %s: %s", + path, (intmax_t) line_number, argv[0], argv[1]); + else if ( !strcmp(argv[2], "if") ) + daemon_config->per_if = false; + else + warning("%s:%ji: %s %s: unknown: %s", path, + (intmax_t) line_number, argv[0], argv[1], argv[2]); + } else if ( !strcmp(argv[1], "need") ) { if ( argc < 3 ) @@ -1734,8 +1755,36 @@ static void daemon_configure_sub(struct daemon* daemon, static void daemon_configure(struct daemon* daemon, struct daemon_config* daemon_config) { - // Parameterized daemons will be instatiated here later on. - daemon_configure_sub(daemon, daemon_config, NULL); + if ( daemon_config->per_if ) + { + struct if_nameindex* ifs = if_nameindex(); + if ( !ifs ) + fatal("if_nameindex: %m"); + for ( size_t i = 0; ifs[i].if_name; i++ ) + { + const char* netif = ifs[i].if_name; + char* parameterized_name; + if ( asprintf(¶meterized_name, "%s.%s", + daemon_config->name, netif) < 0 ) + fatal("malloc: %m"); + struct daemon* parameterized = + daemon_create_unconfigured(parameterized_name); + free(parameterized_name); + if ( !(parameterized->netif = strdup(netif)) ) + fatal("malloc: %m"); + char* name_clone = strdup(parameterized->name); + if ( !name_clone ) + fatal("malloc: %m"); + int flags = DEPENDENCY_FLAG_REQUIRE | DEPENDENCY_FLAG_AWAIT; + if ( !daemon_add_dependency(daemon, parameterized, flags) ) + fatal("malloc: %m"); + daemon_configure_sub(parameterized, daemon_config, netif); + } + if_freenameindex(ifs); + daemon->configured = true; + } + else + daemon_configure_sub(daemon, daemon_config, NULL); } static struct daemon* daemon_create(struct daemon_config* daemon_config) diff --git a/share/init/base b/share/init/base index 1fbf5d63..9b98ce8f 100644 --- a/share/init/base +++ b/share/init/base @@ -1 +1,2 @@ +require network optional require time optional diff --git a/share/init/network b/share/init/network new file mode 100644 index 00000000..e69de29b diff --git a/share/man/man5/init.5 b/share/man/man5/init.5 index a2c50153..c857e77e 100644 --- a/share/man/man5/init.5 +++ b/share/man/man5/init.5 @@ -149,8 +149,10 @@ The following daemons are provided by the system: .It Sy base Virtual daemon that depends on the core operating system daemons. It depends on the +.Sy network +and .Sy time -daemon. +daemons. .It Sy local Virtual daemon that starts daemons pertinent to the local system. The system provides a default implementation that does nothing. @@ -158,6 +160,11 @@ The system administrator is meant to override the daemon in .Pa /etc/init/local by depending on daemons outside of the base system that should run on the local system. +.It Sy network +Virtual daemon that becomes ready when an attempt has been made to establish +network connectivity. +Daemons can depend on this daemon if they need the network to have been +established before they start. .It Sy time Virtual daemon that becomes ready when the current date and time has been established. @@ -388,6 +395,21 @@ daemon readiness protocol. Upon exit, the original terminal settings are restored and .Xr init 8 reclaims ownership of the terminal. +.It Sy per if +Specifies that an instance of the daemon should run for each network interface. +The daemon becomes a virtual daemon that depends on on the instantiated daemons +for each network interface. +The name of each instantiated daemon is the name of the virtual daemon plus +.Sq "." +plus the name of the network interface (e.g. +.Sy exampled +running on the loopback interface +.Sy lo0 +would be +.Sy example.lo0 ) . +The name of the network interface is appended as a command line argument on the +command line of each instantiated daemon. +It is not possible to depend on the instantiated daemons. .It Sy require Ar dependency Oo Ar flag ... Oc When the daemon is needed, start the .Ar dependency