From: Davin McCall Date: Mon, 14 May 2018 20:22:43 +0000 (+0100) Subject: Look in multiple directories for service descriptions. X-Git-Tag: v0.2.0~21 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=4bdd5855e42f7659297255c9db460bc48b94a88a;p=oweals%2Fdinit.git Look in multiple directories for service descriptions. Previously we checked only /etc/dinit.d; now, check /etc/dinit.d, /usr/local/lib/dinit.d, and /lib/dinit.d, in that order. --- diff --git a/README b/README index 69df41e..c7c8cac 100644 --- a/README +++ b/README @@ -117,9 +117,10 @@ Service Description files =-=-=-=-=-=-=-=-=-=-=-=-= Dinit discovers services by reading _service description files_. These files -reside in a directory (/etc/dinit.d is the default "system" location) and -their name matches the name of the service. Service descriptions are loaded -lazily, as needed by Dinit. +reside in a directory (/etc/dinit.d is the default "system" location, with +"/usr/local/lib/dinit.d" and "/lib/dinit.d" also searched) and their name +matches the name of the service. Service descriptions are loaded lazily, as +needed by Dinit. A service description file consists of a number of parameter settings. Settings in the SDF are denoted as a parameter name followed by either an diff --git a/TODO b/TODO index 653604f..864e088 100644 --- a/TODO +++ b/TODO @@ -19,7 +19,11 @@ For version 1.0: * Think about detecting runs-on-console dependency conflicts (i.e. if A runs-on-console and B depends on A and runs-on-consle then B can never start). * Documentation must be complete (see section below). - +* Package-manager-friendly way to enable/disable services. + Perhaps a service can specify a dependency file (with dependency type) where + the file contains a list of service names, or if it is a directory, each + filename within corresponds to a service that is a dependency. +* Be able to boot and shutdown Linux and FreeBSD. For later: ---------- diff --git a/doc/manpages/dinit-service.5 b/doc/manpages/dinit-service.5 index ed80605..c3b4c26 100644 --- a/doc/manpages/dinit-service.5 +++ b/doc/manpages/dinit-service.5 @@ -16,8 +16,9 @@ of the file corresponds to the name of the service it describes. Service description files specify the various attributes of a service. A service description file is named after the service it represents, and is a plain-text file with simple key-value format. The description files are -located in the service description directory (which defaults to -\fI/etc/dinit.d\fR for the system process). +located in a service description directory; by default, the system process +searches \fI/etc/dinit.d\fR, \fI/usr/local/lib/dinit.d\fR and +\fI/lib/dinit.d\fR, while a user process searches \fI$HOME/dinit.d\fR. .LP All services have a \fItype\fR and a set of \fIdependencies\fR. Service types are discussed in the following subsection. If a service depends on diff --git a/doc/manpages/dinit.8 b/doc/manpages/dinit.8 index 753714f..3f0e48e 100644 --- a/doc/manpages/dinit.8 +++ b/doc/manpages/dinit.8 @@ -20,15 +20,18 @@ specified via command line parameter) or as a user instance. This affects the default paths used to locate certain files, and the reaction to various signals. -Dinit reads service descriptions from files located in the service -description directory, normally \fI/etc/dinit.d\fR for the system instance -or \fI$HOME/dinit.d\fR when run as a user process. See \fBSERVICE -DESCRIPTION FILES\fR for details. +Dinit reads service descriptions from files located in a service +description directory, normally one of \fI/etc/dinit.d\fR, +\fI/usr/local/lib/dinit.d/fR or \fI/lib/dinit.d\fR for the system instance +or just \fI$HOME/dinit.d\fR when run as a user process. See \fBSERVICE +DESCRIPTION FILES\fR for details of the service description format. .\" .SH OPTIONS .TP \fB\-d\fR \fIdir\fP, \fB\-\-services\-dir\fR \fIdir\fP Specifies \fIdir\fP as the directory containing service definition files. +The directory specified will be the only directory searched for service +definitions. .TP \fB\-e\fR \fIfile\fP, \fB\-\-env\-file\fR \fIfile\fP Read initial environment from \fIfile\fP. For the system init process, the diff --git a/src/dinit.cc b/src/dinit.cc index 06445dc..7297f98 100644 --- a/src/dinit.cc +++ b/src/dinit.cc @@ -165,6 +165,7 @@ int dinit_main(int argc, char **argv) am_system_init = (getpid() == 1); const char * service_dir = nullptr; + bool service_dir_dynamic = false; // service_dir dynamically allocated? const char * env_file = nullptr; string service_dir_str; // to hold storage for above if necessary bool control_socket_path_set = false; @@ -306,16 +307,20 @@ int dinit_main(int argc, char **argv) if (service_dir == nullptr && ! am_system_init) { const char * userhome = get_user_home(); if (userhome != nullptr) { - service_dir_str = get_user_home(); - service_dir_str += "/dinit.d"; - service_dir = service_dir_str.c_str(); + const char * user_home = get_user_home(); + size_t user_home_len = strlen(user_home); + size_t dinit_d_len = strlen("/dinit.d"); + size_t full_len = user_home_len + dinit_d_len + 1; + char *service_dir_w = new char[full_len]; + std::memcpy(service_dir_w, user_home, user_home_len); + std::memcpy(service_dir_w + user_home_len, "/dinit.d", dinit_d_len); + service_dir_w[full_len - 1] = 0; + + service_dir = service_dir_w; + service_dir_dynamic = true; } } - if (service_dir == nullptr) { - service_dir = "/etc/dinit.d"; - } - if (services_to_start.empty()) { services_to_start.push_back("boot"); } @@ -369,8 +374,18 @@ int dinit_main(int argc, char **argv) log_flush_timer.add_timer(event_loop, dasynq::clock_type::MONOTONIC); + bool add_all_service_dirs = false; + if (service_dir == nullptr) { + service_dir = "/etc/dinit.d"; + add_all_service_dirs = true; + } + /* start requested services */ - services = new dirload_service_set(service_dir); + services = new dirload_service_set(service_dir, service_dir_dynamic); + if (add_all_service_dirs) { + services->add_service_dir("/usr/local/lib/dinit.d", false); + services->add_service_dir("/lib/dinit.d", false); + } init_log(services); if (am_system_init) {