X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Futil.c;h=1febd073d2eeef37f9e7ecf99179ae711a7acbdd;hp=ee6217d64ca8f494bdaf156b2a0123f2b46fd7ac;hb=28cf382a0afd10d0e2a71d152f0df4909e90d159;hpb=46824d0e6b2aae8f503464368d02c1da992f56f1 diff --git a/src/util.c b/src/util.c index ee6217d64..1febd073d 100644 --- a/src/util.c +++ b/src/util.c @@ -3524,7 +3524,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); @@ -3616,7 +3616,7 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid) { if (status.si_code == CLD_EXITED) { if (status.si_status != 0) { log_warning("%s failed with error code %i.", name, status.si_status); - return -EPROTO; + return status.si_status; } log_debug("%s succeeded.", name); @@ -3945,20 +3945,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 +3973,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[]) {