diff --git a/init.d.BSD/hostid b/init.d.BSD/hostid index 57fc6001..c4087512 100644 --- a/init.d.BSD/hostid +++ b/init.d.BSD/hostid @@ -9,6 +9,7 @@ depend() { need root before devd net + keywords nojail } _set() diff --git a/init.d.BSD/moused b/init.d.BSD/moused index f168314d..85015684 100644 --- a/init.d.BSD/moused +++ b/init.d.BSD/moused @@ -16,6 +16,7 @@ depend() { need localmount after bootmisc + keywords nojail } start() diff --git a/init.d.BSD/pf b/init.d.BSD/pf index bf2ac1a6..4a615ec7 100644 --- a/init.d.BSD/pf +++ b/init.d.BSD/pf @@ -11,6 +11,7 @@ extra_started_commands="reload" depend() { need localmount + keywords nojail } start() diff --git a/init.d.BSD/savecore b/init.d.BSD/savecore index 217c0817..3b9ffb29 100755 --- a/init.d.BSD/savecore +++ b/init.d.BSD/savecore @@ -6,7 +6,8 @@ description="Saves a kernel dump." depend() { - need localmount + need localmount + keywords nojail } start() diff --git a/init.d.FreeBSD/clock b/init.d.FreeBSD/clock index f26bef2a..6a8485c9 100644 --- a/init.d.FreeBSD/clock +++ b/init.d.FreeBSD/clock @@ -21,6 +21,7 @@ depend() [ "${clock}" != "UTC" -a ! -e /etc/wall_cmos_clock ]; then need root fi + keywords nojail } start() diff --git a/init.d.FreeBSD/devd b/init.d.FreeBSD/devd index ff500bfa..76706b43 100644 --- a/init.d.FreeBSD/devd +++ b/init.d.FreeBSD/devd @@ -10,6 +10,7 @@ depend() { need localmount after bootmisc before net.lo0 + keywords nojail } start_pre() { diff --git a/init.d.FreeBSD/dumpon b/init.d.FreeBSD/dumpon index 9d40f915..fbe3d1c3 100644 --- a/init.d.FreeBSD/dumpon +++ b/init.d.FreeBSD/dumpon @@ -6,6 +6,7 @@ description="Configures a specific kernel dump device." depend() { need swap + keywords nojail } start() { diff --git a/init.d.FreeBSD/ipfw b/init.d.FreeBSD/ipfw index c1c0cb35..5ef366b2 100644 --- a/init.d.FreeBSD/ipfw +++ b/init.d.FreeBSD/ipfw @@ -13,6 +13,7 @@ opts="panic showstatus" depend() { before net provide firewall + keywords nojail } ipfw() { diff --git a/init.d.FreeBSD/mixer b/init.d.FreeBSD/mixer index 81341e9b..c169033c 100644 --- a/init.d.FreeBSD/mixer +++ b/init.d.FreeBSD/mixer @@ -6,7 +6,8 @@ extra_commands="restore" depend() { - need localmount + need localmount + keywords nojail } restore() diff --git a/init.d.FreeBSD/powerd b/init.d.FreeBSD/powerd index 3d3ae7f0..b44128e0 100644 --- a/init.d.FreeBSD/powerd +++ b/init.d.FreeBSD/powerd @@ -12,6 +12,7 @@ depend() need localmount use logger after bootmisc + keywords nojail } start_pre() diff --git a/init.d.FreeBSD/syscons b/init.d.FreeBSD/syscons index 93d3c7c6..af76baba 100644 --- a/init.d.FreeBSD/syscons +++ b/init.d.FreeBSD/syscons @@ -4,6 +4,7 @@ depend() { need localmount + keywords nojail } start() { diff --git a/init.d/fsck b/init.d/fsck index 3ee3b38b..4c184cf2 100644 --- a/init.d/fsck +++ b/init.d/fsck @@ -7,7 +7,7 @@ description="Check and repair filesystems according to /etc/fstab" depend() { after clock modules - keywords notimeout + keywords nojail notimeout } start() diff --git a/init.d/localmount b/init.d/localmount index 5b8e849c..999fa076 100755 --- a/init.d/localmount +++ b/init.d/localmount @@ -8,6 +8,7 @@ depend() { need fsck use modules mtab + keywords nojail } start() diff --git a/init.d/netmount b/init.d/netmount index dd149a96..bb97d88a 100755 --- a/init.d/netmount +++ b/init.d/netmount @@ -34,6 +34,7 @@ depend() config /etc/fstab need net ${pmap} use afc-client amd autofs dns nfs nfsmount portmap rpcbind rpc.statd + keywords nojail } start() diff --git a/init.d/root b/init.d/root index fa20ebd8..948826e5 100644 --- a/init.d/root +++ b/init.d/root @@ -7,6 +7,7 @@ description="Mount the root fs read/write" depend() { need fsck + keywords nojail } start() diff --git a/init.d/swap b/init.d/swap index 53cf45c6..c11abb55 100644 --- a/init.d/swap +++ b/init.d/swap @@ -5,6 +5,7 @@ depend() { need localmount + keywords nojail } start() diff --git a/init.d/urandom b/init.d/urandom index d02c66d0..bc1e7b7d 100755 --- a/init.d/urandom +++ b/init.d/urandom @@ -9,6 +9,7 @@ description="Initializes the random number generator." depend() { need localmount + keywords nojail } save_seed() diff --git a/man/runscript.8 b/man/runscript.8 index 738bb754..7a05c6d6 100644 --- a/man/runscript.8 +++ b/man/runscript.8 @@ -132,9 +132,14 @@ We provide this virtual service. For example, named provides dns. .It Ic config We should recalculate our dependencies if the listed files have changed. .It Ic keywords -Tags a service with a keyword. Currently the only keyword is notimeout -which means that services do not time out waiting for that service, which only -applies when services are enabled to start and stop in parallel. +Tags a service with a keyword. Here's the keywords we currently understand:- +.Bl -tag -width indent +.It Dv nojail +When in a jail, exclude this service from any dependencies. The service can +still be run directly. +.It Dv notimeout +do not time out waiting for that service. +.El .El .Pp To see how to influence dependencies in configuration files, see the diff --git a/sh/net.sh b/sh/net.sh index c7219086..7dc282fa 100755 --- a/sh/net.sh +++ b/sh/net.sh @@ -21,6 +21,7 @@ depend() need localmount after bootmisc provide net + keywords nojail case "${IFACE}" in lo|lo0);; diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c index 59284344..c7c782c7 100644 --- a/src/librc/librc-depend.c +++ b/src/librc/librc-depend.c @@ -741,24 +741,23 @@ bool rc_deptree_update (void) rc_deptype_t *dt; rc_deptype_t *last_deptype = NULL; char *line; - int len; - int i; - int j; - int k; + size_t len; + size_t i; + size_t j; + size_t k; bool already_added; + const char *sys = rc_sys (); /* Some init scripts need RC_LIBDIR to source stuff Ideally we should be setting our full env instead */ if (! getenv ("RC_LIBDIR")) setenv ("RC_LIBDIR", RC_LIBDIR, 0); - /* Phase 1 */ + /* Phase 1 - source all init scripts and print dependencies */ if (! (fp = popen (GENDEP, "r"))) return (false); deptree = xzalloc (sizeof (*deptree)); - - /* Phase 2 */ while ((line = rc_getline (fp))) { depends = line; @@ -865,6 +864,46 @@ next: } pclose (fp); + /* Phase 2 - if we're a special system, remove services that don't + * work for them. This doesn't stop them from being run directly. */ + if (sys) { + char *nosys; + + len = strlen (sys); + nosys = xmalloc (len + 3); + nosys[0] = 'n'; + nosys[1] = 'o'; + for (i = 0; i < len; i++) + nosys[i + 2] = tolower (sys[i]); + nosys[i + 2] = '\0'; + + last_depinfo = NULL; + for (depinfo = deptree; depinfo; depinfo = depinfo->next) + { + bool removed = false; + if ((deptype = get_deptype (depinfo, "keywords"))) { + STRLIST_FOREACH (deptype->services, service, i) + if (strcmp (service, nosys) == 0) { + if (last_depinfo) + last_depinfo->next = depinfo->next; + else + deptree = depinfo->next; + removed = true; + break; + } + } + if (removed) { + for (di = deptree; di; di = di->next) { + for (dt = di->depends; dt; dt = dt->next) + rc_strlist_delete (&dt->services, depinfo->service); + } + } else + last_depinfo = depinfo; + } + + free (nosys); + } + /* Phase 3 - add our providors to the tree */ for (depinfo = deptree; depinfo; depinfo = depinfo->next) { diff --git a/src/librc/librc.c b/src/librc/librc.c index 75019eec..f323d0fd 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -32,6 +32,9 @@ const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples"; #include "librc.h" +#ifdef __FreeBSD__ +#include +#endif #include #define SOFTLEVEL RC_SVCDIR "/softlevel" @@ -144,6 +147,36 @@ static bool rm_dir (const char *pathname, bool top) return (true); } +const char *rc_sys (void) +{ +#ifdef __FreeBSD__ + int jailed = 0; + size_t len = sizeof (jailed); + + if (sysctlbyname ("security.jail.jailed", &jailed, &len, NULL, 0) == 0) + if (jailed == 1) + return (RC_SYS_JAIL); +#endif + +#ifdef __linux__ + if (exists ("/proc/xen")) { + if ((fp = fopen ("/proc/xen/capabilities", "r"))) { + fclose (fp); + if (file_regex ("/proc/xen/capabilities", "control_d")) + return (RC_SYS_XEN0); + } + if (! sys[0]) + return (RC_SYS_XENU); + } else if (file_regex ("/proc/cpuinfo", "UML")) + return (RC_SYS_UML); + else if (file_regex ("/proc/self/status", + "(s_context|VxID|envID):[[:space:]]*[1-9]")) + return (RC_SYS_VPS); +#endif + + return (NULL); +} + static const char *rc_parse_service_state (rc_service_state_t state) { int i; diff --git a/src/librc/librc.h b/src/librc/librc.h index 7a5d9a0e..7e917e3a 100644 --- a/src/librc/librc.h +++ b/src/librc/librc.h @@ -40,6 +40,7 @@ #include #include +#include #include #include #include diff --git a/src/librc/rc.h b/src/librc/rc.h index 1f1a9a76..690b14f6 100644 --- a/src/librc/rc.h +++ b/src/librc/rc.h @@ -228,6 +228,16 @@ char **rc_services_scheduled (const char *service); * @return true if all daemons started are still running, otherwise false */ bool rc_service_daemons_crashed (const char *service); +/*! @name System types + * OpenRC can support some special sub system types, normally virtualization. + * Some services cannot work in these systems, or we do something else. */ +#define RC_SYS_JAIL "JAIL" +#define RC_SYS_UML "UML" +#define RC_SYS_VPS "VPS" +#define RC_SYS_XEN0 "XEN0" +#define RC_SYS_XENU "XENU" +const char *rc_sys (void); + /*! @name Dependency options * These options can change the services found by the rc_get_depinfo and * rc_get_depends functions. */ diff --git a/src/librc/rc.map b/src/librc/rc.map index e60ea183..e5fd350b 100644 --- a/src/librc/rc.map +++ b/src/librc/rc.map @@ -52,6 +52,7 @@ global: rc_strlist_free; rc_strlist_join; rc_strlist_reverse; + rc_sys; rc_yesno; local: diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c index e56f8006..1c340dd6 100644 --- a/src/rc/rc-misc.c +++ b/src/rc/rc-misc.c @@ -276,9 +276,7 @@ char **env_config (void) char **env = NULL; char *line; size_t l; -#ifdef __linux__ - char sys[6]; -#endif + const char *sys = rc_sys (); struct utsname uts; FILE *fp; char buffer[PATH_MAX]; @@ -323,29 +321,7 @@ char **env_config (void) } else rc_strlist_add (&env, "RC_DEFAULTLEVEL=" RC_LEVEL_DEFAULT); - -#ifdef __linux__ - /* Linux can run some funky stuff like Xen, VServer, UML, etc - We store this special system in RC_SYS so our scripts run fast */ - memset (sys, 0, sizeof (sys)); - - if (exists ("/proc/xen")) { - if ((fp = fopen ("/proc/xen/capabilities", "r"))) { - fclose (fp); - if (file_regex ("/proc/xen/capabilities", "control_d")) - snprintf (sys, sizeof (sys), "XEN0"); - } - if (! sys[0]) - snprintf (sys, sizeof (sys), "XENU"); - } else if (file_regex ("/proc/cpuinfo", "UML")) { - snprintf (sys, sizeof (sys), "UML"); - } else if (file_regex ("/proc/self/status", - "(s_context|VxID|envID):[[:space:]]*[1-9]")) - { - snprintf (sys, sizeof (sys), "VPS"); - } - - if (sys[0]) { + if (sys) { l = strlen ("RC_SYS=") + strlen (sys) + 2; line = xmalloc (sizeof (char) * l); snprintf (line, l, "RC_SYS=%s", sys); @@ -353,8 +329,6 @@ char **env_config (void) free (line); } -#endif - /* Some scripts may need to take a different code path if Linux/FreeBSD, etc To save on calling uname, we store it in an environment variable */ if (uname (&uts) == 0) {