X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Futil.c;h=fada69cf1a981893f85998ac2da465865a2d0074;hp=b2baa1ba29aacb067bf02ad64d3d14badc87ea94;hb=871c44a747a8bf4465cbfda445216e9ac66d4a40;hpb=0a27cf3f32403f48059396cb43ad25d0a12ef64b diff --git a/src/util.c b/src/util.c index b2baa1ba2..fada69cf1 100644 --- a/src/util.c +++ b/src/util.c @@ -61,6 +61,20 @@ #include "exit-status.h" #include "hashmap.h" +size_t page_size(void) { + static __thread size_t pgsz = 0; + long r; + + if (pgsz) + return pgsz; + + assert_se((r = sysconf(_SC_PAGESIZE)) > 0); + + pgsz = (size_t) r; + + return pgsz; +} + bool streq_ptr(const char *a, const char *b) { /* Like streq(), but tries to make sense of NULL pointers */ @@ -3524,7 +3538,7 @@ int touch(const char *path) { assert(path); - if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666)) < 0) + if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0) return -errno; close_nointr_nofail(fd); @@ -3945,20 +3959,21 @@ int detect_vm(const char **id) { return 0; } -/* Returns a short identifier for the various VM/container implementations */ -int detect_virtualization(const char **id) { - int r; +int detect_container(const char **id) { + FILE *f; - /* Unfortunately most of these operations require root access + /* Unfortunately many of these operations require root access * in one way or another */ + if (geteuid() != 0) return -EPERM; - if ((r = running_in_chroot()) > 0) { + if (running_in_chroot() > 0) { + if (id) *id = "chroot"; - return r; + return 1; } /* /proc/vz exists in container and outside of the container, @@ -3972,7 +3987,68 @@ int detect_virtualization(const char **id) { return 1; } - return detect_vm(id); + 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); + + if (id) + *id = "pidns"; + + return 1; + } + } + + fclose(f); + } + + return 0; +} + +/* Returns a short identifier for the various VM/container implementations */ +int detect_virtualization(const char **id) { + static __thread const char *cached_id = NULL; + const char *_id; + int r; + + if (cached_id) { + + if (cached_id == (const char*) -1) + return 0; + + if (id) + *id = cached_id; + + return 1; + } + + if ((r = detect_container(&_id)) != 0) + goto finish; + + r = detect_vm(&_id); + +finish: + if (r > 0) { + cached_id = _id; + + if (id) + *id = _id; + } else if (r == 0) + cached_id = (const char*) -1; + + return r; } void execute_directory(const char *directory, DIR *d, char *argv[]) {