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 commits8addd79
and9f6e056
This fixes #75.
This commit is contained in:
parent
55a28f5d25
commit
649f63d882
@ -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:
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
@ -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 *
|
||||
|
@ -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
|
||||
|
164
src/rc/rc-misc.c
164
src/rc/rc-misc.c
@ -27,7 +27,6 @@
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
# include <regex.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -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;
|
||||
|
20
src/rc/rc.c
20
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);
|
||||
|
Loading…
Reference in New Issue
Block a user