Add the nojail keyword which excludes services marked as such from the dependency tree when in a jail, #bug 22

This commit is contained in:
Roy Marples 2008-02-19 14:15:53 +00:00
parent f95e0b2c3e
commit 0364bb2c84
25 changed files with 121 additions and 41 deletions

View File

@ -9,6 +9,7 @@ depend()
{
need root
before devd net
keywords nojail
}
_set()

View File

@ -16,6 +16,7 @@ depend()
{
need localmount
after bootmisc
keywords nojail
}
start()

View File

@ -11,6 +11,7 @@ extra_started_commands="reload"
depend() {
need localmount
keywords nojail
}
start()

View File

@ -6,7 +6,8 @@ description="Saves a kernel dump."
depend()
{
need localmount
need localmount
keywords nojail
}
start()

View File

@ -21,6 +21,7 @@ depend()
[ "${clock}" != "UTC" -a ! -e /etc/wall_cmos_clock ]; then
need root
fi
keywords nojail
}
start()

View File

@ -10,6 +10,7 @@ depend() {
need localmount
after bootmisc
before net.lo0
keywords nojail
}
start_pre() {

View File

@ -6,6 +6,7 @@ description="Configures a specific kernel dump device."
depend() {
need swap
keywords nojail
}
start() {

View File

@ -13,6 +13,7 @@ opts="panic showstatus"
depend() {
before net
provide firewall
keywords nojail
}
ipfw() {

View File

@ -6,7 +6,8 @@ extra_commands="restore"
depend()
{
need localmount
need localmount
keywords nojail
}
restore()

View File

@ -12,6 +12,7 @@ depend()
need localmount
use logger
after bootmisc
keywords nojail
}
start_pre()

View File

@ -4,6 +4,7 @@
depend() {
need localmount
keywords nojail
}
start() {

View File

@ -7,7 +7,7 @@ description="Check and repair filesystems according to /etc/fstab"
depend()
{
after clock modules
keywords notimeout
keywords nojail notimeout
}
start()

View File

@ -8,6 +8,7 @@ depend()
{
need fsck
use modules mtab
keywords nojail
}
start()

View File

@ -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()

View File

@ -7,6 +7,7 @@ description="Mount the root fs read/write"
depend()
{
need fsck
keywords nojail
}
start()

View File

@ -5,6 +5,7 @@
depend()
{
need localmount
keywords nojail
}
start()

View File

@ -9,6 +9,7 @@ description="Initializes the random number generator."
depend()
{
need localmount
keywords nojail
}
save_seed()

View File

@ -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

View File

@ -21,6 +21,7 @@ depend()
need localmount
after bootmisc
provide net
keywords nojail
case "${IFACE}" in
lo|lo0);;

View File

@ -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)
{

View File

@ -32,6 +32,9 @@
const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include "librc.h"
#ifdef __FreeBSD__
#include <sys/sysctl.h>
#endif
#include <signal.h>
#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;

View File

@ -40,6 +40,7 @@
#include <sys/time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>

View File

@ -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. */

View File

@ -52,6 +52,7 @@ global:
rc_strlist_free;
rc_strlist_join;
rc_strlist_reverse;
rc_sys;
rc_yesno;
local:

View File

@ -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) {