commit:     8addd7913a743b75ef3854ab4a96fea81cc5245d
Author:     William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Sat Dec  5 00:02:43 2015 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Tue Dec  8 18:05:59 2015 +0000
URL:        https://gitweb.gentoo.org/proj/openrc.git/commit/?id=8addd791

Create detect_container() and detect_vm() functions

These functions replace rc_sys so that we can detect containers and vms
separately.

Also, we copy file_regex() to rc-misc.c and open it to all operating
systems.

 src/includes/rc-misc.h |   4 ++
 src/rc/rc-misc.c       | 159 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/src/includes/rc-misc.h b/src/includes/rc-misc.h
index 3cce8d0..e0565b6 100644
--- a/src/includes/rc-misc.h
+++ b/src/includes/rc-misc.h
@@ -87,4 +87,8 @@ 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);
 #endif

diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c
index 27d9f81..1e2af0a 100644
--- a/src/rc/rc-misc.c
+++ b/src/rc/rc-misc.c
@@ -34,12 +34,12 @@
 
 #ifdef __linux__
 #  include <sys/sysinfo.h>
-#  include <regex.h>
 #endif
 
 #include <ctype.h>
 #include <fcntl.h>
 #include <limits.h>
+#  include <regex.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -346,3 +346,160 @@ 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)
+{
+       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)
+{
+       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;
+}

Reply via email to