chiark / gitweb /
util: detect CLONE_NEWPID namespaces, and cache results
authorLennart Poettering <lennart@poettering.net>
Mon, 14 Mar 2011 01:36:00 +0000 (02:36 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 14 Mar 2011 02:12:25 +0000 (03:12 +0100)
TODO
src/util.c

diff --git a/TODO b/TODO
index a36ca5e..986e06a 100644 (file)
--- 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
index b2baa1b..38d630e 100644 (file)
@@ -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[]) {