1 |
commit: 8addd7913a743b75ef3854ab4a96fea81cc5245d |
2 |
Author: William Hubbs <w.d.hubbs <AT> gmail <DOT> com> |
3 |
AuthorDate: Sat Dec 5 00:02:43 2015 +0000 |
4 |
Commit: William Hubbs <williamh <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Dec 8 18:05:59 2015 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=8addd791 |
7 |
|
8 |
Create detect_container() and detect_vm() functions |
9 |
|
10 |
These functions replace rc_sys so that we can detect containers and vms |
11 |
separately. |
12 |
|
13 |
Also, we copy file_regex() to rc-misc.c and open it to all operating |
14 |
systems. |
15 |
|
16 |
src/includes/rc-misc.h | 4 ++ |
17 |
src/rc/rc-misc.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++- |
18 |
2 files changed, 162 insertions(+), 1 deletion(-) |
19 |
|
20 |
diff --git a/src/includes/rc-misc.h b/src/includes/rc-misc.h |
21 |
index 3cce8d0..e0565b6 100644 |
22 |
--- a/src/includes/rc-misc.h |
23 |
+++ b/src/includes/rc-misc.h |
24 |
@@ -87,4 +87,8 @@ int is_writable(const char *); |
25 |
#define service_stop(service) exec_service(service, "stop"); |
26 |
|
27 |
int parse_mode(mode_t *, char *); |
28 |
+const char *detect_prefix(void); |
29 |
+const char *get_systype(void); |
30 |
+const char *detect_container(void); |
31 |
+const char *detect_vm(void); |
32 |
#endif |
33 |
|
34 |
diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c |
35 |
index 27d9f81..1e2af0a 100644 |
36 |
--- a/src/rc/rc-misc.c |
37 |
+++ b/src/rc/rc-misc.c |
38 |
@@ -34,12 +34,12 @@ |
39 |
|
40 |
#ifdef __linux__ |
41 |
# include <sys/sysinfo.h> |
42 |
-# include <regex.h> |
43 |
#endif |
44 |
|
45 |
#include <ctype.h> |
46 |
#include <fcntl.h> |
47 |
#include <limits.h> |
48 |
+# include <regex.h> |
49 |
#include <signal.h> |
50 |
#include <stdio.h> |
51 |
#include <stdlib.h> |
52 |
@@ -346,3 +346,160 @@ is_writable(const char *path) |
53 |
|
54 |
return 0; |
55 |
} |
56 |
+ |
57 |
+static bool file_regex(const char *file, const char *regex) |
58 |
+{ |
59 |
+ FILE *fp; |
60 |
+ char *line = NULL; |
61 |
+ size_t len = 0; |
62 |
+ regex_t re; |
63 |
+ bool retval = true; |
64 |
+ int result; |
65 |
+ |
66 |
+ if (!(fp = fopen(file, "r"))) |
67 |
+ return false; |
68 |
+ |
69 |
+ if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) { |
70 |
+ fclose(fp); |
71 |
+ line = xmalloc(sizeof(char) * BUFSIZ); |
72 |
+ regerror(result, &re, line, BUFSIZ); |
73 |
+ fprintf(stderr, "file_regex: %s", line); |
74 |
+ free(line); |
75 |
+ return false; |
76 |
+ } |
77 |
+ |
78 |
+ while ((rc_getline(&line, &len, fp))) { |
79 |
+ char *str = line; |
80 |
+ /* some /proc files have \0 separated content so we have to |
81 |
+ loop through the 'line' */ |
82 |
+ do { |
83 |
+ if (regexec(&re, str, 0, NULL, 0) == 0) |
84 |
+ goto found; |
85 |
+ str += strlen(str) + 1; |
86 |
+ /* len is the size of allocated buffer and we don't |
87 |
+ want call regexec BUFSIZE times. find next str */ |
88 |
+ while (str < line + len && *str == '\0') |
89 |
+ str++; |
90 |
+ } while (str < line + len); |
91 |
+ } |
92 |
+ retval = false; |
93 |
+found: |
94 |
+ fclose(fp); |
95 |
+ free(line); |
96 |
+ regfree(&re); |
97 |
+ |
98 |
+ return retval; |
99 |
+} |
100 |
+ |
101 |
+const char *detect_prefix(void) |
102 |
+{ |
103 |
+#ifdef PREFIX |
104 |
+ return RC_SYS_PREFIX; |
105 |
+#else |
106 |
+ return NULL; |
107 |
+#endif |
108 |
+} |
109 |
+ |
110 |
+const char *get_systype(void) |
111 |
+{ |
112 |
+ char *systype = rc_conf_value("rc_sys"); |
113 |
+ if (systype) { |
114 |
+ char *s = systype; |
115 |
+ /* Convert to uppercase */ |
116 |
+ while (s && *s) { |
117 |
+ if (islower((unsigned char) *s)) |
118 |
+ *s = toupper((unsigned char) *s); |
119 |
+ s++; |
120 |
+ } |
121 |
+ } |
122 |
+ return systype; |
123 |
+} |
124 |
+ |
125 |
+const char *detect_container(void) |
126 |
+{ |
127 |
+ char *systype = get_systype(); |
128 |
+ |
129 |
+#ifdef __FreeBSD__ |
130 |
+ if (systype && strcmp(systype, RC_SYS_JAIL) == 0) |
131 |
+ return RC_SYS_JAIL; |
132 |
+ int jailed = 0; |
133 |
+ size_t len = sizeof(jailed); |
134 |
+ |
135 |
+ if (sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0) == 0) |
136 |
+ if (jailed == 1) |
137 |
+ return RC_SYS_JAIL; |
138 |
+#endif |
139 |
+ |
140 |
+#ifdef __linux__ |
141 |
+ if (systype) { |
142 |
+ if (strcmp(systype, RC_SYS_UML) == 0) |
143 |
+ return RC_SYS_UML; |
144 |
+ if (strcmp(systype, RC_SYS_VSERVER) == 0) |
145 |
+ return RC_SYS_VSERVER; |
146 |
+ if (strcmp(systype, RC_SYS_OPENVZ) == 0) |
147 |
+ return RC_SYS_OPENVZ; |
148 |
+ if (strcmp(systype, RC_SYS_LXC) == 0) |
149 |
+ return RC_SYS_LXC; |
150 |
+ if (strcmp(systype, RC_SYS_RKT) == 0) |
151 |
+ return RC_SYS_RKT; |
152 |
+ if (strcmp(systype, RC_SYS_SYSTEMD_NSPAWN) == 0) |
153 |
+ return RC_SYS_SYSTEMD_NSPAWN; |
154 |
+ if (strcmp(systype, RC_SYS_DOCKER) == 0) |
155 |
+ return RC_SYS_DOCKER; |
156 |
+ } |
157 |
+ if (file_regex("/proc/cpuinfo", "UML")) |
158 |
+ return RC_SYS_UML; |
159 |
+ else if (file_regex("/proc/self/status", |
160 |
+ "(s_context|VxID):[[:space:]]*[1-9]")) |
161 |
+ return RC_SYS_VSERVER; |
162 |
+ else if (exists("/proc/vz/veinfo") && !exists("/proc/vz/version")) |
163 |
+ return RC_SYS_OPENVZ; |
164 |
+ else if (file_regex("/proc/self/status", |
165 |
+ "envID:[[:space:]]*[1-9]")) |
166 |
+ return RC_SYS_OPENVZ; /* old test */ |
167 |
+ else if (file_regex("/proc/1/environ", "container=lxc")) |
168 |
+ return RC_SYS_LXC; |
169 |
+ else if (file_regex("/proc/1/environ", "container=rkt")) |
170 |
+ return RC_SYS_RKT; |
171 |
+ else if (file_regex("/proc/1/environ", "container=systemd-nspawn")) |
172 |
+ return RC_SYS_SYSTEMD_NSPAWN; |
173 |
+ else if (file_regex("/proc/1/environ", "container=docker")) |
174 |
+ return RC_SYS_DOCKER; |
175 |
+#endif |
176 |
+ |
177 |
+ return NULL; |
178 |
+} |
179 |
+ |
180 |
+const char *detect_vm(void) |
181 |
+{ |
182 |
+ char *systype = get_systype(); |
183 |
+ |
184 |
+#ifdef __NetBSD__ |
185 |
+ if (systype) { |
186 |
+ if(strcmp(systype, RC_SYS_XEN0) == 0) |
187 |
+ return RC_SYS_XEN0; |
188 |
+ if (strcmp(systype, RC_SYS_XENU) == 0) |
189 |
+ return RC_SYS_XENU; |
190 |
+ } |
191 |
+ if (exists("/kern/xen/privcmd")) |
192 |
+ return RC_SYS_XEN0; |
193 |
+ if (exists("/kern/xen")) |
194 |
+ return RC_SYS_XENU; |
195 |
+#endif |
196 |
+ |
197 |
+#ifdef __linux__ |
198 |
+ if (systype) { |
199 |
+ if (strcmp(systype, RC_SYS_XEN0) == 0) |
200 |
+ return RC_SYS_XEN0; |
201 |
+ if (strcmp(systype, RC_SYS_XENU) == 0) |
202 |
+ return RC_SYS_XENU; |
203 |
+ } |
204 |
+ if (exists("/proc/xen")) { |
205 |
+ if (file_regex("/proc/xen/capabilities", "control_d")) |
206 |
+ return RC_SYS_XEN0; |
207 |
+ return RC_SYS_XENU; |
208 |
+ } |
209 |
+#endif |
210 |
+ |
211 |
+ return NULL; |
212 |
+} |