From 649f63d882d53533ae8b1c3b28967e772e738c45 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Sun, 17 Jan 2016 21:43:46 -0800 Subject: librc: move system detection code into rc_sys and use it This fixes an issue where librc code was calling code that only existed in the rc binary. This reverts commits 8addd79 and 9f6e056 This fixes #75. --- FEATURE-REMOVAL-SCHEDULE.md | 10 --- src/includes/rc-misc.h | 4 -- src/librc/librc-depend.c | 5 +- src/librc/librc.c | 97 ++++++++++++++++++-------- src/rc/_usage.c | 5 +- src/rc/rc-misc.c | 164 +------------------------------------------- src/rc/rc.c | 20 ++---- 7 files changed, 76 insertions(+), 229 deletions(-) diff --git a/FEATURE-REMOVAL-SCHEDULE.md b/FEATURE-REMOVAL-SCHEDULE.md index 8d07cd46..d66f94fa 100644 --- a/FEATURE-REMOVAL-SCHEDULE.md +++ b/FEATURE-REMOVAL-SCHEDULE.md @@ -76,13 +76,3 @@ Why: The getline() function was standardized in POSIX.1-2008, so it Who: -### rc_sys() - -When: 1.0 - -Why: The OpenRC code now uses two internal functions, detect_container() - and detect_vm() to handle this. rc_sys() is broken because it - doesn't differentiate between containers and vm's. - -Who: - diff --git a/src/includes/rc-misc.h b/src/includes/rc-misc.h index f2449cd7..684ace59 100644 --- a/src/includes/rc-misc.h +++ b/src/includes/rc-misc.h @@ -60,10 +60,6 @@ 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/librc/librc-depend.c b/src/librc/librc-depend.c index 991a871f..d64b2b2a 100644 --- a/src/librc/librc-depend.c +++ b/src/librc/librc-depend.c @@ -740,7 +740,7 @@ rc_deptree_update(void) char *depend, *depends, *service, *type, *nosys, *onosys; size_t i, k, l; bool retval = true; - const char *sys = NULL; + const char *sys = rc_sys(); struct utsname uts; /* Some init scripts need RC_LIBEXECDIR to source stuff @@ -847,9 +847,6 @@ rc_deptree_update(void) /* 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. */ - sys = detect_container(); - if (!sys) - sys = detect_vm(); if (sys) { len = strlen(sys); nosys = xmalloc(len + 2); diff --git a/src/librc/librc.c b/src/librc/librc.c index 64498982..5cf4898f 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -198,13 +198,9 @@ found: #endif -const char * -rc_sys(void) +static const char * +get_systype(void) { -#ifdef PREFIX - return RC_SYS_PREFIX; -#endif - char *systype = rc_conf_value("rc_sys"); if (systype) { char *s = systype; @@ -215,7 +211,22 @@ rc_sys(void) s++; } } + return systype; +} + +static const char * +detect_prefix(const char *systype) +{ +#ifdef PREFIX + return RC_SYS_PREFIX; +#else + return NULL; +#endif +} +static const char * +detect_container(const char *systype) +{ #ifdef __FreeBSD__ if (systype && strcmp(systype, RC_SYS_JAIL) == 0) return RC_SYS_JAIL; @@ -227,25 +238,8 @@ rc_sys(void) return RC_SYS_JAIL; #endif -#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 (strcmp(systype, RC_SYS_UML) == 0) return RC_SYS_UML; if (strcmp(systype, RC_SYS_VSERVER) == 0) @@ -261,11 +255,7 @@ rc_sys(void) if (strcmp(systype, RC_SYS_DOCKER) == 0) return RC_SYS_DOCKER; } - if (exists("/proc/xen")) { - if (file_regex("/proc/xen/capabilities", "control_d")) - return RC_SYS_XEN0; - return RC_SYS_XENU; - } else if (file_regex("/proc/cpuinfo", "UML")) + if (file_regex("/proc/cpuinfo", "UML")) return RC_SYS_UML; else if (file_regex("/proc/self/status", "(s_context|VxID):[[:space:]]*[1-9]")) @@ -287,6 +277,57 @@ rc_sys(void) return NULL; } + +static const char * +detect_vm(const char *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; +} + +const char * +rc_sys(void) +{ + const char *systype; + const char *sys; + + systype = get_systype(); + sys = detect_prefix(systype); + if (!sys) { + sys = detect_container(systype); + if (!sys) { + sys = detect_vm(systype); + } + } + + return sys; +} librc_hidden_def(rc_sys) static const char * diff --git a/src/rc/_usage.c b/src/rc/_usage.c index 9fc3e5d8..0d3d5edd 100644 --- a/src/rc/_usage.c +++ b/src/rc/_usage.c @@ -47,10 +47,7 @@ _noreturn void show_version(void) const char *systype = NULL; printf("%s (OpenRC", applet); - systype = detect_container(); - if (!systype) - systype = detect_vm(); - if (systype) + if ((systype = rc_sys())) printf(" [%s]", systype); printf(") %s", VERSION); #ifdef BRANDING diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c index 2c6c3883..f2967dd1 100644 --- a/src/rc/rc-misc.c +++ b/src/rc/rc-misc.c @@ -27,7 +27,6 @@ #include #include #include -# include #include #include #include @@ -126,7 +125,7 @@ env_config(void) char *np; char *npp; char *tok; - const char *sys = NULL; + const char *sys = rc_sys(); char buffer[PATH_MAX]; /* Ensure our PATH is prefixed with the system locations first @@ -177,10 +176,6 @@ env_config(void) } else setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1); - sys = detect_container(); - if (!sys) - sys = detect_vm(); - if (sys) setenv("RC_SYS", sys, 1); @@ -338,163 +333,6 @@ 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 87c4913f..1aae45ff 100644 --- a/src/rc/rc.c +++ b/src/rc/rc.c @@ -281,12 +281,8 @@ open_shell(void) struct passwd *pw; #ifdef __linux__ - const char *sys = NULL; + const char *sys = rc_sys(); - 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)) @@ -491,10 +487,7 @@ do_sysinit() uts.machine); #endif - sys = detect_container(); - if (!sys) - sys = detect_vm(); - if (sys) + if ((sys = rc_sys())) printf(" [%s]", sys); printf("%s\n\n", ecolor(ECOLOR_NORMAL)); @@ -509,10 +502,7 @@ do_sysinit() /* init may have mounted /proc so we can now detect or real * sys */ - sys = detect_container(); - if (!sys) - sys = detect_vm(); - if (sys) + if ((sys = rc_sys())) setenv("RC_SYS", sys, 1); } @@ -832,9 +822,7 @@ int main(int argc, char **argv) eerrorx("%s: %s", applet, strerror(errno)); /* NOTREACHED */ case 'S': - systype = detect_container(); - if (!systype) - systype = detect_vm(); + systype = rc_sys(); if (systype) printf("%s\n", systype); exit(EXIT_SUCCESS); -- cgit v1.2.3