summaryrefslogtreecommitdiff
path: root/src/librc
diff options
context:
space:
mode:
Diffstat (limited to 'src/librc')
-rw-r--r--src/librc/librc-depend.c53
-rw-r--r--src/librc/librc.c33
-rw-r--r--src/librc/librc.h1
-rw-r--r--src/librc/rc.h10
-rw-r--r--src/librc/rc.map1
5 files changed, 91 insertions, 7 deletions
diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
index 5928434..c7c782c 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 75019ee..f323d0f 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 <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;
diff --git a/src/librc/librc.h b/src/librc/librc.h
index 7a5d9a0..7e917e3 100644
--- a/src/librc/librc.h
+++ b/src/librc/librc.h
@@ -40,6 +40,7 @@
#include <sys/time.h>
#include <sys/wait.h>
+#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/src/librc/rc.h b/src/librc/rc.h
index 1f1a9a7..690b14f 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 e60ea18..e5fd350 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: