aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/includes/rc-misc.h5
-rw-r--r--src/rc/_usage.c5
-rw-r--r--src/rc/rc-misc.c333
-rw-r--r--src/rc/rc.c19
4 files changed, 186 insertions, 176 deletions
diff --git a/src/includes/rc-misc.h b/src/includes/rc-misc.h
index de73c5c1..f2449cd7 100644
--- a/src/includes/rc-misc.h
+++ b/src/includes/rc-misc.h
@@ -43,7 +43,6 @@
char *rc_conf_value(const char *var);
bool rc_conf_yesno(const char *var);
-char *get_systype(void);
void env_filter(void);
void env_config(void);
int signal_setup(int sig, void (*handler)(int));
@@ -61,6 +60,10 @@ int is_writable(const char *);
#define service_stop(service) exec_service(service, "stop");
int parse_mode(mode_t *, char *);
+const char *detect_prefix(void);
+const char *get_systype(void);
+const char *detect_container(void);
+const char *detect_vm(void);
/* Handy function so we can wrap einfo around our deptree */
RC_DEPTREE *_rc_deptree_load (int, int *);
diff --git a/src/rc/_usage.c b/src/rc/_usage.c
index 40d81422..9fc3e5d8 100644
--- a/src/rc/_usage.c
+++ b/src/rc/_usage.c
@@ -44,9 +44,12 @@ void set_quiet_options(void)
_noreturn void show_version(void)
{
- char *systype = get_systype();
+ const char *systype = NULL;
printf("%s (OpenRC", applet);
+ systype = detect_container();
+ if (!systype)
+ systype = detect_vm();
if (systype)
printf(" [%s]", systype);
printf(") %s", VERSION);
diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c
index e0e6e2c7..2c6c3883 100644
--- a/src/rc/rc-misc.c
+++ b/src/rc/rc-misc.c
@@ -50,172 +50,6 @@ rc_conf_yesno(const char *setting)
return rc_yesno(rc_conf_value (setting));
}
-/*
- * static bool is_container(const char *systype)
- * {
- * FreeBSD: RC_SYS_JAIL
- * Linux: RC_SYS_UML RC_SYS_VSERVER RC_SYS_OPENVZ RC_SYS_LXC
- * RC_SYS_RKT RC_SYS_SYSTEMD_NSPAWN RC_SYS_DOCKER
- * }
- *
- * static bool is_vm(const char *systype)
- * {
- * NetBSD: RC_SYS_XEN0 RC_SYS_XENU
- * Linux: RC_SYS_XEN0 RC_SYS_XENU
- * }
- */
-
-static bool file_regex(const char *file, const char *regex)
-{
- FILE *fp;
- char *line = NULL;
- size_t len = 0;
- regex_t re;
- bool retval = true;
- int result;
-
- if (!(fp = fopen(file, "r")))
- return false;
-
- if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
- fclose(fp);
- line = xmalloc(sizeof(char) * BUFSIZ);
- regerror(result, &re, line, BUFSIZ);
- fprintf(stderr, "file_regex: %s", line);
- free(line);
- return false;
- }
-
- while ((rc_getline(&line, &len, fp))) {
- char *str = line;
- /* some /proc files have \0 separated content so we have to
- loop through the 'line' */
- do {
- if (regexec(&re, str, 0, NULL, 0) == 0)
- goto found;
- str += strlen(str) + 1;
- /* len is the size of allocated buffer and we don't
- want call regexec BUFSIZE times. find next str */
- while (str < line + len && *str == '\0')
- str++;
- } while (str < line + len);
- }
- retval = false;
-found:
- fclose(fp);
- free(line);
- regfree(&re);
-
- return retval;
-}
-
-char *get_systype(void)
-{
- char *systype = rc_conf_value("rc_sys");
- char *s;
-
- if (systype) {
- if (*systype == '\0') {
- free(systype);
- return NULL;
- }
- s = systype;
- /* Convert to uppercase */
- while (s && *s) {
- if (islower((unsigned char) *s))
- *s = toupper((unsigned char) *s);
- s++;
- }
- if (strcmp(systype,RC_SYS_PREFIX) == 0)
- return systype;
-
-#ifdef __FreeBSD__
- if (strcmp(systype, RC_SYS_JAIL) == 0)
- return systype;
-#endif
-
-#ifdef __linux__
- if (strcmp(systype, RC_SYS_UML) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_VSERVER) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_OPENVZ) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_LXC) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_RKT) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_SYSTEMD_NSPAWN) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_DOCKER) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_XEN0) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_XENU) == 0)
- return systype;
-#endif
-
-#ifdef __NetBSD__
- if(strcmp(systype, RC_SYS_XEN0) == 0)
- return systype;
- else if (strcmp(systype, RC_SYS_XENU) == 0)
- return systype;
-#endif
- }
-
- free(systype);
- systype = NULL;
-
-#ifdef PREFIX
- systype = xstrdup(RC_SYS_PREFIX);
- return systype;
-#endif
-
-#ifdef __FreeBSD__
- int jailed = 0;
- size_t len = sizeof(jailed);
-
- if (sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0) == 0)
- if (jailed == 1)
- systype = xstrdup(RC_SYS_JAIL);
-#endif
-
-#ifdef __linux__
- if (file_regex("/proc/cpuinfo", "UML"))
- systype = xstrdup(RC_SYS_UML);
- else if (file_regex("/proc/self/status",
- "(s_context|VxID):[[:space:]]*[1-9]"))
- systype = xstrdup(RC_SYS_VSERVER);
- else if (exists("/proc/vz/veinfo") && !exists("/proc/vz/version"))
- systype = xstrdup(RC_SYS_OPENVZ);
- else if (file_regex("/proc/self/status",
- "envID:[[:space:]]*[1-9]"))
- systype = xstrdup(RC_SYS_OPENVZ); /* old test */
- else if (file_regex("/proc/1/environ", "container=lxc"))
- systype = xstrdup(RC_SYS_LXC);
- else if (file_regex("/proc/1/environ", "container=rkt"))
- systype = xstrdup(RC_SYS_RKT);
- else if (file_regex("/proc/1/environ", "container=systemd-nspawn"))
- systype = xstrdup(RC_SYS_SYSTEMD_NSPAWN);
- else if (file_regex("/proc/1/environ", "container=docker"))
- systype = xstrdup(RC_SYS_DOCKER);
- else if (exists("/proc/xen")) {
- if (file_regex("/proc/xen/capabilities", "control_d"))
- systype = xstrdup(RC_SYS_XEN0);
- systype = xstrdup(RC_SYS_XENU);
- }
-#endif
-
-#ifdef __NetBSD__
- if (exists("/kern/xen/privcmd"))
- systype = xstrdup(RC_SYS_XEN0);
- else if (exists("/kern/xen"))
- systype = xstrdup(RC_SYS_XENU);
-#endif
-
- return systype;
-}
-
static const char *const env_whitelist[] = {
"EERROR_QUIET", "EINFO_QUIET",
"IN_BACKGROUND", "IN_HOTPLUG",
@@ -292,7 +126,7 @@ env_config(void)
char *np;
char *npp;
char *tok;
- char *sys = get_systype();
+ const char *sys = NULL;
char buffer[PATH_MAX];
/* Ensure our PATH is prefixed with the system locations first
@@ -343,10 +177,12 @@ env_config(void)
} else
setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1);
- if (sys) {
+ sys = detect_container();
+ if (!sys)
+ sys = detect_vm();
+
+ if (sys)
setenv("RC_SYS", sys, 1);
- free(sys);
- }
#ifdef PREFIX
setenv("RC_PREFIX", RC_PREFIX, 1);
@@ -502,6 +338,163 @@ is_writable(const char *path)
return 0;
}
+static bool file_regex(const char *file, const char *regex)
+{
+ FILE *fp;
+ char *line = NULL;
+ size_t len = 0;
+ regex_t re;
+ bool retval = true;
+ int result;
+
+ if (!(fp = fopen(file, "r")))
+ return false;
+
+ if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
+ fclose(fp);
+ line = xmalloc(sizeof(char) * BUFSIZ);
+ regerror(result, &re, line, BUFSIZ);
+ fprintf(stderr, "file_regex: %s", line);
+ free(line);
+ return false;
+ }
+
+ while ((rc_getline(&line, &len, fp))) {
+ char *str = line;
+ /* some /proc files have \0 separated content so we have to
+ loop through the 'line' */
+ do {
+ if (regexec(&re, str, 0, NULL, 0) == 0)
+ goto found;
+ str += strlen(str) + 1;
+ /* len is the size of allocated buffer and we don't
+ want call regexec BUFSIZE times. find next str */
+ while (str < line + len && *str == '\0')
+ str++;
+ } while (str < line + len);
+ }
+ retval = false;
+found:
+ fclose(fp);
+ free(line);
+ regfree(&re);
+
+ return retval;
+}
+
+const char *detect_prefix(void)
+{
+#ifdef PREFIX
+ return RC_SYS_PREFIX;
+#else
+ return NULL;
+#endif
+}
+
+const char *get_systype(void)
+{
+ char *systype = rc_conf_value("rc_sys");
+ if (systype) {
+ char *s = systype;
+ /* Convert to uppercase */
+ while (s && *s) {
+ if (islower((unsigned char) *s))
+ *s = toupper((unsigned char) *s);
+ s++;
+ }
+ }
+ return systype;
+}
+
+const char *detect_container(void)
+{
+ const char *systype = get_systype();
+
+#ifdef __FreeBSD__
+ if (systype && strcmp(systype, RC_SYS_JAIL) == 0)
+ return RC_SYS_JAIL;
+ 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 (systype) {
+ if (strcmp(systype, RC_SYS_UML) == 0)
+ return RC_SYS_UML;
+ if (strcmp(systype, RC_SYS_VSERVER) == 0)
+ return RC_SYS_VSERVER;
+ if (strcmp(systype, RC_SYS_OPENVZ) == 0)
+ return RC_SYS_OPENVZ;
+ if (strcmp(systype, RC_SYS_LXC) == 0)
+ return RC_SYS_LXC;
+ if (strcmp(systype, RC_SYS_RKT) == 0)
+ return RC_SYS_RKT;
+ if (strcmp(systype, RC_SYS_SYSTEMD_NSPAWN) == 0)
+ return RC_SYS_SYSTEMD_NSPAWN;
+ if (strcmp(systype, RC_SYS_DOCKER) == 0)
+ return RC_SYS_DOCKER;
+ }
+ if (file_regex("/proc/cpuinfo", "UML"))
+ return RC_SYS_UML;
+ else if (file_regex("/proc/self/status",
+ "(s_context|VxID):[[:space:]]*[1-9]"))
+ return RC_SYS_VSERVER;
+ else if (exists("/proc/vz/veinfo") && !exists("/proc/vz/version"))
+ return RC_SYS_OPENVZ;
+ else if (file_regex("/proc/self/status",
+ "envID:[[:space:]]*[1-9]"))
+ return RC_SYS_OPENVZ; /* old test */
+ else if (file_regex("/proc/1/environ", "container=lxc"))
+ return RC_SYS_LXC;
+ else if (file_regex("/proc/1/environ", "container=rkt"))
+ return RC_SYS_RKT;
+ else if (file_regex("/proc/1/environ", "container=systemd-nspawn"))
+ return RC_SYS_SYSTEMD_NSPAWN;
+ else if (file_regex("/proc/1/environ", "container=docker"))
+ return RC_SYS_DOCKER;
+#endif
+
+ return NULL;
+}
+
+const char *detect_vm(void)
+{
+ const char *systype = get_systype();
+
+#ifdef __NetBSD__
+ if (systype) {
+ if(strcmp(systype, RC_SYS_XEN0) == 0)
+ return RC_SYS_XEN0;
+ if (strcmp(systype, RC_SYS_XENU) == 0)
+ return RC_SYS_XENU;
+ }
+ if (exists("/kern/xen/privcmd"))
+ return RC_SYS_XEN0;
+ if (exists("/kern/xen"))
+ return RC_SYS_XENU;
+#endif
+
+#ifdef __linux__
+ if (systype) {
+ if (strcmp(systype, RC_SYS_XEN0) == 0)
+ return RC_SYS_XEN0;
+ if (strcmp(systype, RC_SYS_XENU) == 0)
+ return RC_SYS_XENU;
+ }
+ if (exists("/proc/xen")) {
+ if (file_regex("/proc/xen/capabilities", "control_d"))
+ return RC_SYS_XEN0;
+ return RC_SYS_XENU;
+ }
+#endif
+
+ return NULL;
+}
+
RC_DEPTREE * _rc_deptree_load(int force, int *regen)
{
int fd;
diff --git a/src/rc/rc.c b/src/rc/rc.c
index 0a970b4e..87c4913f 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -281,8 +281,12 @@ open_shell(void)
struct passwd *pw;
#ifdef __linux__
- char *sys = get_systype();
+ const char *sys = NULL;
+ sys = detect_container();
+ if (!sys)
+ sys = detect_vm();
+
/* VSERVER and OPENVZ systems cannot really drop to shells */
if (sys &&
(strcmp(sys, "VSERVER") == 0 || strcmp(sys, "OPENVZ") == 0))
@@ -466,7 +470,7 @@ static void
do_sysinit()
{
struct utsname uts;
- char *sys = get_systype();
+ const char *sys;
/* exec init-early.sh if it exists
* This should just setup the console to use the correct
@@ -487,6 +491,9 @@ do_sysinit()
uts.machine);
#endif
+ sys = detect_container();
+ if (!sys)
+ sys = detect_vm();
if (sys)
printf(" [%s]", sys);
@@ -502,7 +509,9 @@ do_sysinit()
/* init may have mounted /proc so we can now detect or real
* sys */
- sys = get_systype();
+ sys = detect_container();
+ if (!sys)
+ sys = detect_vm();
if (sys)
setenv("RC_SYS", sys, 1);
}
@@ -823,7 +832,9 @@ int main(int argc, char **argv)
eerrorx("%s: %s", applet, strerror(errno));
/* NOTREACHED */
case 'S':
- systype = get_systype();
+ systype = detect_container();
+ if (!systype)
+ systype = detect_vm();
if (systype)
printf("%s\n", systype);
exit(EXIT_SUCCESS);