aboutsummaryrefslogtreecommitdiff
path: root/src/rc/rc.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-10-10 08:37:21 +0000
committerRoy Marples <roy@marples.name>2008-10-10 08:37:21 +0000
commitd6da8e8c48feb8faf9287fc86fbbf0890c37a87c (patch)
treee6cdf21f0f3a3270b705fe14b876f92b14b38dbf /src/rc/rc.c
parent247766695cd7c5e8d83dff72f7eb7e6578bf57b8 (diff)
sysinit is now a real runlevel that handles things like udev, dmesg and
mounting various bits in /dev and /sys. init.sh JUST mounts /lib/rc/init.d (and /proc for Linux systems) To make development of this easier we now return an empty RC_STRINGLIST instead of a NULL for empty things. If you don't have a udev init script installed, don't reboot your box OR roll back to an older OpenRC version.
Diffstat (limited to 'src/rc/rc.c')
-rw-r--r--src/rc/rc.c215
1 files changed, 42 insertions, 173 deletions
diff --git a/src/rc/rc.c b/src/rc/rc.c
index 4fee7002..cb4045f0 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -43,12 +43,6 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include <sys/utsname.h>
#include <sys/wait.h>
-/* So we can coldplug net devices */
-#ifdef BSD
-# include <sys/socket.h>
-# include <ifaddrs.h>
-#endif
-
#ifdef __linux__
# include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#endif
@@ -519,115 +513,10 @@ static void handle_signal(int sig)
errno = serrno;
}
-static void do_coldplug(void)
-{
- size_t l;
- DIR *dp;
- struct dirent *d;
- char *service;
- RC_STRING *s;
-#ifdef BSD
- struct ifaddrs *ifap;
- struct ifaddrs *ifa;
- char *p;
-#endif
-
- errno = 0;
- if (!rc_conf_yesno("rc_coldplug") && errno != ENOENT)
- return;
-
- /* We need to ensure our state dirs exist.
- * We should have a better call than this, but oh well. */
- rc_deptree_update_needed();
-
-#ifdef BSD
- if (getifaddrs(&ifap) == 0) {
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr->sa_family != AF_LINK)
- continue;
-
- l = strlen("net.") + strlen(ifa->ifa_name) + 1;
- service = xmalloc(sizeof (char) * l);
- snprintf(service, l, "net.%s", ifa->ifa_name);
- if (rc_service_exists(service) &&
- service_plugable(service))
- rc_service_mark(service, RC_SERVICE_COLDPLUGGED);
- free(service);
- }
- freeifaddrs (ifap);
- }
-
- /* The mice are a little more tricky.
- * If we coldplug anything else, we'll probably do it here. */
- if ((dp = opendir("/dev"))) {
- while ((d = readdir(dp))) {
- if (strncmp(d->d_name, "psm", 3) == 0 ||
- strncmp(d->d_name, "ums", 3) == 0)
- {
- p = d->d_name + 3;
- if (p && isdigit((unsigned char)*p)) {
- l = strlen("moused.") + strlen(d->d_name) + 1;
- service = xmalloc(sizeof(char) * l);
- snprintf (service, l, "moused.%s", d->d_name);
- if (rc_service_exists (service) &&
- service_plugable (service))
- rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
- free(service);
- }
- }
- }
- closedir (dp);
- }
-
-#else
-
- /* udev likes to start services before we're ready when it does
- * its coldplugging thing. runscript knows when we're not ready so it
- * stores a list of coldplugged services in DEVBOOT for us to pick up
- * here when we are ready for them */
- if ((dp = opendir(DEVBOOT))) {
- while ((d = readdir(dp))) {
- if (d->d_name[0] == '.' &&
- (d->d_name[1] == '\0' ||
- (d->d_name[1] == '.' && d->d_name[2] == '\0')))
- continue;
-
- if (rc_service_exists(d->d_name) &&
- service_plugable(d->d_name))
- rc_service_mark(d->d_name, RC_SERVICE_COLDPLUGGED);
-
- l = strlen(DEVBOOT "/") + strlen(d->d_name) + 1;
- service = xmalloc(sizeof (char) * l);
- snprintf(service, l, DEVBOOT "/%s", d->d_name);
- if (unlink(service))
- eerror("%s: unlink `%s': %s", applet, service,
- strerror(errno));
- free(service);
- }
- closedir(dp);
- rmdir(DEVBOOT);
- }
-#endif
-
- if (rc_yesno(getenv("EINFO_QUIET")))
- return;
-
- /* Load our list of coldplugged services and display them */
- einfon("Device initiated services:%s", ecolor(ECOLOR_HILITE));
- coldplugged_services = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
- if (coldplugged_services)
- TAILQ_FOREACH(s, coldplugged_services, entries)
- printf(" %s", s->value);
- printf("%s\n", ecolor(ECOLOR_NORMAL));
-}
-
static void do_newlevel(const char *newlevel)
{
struct utsname uts;
const char *sys;
-#ifdef __linux__
- char *cmd;
-#endif
if (strcmp(newlevel, RC_LEVEL_SYSINIT) == 0
#ifndef PREFIX
@@ -669,39 +558,13 @@ static void do_newlevel(const char *newlevel)
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL));
setenv("RC_RUNLEVEL", newlevel, 1);
- rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, newlevel);
- hook_out = RC_HOOK_RUNLEVEL_START_OUT;
run_program(INITSH);
-
-#ifdef __linux__
- /* If we requested a runlevel, save it now */
- if ((cmd = proc_getent("rc_runlevel"))) {
- set_krunlevel(cmd);
- free(cmd);
- } else if ((cmd = proc_getent("softlevel"))) {
- set_krunlevel(cmd);
- free(cmd);
- } else
- set_krunlevel(NULL);
-#endif
-
- /* Setup our coldplugged services now */
- do_coldplug();
-
- rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, newlevel);
- hook_out = 0;
-
- if (want_interactive())
- mark_interactive();
-
- exit(EXIT_SUCCESS);
} else if (strcmp(newlevel, RC_LEVEL_SINGLE) == 0) {
#ifndef PREFIX
if (! RUNLEVEL ||
(strcmp(RUNLEVEL, "S") != 0 &&
strcmp(RUNLEVEL, "1") != 0))
{
- /* Remember the current runlevel for when we come back */
set_krunlevel(runlevel);
single_user();
}
@@ -883,7 +746,12 @@ interactive_option:
if (! parallel) {
rc_waitpid(pid);
remove_pid(pid);
+ /* Attempt to open the logger as a service may
+ * mount the needed /dev/pts for this to work */
+ if (rc_logger_tty == -1)
+ rc_logger_open(runlevel);
}
+
}
}
@@ -1076,7 +944,8 @@ int main(int argc, char **argv)
{
/* Try not to join boot and krunlevels together */
if (! newlevel ||
- strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0)
+ (strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0 &&
+ strcmp(newlevel, RC_LEVEL_SYSINIT) != 0))
if (get_krunlevel(krunlevel, sizeof(krunlevel)))
newlevel = krunlevel;
} else if (! RUNLEVEL ||
@@ -1135,21 +1004,11 @@ int main(int argc, char **argv)
* correct order for stopping them */
stop_services = rc_services_in_state(RC_SERVICE_STARTED);
tmplist = rc_services_in_state(RC_SERVICE_INACTIVE);
- if (tmplist) {
- if (stop_services) {
- TAILQ_CONCAT(stop_services, tmplist, entries);
- free(tmplist);
- } else
- stop_services = tmplist;
- }
+ TAILQ_CONCAT(stop_services, tmplist, entries);
+ free(tmplist);
tmplist = rc_services_in_state(RC_SERVICE_STARTING);
- if (tmplist) {
- if (stop_services) {
- TAILQ_CONCAT(stop_services, tmplist, entries);
- free(tmplist);
- } else
- stop_services = tmplist;
- }
+ TAILQ_CONCAT(stop_services, tmplist, entries);
+ free(tmplist);
if (stop_services)
rc_stringlist_sort(&stop_services);
@@ -1171,24 +1030,30 @@ int main(int argc, char **argv)
strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
{
- /* We need to include the boot runlevel services if we're not in it */
- start_services = rc_services_in_runlevel(bootlevel);
- if (strcmp (newlevel ? newlevel : runlevel, bootlevel) != 0) {
- tmplist = rc_services_in_runlevel(newlevel ? newlevel : runlevel);
- if (tmplist) {
- if (start_services) {
- TAILQ_CONCAT(start_services, tmplist, entries);
- free(tmplist);
- } else
- start_services = tmplist;
+ start_services = rc_services_in_runlevel(RC_LEVEL_SYSINIT);
+ if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SYSINIT)
+ != 0)
+ {
+ /* We need to include the boot runlevel services */
+ tmplist = rc_services_in_runlevel(bootlevel);
+ TAILQ_CONCAT(start_services, tmplist, entries);
+ free(tmplist);
+ if (strcmp (newlevel ? newlevel : runlevel, bootlevel)
+ != 0)
+ {
+ tmplist = rc_services_in_runlevel(newlevel ?
+ newlevel :
+ runlevel);
+ TAILQ_CONCAT(start_services, tmplist, entries);
+ free(tmplist);
}
- }
- if (coldplugged_services) {
- if (!start_services)
- start_services = rc_stringlist_new();
- TAILQ_FOREACH(service, coldplugged_services, entries)
- rc_stringlist_addu(start_services, service->value);
+ if (coldplugged_services) {
+ if (!start_services)
+ start_services = rc_stringlist_new();
+ TAILQ_FOREACH(service, coldplugged_services, entries)
+ rc_stringlist_addu(start_services, service->value);
+ }
}
}
@@ -1265,14 +1130,15 @@ int main(int argc, char **argv)
if (start_services) {
do_start_services(parallel);
+ /* FIXME: If we skip the boot runlevel and go straight
+ * to default from sysinit, we should now re-evaluate our
+ * start services + coldplugged services and call
+ * do_start_services a second time. */
/* Wait for our services to finish */
wait_for_services();
}
- rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, runlevel);
- hook_out = 0;
-
#ifdef __linux__
/* mark any services skipped as stopped */
if (PREVLEVEL && strcmp(PREVLEVEL, "N") == 0) {
@@ -1285,12 +1151,15 @@ int main(int argc, char **argv)
}
#endif
+ rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, runlevel);
+ hook_out = 0;
+
/* If we're in the boot runlevel and we regenerated our dependencies
* we need to delete them so that they are regenerated again in the
- * default runlevel as they may depend on things that are now available */
+ * default runlevel as they may depend on things that are now
+ * available */
if (regen && strcmp(runlevel, bootlevel) == 0)
unlink(RC_DEPTREE_CACHE);
return EXIT_SUCCESS;
}
-