diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/mount-util.c | 11 | ||||
-rw-r--r-- | src/basic/util.c | 55 | ||||
-rw-r--r-- | src/basic/util.h | 3 |
3 files changed, 67 insertions, 2 deletions
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index 63dff3dd5c..b91f0f9e0e 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -534,15 +534,22 @@ int repeat_unmount(const char *path, int flags) { } const char* mode_to_inaccessible_node(mode_t mode) { + /* This function maps a node type to the correspondent inaccessible node type. + * Character and block inaccessible devices may not be created (because major=0 and minor=0), + * in such case we map character and block devices to the inaccessible node type socket. */ switch(mode & S_IFMT) { case S_IFREG: return "/run/systemd/inaccessible/reg"; case S_IFDIR: return "/run/systemd/inaccessible/dir"; case S_IFCHR: - return "/run/systemd/inaccessible/chr"; + if (access("/run/systemd/inaccessible/chr", F_OK) == 0) + return "/run/systemd/inaccessible/chr"; + return "/run/systemd/inaccessible/sock"; case S_IFBLK: - return "/run/systemd/inaccessible/blk"; + if (access("/run/systemd/inaccessible/blk", F_OK) == 0) + return "/run/systemd/inaccessible/blk"; + return "/run/systemd/inaccessible/sock"; case S_IFIFO: return "/run/systemd/inaccessible/fifo"; case S_IFSOCK: diff --git a/src/basic/util.c b/src/basic/util.c index 41e79315ae..9d66d28eb7 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -791,6 +791,61 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) { return r; } +uint64_t system_tasks_max(void) { + +#if SIZEOF_PID_T == 4 +#define TASKS_MAX ((uint64_t) (INT32_MAX-1)) +#elif SIZEOF_PID_T == 2 +#define TASKS_MAX ((uint64_t) (INT16_MAX-1)) +#else +#error "Unknown pid_t size" +#endif + + _cleanup_free_ char *value = NULL, *root = NULL; + uint64_t a = TASKS_MAX, b = TASKS_MAX; + + /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this + * limit: + * + * a) the maximum value for the pid_t type + * b) the cgroups pids_max attribute for the system + * c) the kernel's configure maximum PID value + * + * And then pick the smallest of the three */ + + if (read_one_line_file("/proc/sys/kernel/pid_max", &value) >= 0) + (void) safe_atou64(value, &a); + + if (cg_get_root_path(&root) >= 0) { + value = mfree(value); + + if (cg_get_attribute("pids", root, "pids.max", &value) >= 0) + (void) safe_atou64(value, &b); + } + + return MIN3(TASKS_MAX, + a <= 0 ? TASKS_MAX : a, + b <= 0 ? TASKS_MAX : b); +} + +uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) { + uint64_t t, m; + + assert(max > 0); + + /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages + * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */ + + t = system_tasks_max(); + assert(t > 0); + + m = t * v; + if (m / t != v) /* overflow? */ + return UINT64_MAX; + + return m / max; +} + int update_reboot_parameter_and_warn(const char *param) { int r; diff --git a/src/basic/util.h b/src/basic/util.h index 94b8091906..44497dcd78 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -184,6 +184,9 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int uint64_t physical_memory(void); uint64_t physical_memory_scale(uint64_t v, uint64_t max); +uint64_t system_tasks_max(void); +uint64_t system_tasks_max_scale(uint64_t v, uint64_t max); + int update_reboot_parameter_and_warn(const char *param); int version(void); |