summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--src/util.c66
2 files changed, 60 insertions, 8 deletions
diff --git a/TODO b/TODO
index a36ca5e0f9..986e06a609 100644
--- a/TODO
+++ b/TODO
@@ -22,6 +22,8 @@ F15:
* 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown
+* capability_bounding_set_drop not used.
+
Features:
* optionally create watched directories in .path units
diff --git a/src/util.c b/src/util.c
index b2baa1ba29..38d630e6a0 100644
--- a/src/util.c
+++ b/src/util.c
@@ -3948,6 +3948,20 @@ int detect_vm(const char **id) {
/* Returns a short identifier for the various VM/container implementations */
int detect_virtualization(const char **id) {
int r;
+ static __thread const char *cached_id = NULL;
+ const char *_id;
+ FILE *f;
+
+ if (cached_id) {
+
+ if (cached_id == (const char*) -1)
+ return 0;
+
+ if (id)
+ *id = cached_id;
+
+ return 1;
+ }
/* Unfortunately most of these operations require root access
* in one way or another */
@@ -3955,24 +3969,60 @@ int detect_virtualization(const char **id) {
return -EPERM;
if ((r = running_in_chroot()) > 0) {
- if (id)
- *id = "chroot";
+ _id = "chroot";
+ r = 1;
+ goto finish;
+ }
- return r;
+ if ((f = fopen("/proc/self/cgroup", "r"))) {
+
+ for (;;) {
+ char line[LINE_MAX], *p;
+
+ if (!fgets(line, sizeof(line), f))
+ break;
+
+ if (!(p = strchr(strstrip(line), ':')))
+ continue;
+
+ if (strncmp(p, ":ns:", 4))
+ continue;
+
+ if (!streq(p, ":ns:/")) {
+ fclose(f);
+
+ r = 1;
+ _id = "ns";
+ goto finish;
+ }
+ }
+
+ fclose(f);
}
/* /proc/vz exists in container and outside of the container,
* /proc/bc only outside of the container. */
if (access("/proc/vz", F_OK) >= 0 &&
access("/proc/bc", F_OK) < 0) {
+ _id = "openvz";
+ r = 1;
+ goto finish;
+ }
- if (id)
- *id = "openvz";
+ r = detect_vm(&_id);
- return 1;
- }
+finish:
+ if (r < 0)
+ return r;
+ else if (r > 0)
+ cached_id = _id;
+ else
+ cached_id = (const char*) -1;
- return detect_vm(id);
+ if (id)
+ *id = _id;
+
+ return r;
}
void execute_directory(const char *directory, DIR *d, char *argv[]) {