diff options
Diffstat (limited to 'src/rc')
-rw-r--r-- | src/rc/_usage.c | 5 | ||||
-rw-r--r-- | src/rc/rc-misc.c | 333 | ||||
-rw-r--r-- | src/rc/rc.c | 19 |
3 files changed, 182 insertions, 175 deletions
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); |