summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/cgroup-util.c8
-rw-r--r--src/basic/cgroup-util.h2
-rw-r--r--src/basic/copy.c16
-rw-r--r--src/basic/copy.h3
-rw-r--r--src/basic/util.c89
-rw-r--r--src/basic/util.h4
-rw-r--r--src/cgtop/cgtop.c109
-rw-r--r--src/core/automount.c6
-rw-r--r--src/core/cgroup.c49
-rw-r--r--src/core/cgroup.h4
-rw-r--r--src/core/dbus-cgroup.c41
-rw-r--r--src/core/dbus-unit.c25
-rw-r--r--src/core/dbus.c9
-rw-r--r--src/core/device.c3
-rw-r--r--src/core/execute.c38
-rw-r--r--src/core/load-fragment-gperf.gperf.m42
-rw-r--r--src/core/load-fragment.c73
-rw-r--r--src/core/load-fragment.h1
-rw-r--r--src/core/main.c6
-rw-r--r--src/core/manager.h1
-rw-r--r--src/core/swap.c3
-rw-r--r--src/core/unit.c7
-rw-r--r--src/cryptsetup/cryptsetup-generator.c2
-rw-r--r--src/import/pull-raw.c2
-rw-r--r--src/journal/compress.c31
-rw-r--r--src/journal/compress.h10
-rw-r--r--src/journal/coredump-vacuum.c20
-rw-r--r--src/journal/coredump-vacuum.h3
-rw-r--r--src/journal/coredump.c34
-rw-r--r--src/journal/journal-file.c2
-rw-r--r--src/journal/journalctl.c2
-rw-r--r--src/journal/journald-gperf.gperf12
-rw-r--r--src/journal/test-compress.c4
-rw-r--r--src/journal/test-coredump-vacuum.c2
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c3
-rw-r--r--src/libsystemd/sd-bus/busctl.c8
-rw-r--r--src/login/logind-user.c10
-rw-r--r--src/machine/machine-dbus.c2
-rw-r--r--src/machine/machinectl.c6
-rw-r--r--src/nspawn/nspawn.c2
-rw-r--r--src/resolve/resolved-dns-zone.c7
-rw-r--r--src/resolve/resolved-link.c3
-rw-r--r--src/shared/bus-util.c37
-rw-r--r--src/shared/conf-parser.c28
-rw-r--r--src/shared/conf-parser.h2
-rw-r--r--src/shared/machine-image.c119
-rw-r--r--src/shared/pager.c2
-rw-r--r--src/shared/path-lookup.c12
-rw-r--r--src/systemctl/systemctl.c96
-rw-r--r--src/sysusers/sysusers.c2
-rw-r--r--src/test/test-copy.c2
-rw-r--r--src/test/test-util.c12
52 files changed, 646 insertions, 330 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 94a25585b2..6099dc8721 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -2018,9 +2018,10 @@ int cg_mask_supported(CGroupMask *ret) {
mask |= CGROUP_CONTROLLER_TO_MASK(v);
}
- /* Currently, we only support the memory controller in
- * the unified hierarchy, mask everything else off. */
- mask &= CGROUP_MASK_MEMORY;
+ /* Currently, we only support the memory and pids
+ * controller in the unified hierarchy, mask
+ * everything else off. */
+ mask &= CGROUP_MASK_MEMORY | CGROUP_MASK_PIDS;
} else {
CGroupController c;
@@ -2212,6 +2213,7 @@ static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
[CGROUP_CONTROLLER_BLKIO] = "blkio",
[CGROUP_CONTROLLER_MEMORY] = "memory",
[CGROUP_CONTROLLER_DEVICES] = "devices",
+ [CGROUP_CONTROLLER_PIDS] = "pids",
};
DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 16d439fd9d..7e1b4f9c72 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -35,6 +35,7 @@ typedef enum CGroupController {
CGROUP_CONTROLLER_BLKIO,
CGROUP_CONTROLLER_MEMORY,
CGROUP_CONTROLLER_DEVICES,
+ CGROUP_CONTROLLER_PIDS,
_CGROUP_CONTROLLER_MAX,
_CGROUP_CONTROLLER_INVALID = -1,
} CGroupController;
@@ -48,6 +49,7 @@ typedef enum CGroupMask {
CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO),
CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY),
CGROUP_MASK_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_DEVICES),
+ CGROUP_MASK_PIDS = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_PIDS),
_CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1
} CGroupMask;
diff --git a/src/basic/copy.c b/src/basic/copy.c
index cc5faa80a1..b8cbe644d4 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -29,7 +29,7 @@
#define COPY_BUFFER_SIZE (16*1024)
-int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
+int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
bool try_sendfile = true, try_splice = true;
int r;
@@ -37,7 +37,7 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
assert(fdt >= 0);
/* Try btrfs reflinks first. */
- if (try_reflink && max_bytes == (off_t) -1) {
+ if (try_reflink && max_bytes == (uint64_t) -1) {
r = btrfs_reflink(fdf, fdt);
if (r >= 0)
return r;
@@ -47,12 +47,12 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
size_t m = COPY_BUFFER_SIZE;
ssize_t n;
- if (max_bytes != (off_t) -1) {
+ if (max_bytes != (uint64_t) -1) {
if (max_bytes <= 0)
return -EFBIG;
- if ((off_t) m > max_bytes)
+ if ((uint64_t) m > max_bytes)
m = (size_t) max_bytes;
}
@@ -105,8 +105,8 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
}
next:
- if (max_bytes != (off_t) -1) {
- assert(max_bytes >= n);
+ if (max_bytes != (uint64_t) -1) {
+ assert(max_bytes >= (uint64_t) n);
max_bytes -= n;
}
}
@@ -152,7 +152,7 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
if (fdt < 0)
return -errno;
- r = copy_bytes(fdf, fdt, (off_t) -1, true);
+ r = copy_bytes(fdf, fdt, (uint64_t) -1, true);
if (r < 0) {
unlinkat(dt, to, 0);
return r;
@@ -371,7 +371,7 @@ int copy_file_fd(const char *from, int fdt, bool try_reflink) {
if (fdf < 0)
return -errno;
- r = copy_bytes(fdf, fdt, (off_t) -1, try_reflink);
+ r = copy_bytes(fdf, fdt, (uint64_t) -1, try_reflink);
(void) copy_times(fdf, fdt);
(void) copy_xattr(fdf, fdt);
diff --git a/src/basic/copy.h b/src/basic/copy.h
index 8de0cfba32..ba0890b442 100644
--- a/src/basic/copy.h
+++ b/src/basic/copy.h
@@ -21,6 +21,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <inttypes.h>
#include <stdbool.h>
#include <sys/types.h>
@@ -30,6 +31,6 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
int copy_tree(const char *from, const char *to, bool merge);
int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
int copy_directory_fd(int dirfd, const char *to, bool merge);
-int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink);
+int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink);
int copy_times(int fdf, int fdt);
int copy_xattr(int fdf, int fdt);
diff --git a/src/basic/util.c b/src/basic/util.c
index f7b2edf88c..e3b2af8e02 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -2214,7 +2214,7 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
return 0;
}
-int parse_size(const char *t, off_t base, off_t *size) {
+int parse_size(const char *t, uint64_t base, uint64_t *size) {
/* Soo, sometimes we want to parse IEC binary suffixes, and
* sometimes SI decimal suffixes. This function can parse
@@ -2242,8 +2242,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
{ "G", 1024ULL*1024ULL*1024ULL },
{ "M", 1024ULL*1024ULL },
{ "K", 1024ULL },
- { "B", 1 },
- { "", 1 },
+ { "B", 1ULL },
+ { "", 1ULL },
};
static const struct table si[] = {
@@ -2253,8 +2253,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
{ "G", 1000ULL*1000ULL*1000ULL },
{ "M", 1000ULL*1000ULL },
{ "K", 1000ULL },
- { "B", 1 },
- { "", 1 },
+ { "B", 1ULL },
+ { "", 1ULL },
};
const struct table *table;
@@ -2276,33 +2276,32 @@ int parse_size(const char *t, off_t base, off_t *size) {
p = t;
do {
- long long l;
- unsigned long long l2;
+ unsigned long long l, tmp;
double frac = 0;
char *e;
unsigned i;
- errno = 0;
- l = strtoll(p, &e, 10);
+ p += strspn(p, WHITESPACE);
+ if (*p == '-')
+ return -ERANGE;
+ errno = 0;
+ l = strtoull(p, &e, 10);
if (errno > 0)
return -errno;
-
- if (l < 0)
- return -ERANGE;
-
if (e == p)
return -EINVAL;
if (*e == '.') {
e++;
+
+ /* strtoull() itself would accept space/+/- */
if (*e >= '0' && *e <= '9') {
+ unsigned long long l2;
char *e2;
- /* strotoull itself would accept space/+/- */
l2 = strtoull(e, &e2, 10);
-
- if (errno == ERANGE)
+ if (errno > 0)
return -errno;
/* Ignore failure. E.g. 10.M is valid */
@@ -2315,27 +2314,27 @@ int parse_size(const char *t, off_t base, off_t *size) {
e += strspn(e, WHITESPACE);
for (i = start_pos; i < n_entries; i++)
- if (startswith(e, table[i].suffix)) {
- unsigned long long tmp;
- if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
- return -ERANGE;
- tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
- if (tmp > ULLONG_MAX - r)
- return -ERANGE;
-
- r += tmp;
- if ((unsigned long long) (off_t) r != r)
- return -ERANGE;
-
- p = e + strlen(table[i].suffix);
-
- start_pos = i + 1;
+ if (startswith(e, table[i].suffix))
break;
- }
if (i >= n_entries)
return -EINVAL;
+ if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
+ return -ERANGE;
+
+ tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
+ if (tmp > ULLONG_MAX - r)
+ return -ERANGE;
+
+ r += tmp;
+ if ((unsigned long long) (uint64_t) r != r)
+ return -ERANGE;
+
+ p = e + strlen(table[i].suffix);
+
+ start_pos = i + 1;
+
} while (*p);
*size = r;
@@ -3785,38 +3784,38 @@ int prot_from_flags(int flags) {
}
}
-char *format_bytes(char *buf, size_t l, off_t t) {
+char *format_bytes(char *buf, size_t l, uint64_t t) {
unsigned i;
static const struct {
const char *suffix;
- off_t factor;
+ uint64_t factor;
} table[] = {
- { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
- { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
- { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
- { "G", 1024ULL*1024ULL*1024ULL },
- { "M", 1024ULL*1024ULL },
- { "K", 1024ULL },
+ { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+ { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+ { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+ { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+ { "M", UINT64_C(1024)*UINT64_C(1024) },
+ { "K", UINT64_C(1024) },
};
- if (t == (off_t) -1)
+ if (t == (uint64_t) -1)
return NULL;
for (i = 0; i < ELEMENTSOF(table); i++) {
if (t >= table[i].factor) {
snprintf(buf, l,
- "%llu.%llu%s",
- (unsigned long long) (t / table[i].factor),
- (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
+ "%" PRIu64 ".%" PRIu64 "%s",
+ t / table[i].factor,
+ ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
table[i].suffix);
goto finish;
}
}
- snprintf(buf, l, "%lluB", (unsigned long long) t);
+ snprintf(buf, l, "%" PRIu64 "B", t);
finish:
buf[l-1] = 0;
diff --git a/src/basic/util.h b/src/basic/util.h
index 5fa44b5cf3..c7dff9a86d 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -152,7 +152,7 @@ void close_many(const int fds[], unsigned n_fd);
int fclose_nointr(FILE *f);
FILE* safe_fclose(FILE *f);
-int parse_size(const char *t, off_t base, off_t *size);
+int parse_size(const char *t, uint64_t base, uint64_t *size);
int parse_boolean(const char *v) _pure_;
int parse_pid(const char *s, pid_t* ret_pid);
@@ -478,7 +478,7 @@ bool kexec_loaded(void);
int prot_from_flags(int flags) _const_;
-char *format_bytes(char *buf, size_t l, off_t t);
+char *format_bytes(char *buf, size_t l, uint64_t t);
int fd_wait_for_event(int fd, int event, usec_t timeout);
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index 1c94bea31a..4786a155da 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -45,7 +45,7 @@ typedef struct Group {
bool memory_valid:1;
bool io_valid:1;
- unsigned n_tasks;
+ uint64_t n_tasks;
unsigned cpu_iteration;
nsec_t cpu_usage;
@@ -65,7 +65,12 @@ static unsigned arg_iterations = (unsigned) -1;
static bool arg_batch = false;
static bool arg_raw = false;
static usec_t arg_delay = 1*USEC_PER_SEC;
-static bool arg_kernel_threads = false;
+
+enum {
+ COUNT_PIDS,
+ COUNT_USERSPACE_PROCESSES,
+ COUNT_ALL_PROCESSES,
+} arg_count = COUNT_PIDS;
static bool arg_recursive = true;
static enum {
@@ -73,7 +78,7 @@ static enum {
ORDER_TASKS,
ORDER_CPU,
ORDER_MEMORY,
- ORDER_IO
+ ORDER_IO,
} arg_order = ORDER_CPU;
static enum {
@@ -100,7 +105,7 @@ static void group_hashmap_free(Hashmap *h) {
hashmap_free(h);
}
-static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, off_t t) {
+static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, uint64_t t) {
if (!is_valid)
return "-";
if (arg_raw) {
@@ -153,7 +158,7 @@ static int process(
}
}
- if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES)) {
_cleanup_fclose_ FILE *f = NULL;
pid_t pid;
@@ -166,7 +171,7 @@ static int process(
g->n_tasks = 0;
while (cg_read_pid(f, &pid) > 0) {
- if (!arg_kernel_threads && is_kernel_thread(pid) > 0)
+ if (arg_count == COUNT_USERSPACE_PROCESSES && is_kernel_thread(pid) > 0)
continue;
g->n_tasks++;
@@ -175,6 +180,26 @@ static int process(
if (g->n_tasks > 0)
g->n_tasks_valid = true;
+ } else if (streq(controller, "pids") && arg_count == COUNT_PIDS) {
+ _cleanup_free_ char *p = NULL, *v = NULL;
+
+ r = cg_get_path(controller, path, "pids.current", &p);
+ if (r < 0)
+ return r;
+
+ r = read_one_line_file(p, &v);
+ if (r == -ENOENT)
+ return 0;
+ if (r < 0)
+ return r;
+
+ r = safe_atou64(v, &g->n_tasks);
+ if (r < 0)
+ return r;
+
+ if (g->n_tasks > 0)
+ g->n_tasks_valid = true;
+
} else if (streq(controller, "cpuacct") && cg_unified() <= 0) {
_cleanup_free_ char *p = NULL, *v = NULL;
uint64_t new_usage;
@@ -371,6 +396,7 @@ static int refresh_one(
return r;
if (arg_recursive &&
+ IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES) &&
child &&
child->n_tasks_valid &&
streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
@@ -409,6 +435,9 @@ static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration)
r = refresh_one("blkio", root, a, b, iteration, 0, NULL);
if (r < 0)
return r;
+ r = refresh_one("pids", root, a, b, iteration, 0, NULL);
+ if (r < 0)
+ return r;
return 0;
}
@@ -549,7 +578,7 @@ static void display(Hashmap *a) {
printf("%s%-*s%s %s%7s%s %s%s%s %s%8s%s %s%8s%s %s%8s%s\n\n",
arg_order == ORDER_PATH ? ON : "", path_columns, "Control Group",
arg_order == ORDER_PATH ? OFF : "",
- arg_order == ORDER_TASKS ? ON : "", "Tasks",
+ arg_order == ORDER_TASKS ? ON : "", arg_count == COUNT_PIDS ? "Tasks" : arg_count == COUNT_USERSPACE_PROCESSES ? "Procs" : "Proc+",
arg_order == ORDER_TASKS ? OFF : "",
arg_order == ORDER_CPU ? ON : "", buffer,
arg_order == ORDER_CPU ? OFF : "",
@@ -576,7 +605,7 @@ static void display(Hashmap *a) {
printf("%-*s", path_columns, ellipsized ?: path);
if (g->n_tasks_valid)
- printf(" %7u", g->n_tasks);
+ printf(" %7" PRIu64, g->n_tasks);
else
fputs(" -", stdout);
@@ -602,15 +631,16 @@ static void help(void) {
" -h --help Show this help\n"
" --version Show package version\n"
" -p --order=path Order by path\n"
- " -t --order=tasks Order by number of tasks\n"
+ " -t --order=tasks Order by number of tasks/processes\n"
" -c --order=cpu Order by CPU load (default)\n"
" -m --order=memory Order by memory load\n"
" -i --order=io Order by IO load\n"
" -r --raw Provide raw (not human-readable) numbers\n"
" --cpu=percentage Show CPU usage as percentage (default)\n"
" --cpu=time Show CPU usage as time\n"
- " -k Include kernel threads in task count\n"
- " --recursive=BOOL Sum up task count recursively\n"
+ " -P Count userspace processes instead of tasks (excl. kernel)\n"
+ " -k Count all processes instead of tasks (incl. kernel)\n"
+ " --recursive=BOOL Sum up process count recursively\n"
" -d --delay=DELAY Delay between updates\n"
" -n --iterations=N Run for N iterations before exiting\n"
" -b --batch Run in batch mode, accepting no input\n"
@@ -642,12 +672,13 @@ static int parse_argv(int argc, char *argv[]) {
{}
};
+ bool recursive_unset = false;
int c, r;
assert(argc >= 1);
assert(argv);
- while ((c = getopt_long(argc, argv, "hptcmin:brd:k", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "hptcmin:brd:kP", options, NULL)) >= 0)
switch (c) {
@@ -748,7 +779,11 @@ static int parse_argv(int argc, char *argv[]) {
break;
case 'k':
- arg_kernel_threads = true;
+ arg_count = COUNT_ALL_PROCESSES;
+ break;
+
+ case 'P':
+ arg_count = COUNT_USERSPACE_PROCESSES;
break;
case ARG_RECURSIVE:
@@ -759,6 +794,7 @@ static int parse_argv(int argc, char *argv[]) {
}
arg_recursive = r;
+ recursive_unset = r == 0;
break;
case '?':
@@ -773,9 +809,23 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
+ if (recursive_unset && arg_count == COUNT_PIDS) {
+ log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k.");
+ return -EINVAL;
+ }
+
return 1;
}
+static const char* counting_what(void) {
+ if (arg_count == COUNT_PIDS)
+ return "tasks";
+ else if (arg_count == COUNT_ALL_PROCESSES)
+ return "all processes (incl. kernel)";
+ else
+ return "userspace processes (excl. kernel)";
+}
+
int main(int argc, char *argv[]) {
int r;
Hashmap *a = NULL, *b = NULL;
@@ -783,10 +833,19 @@ int main(int argc, char *argv[]) {
usec_t last_refresh = 0;
bool quit = false, immediate_refresh = false;
_cleanup_free_ char *root = NULL;
+ CGroupMask mask;
log_parse_environment();
log_open();
+ r = cg_mask_supported(&mask);
+ if (r < 0) {
+ log_error_errno(r, "Failed to determine supported controllers: %m");
+ goto finish;
+ }
+
+ arg_count = (mask & CGROUP_MASK_PIDS) ? COUNT_PIDS : COUNT_USERSPACE_PROCESSES;
+
r = parse_argv(argc, argv);
if (r <= 0)
goto finish;
@@ -899,15 +958,26 @@ int main(int argc, char *argv[]) {
break;
case 'k':
- arg_kernel_threads = !arg_kernel_threads;
- fprintf(stdout, "\nCounting kernel threads: %s.", yes_no(arg_kernel_threads));
+ arg_count = arg_count != COUNT_ALL_PROCESSES ? COUNT_ALL_PROCESSES : COUNT_PIDS;
+ fprintf(stdout, "\nCounting: %s.", counting_what());
+ fflush(stdout);
+ sleep(1);
+ break;
+
+ case 'P':
+ arg_count = arg_count != COUNT_USERSPACE_PROCESSES ? COUNT_USERSPACE_PROCESSES : COUNT_PIDS;
+ fprintf(stdout, "\nCounting: %s.", counting_what());
fflush(stdout);
sleep(1);
break;
case 'r':
- arg_recursive = !arg_recursive;
- fprintf(stdout, "\nRecursive task counting: %s", yes_no(arg_recursive));
+ if (arg_count == COUNT_PIDS)
+ fprintf(stdout, "\n\aCannot toggle recursive counting, not available in task counting mode.");
+ else {
+ arg_recursive = !arg_recursive;
+ fprintf(stdout, "\nRecursive process counting: %s", yes_no(arg_recursive));
+ }
fflush(stdout);
sleep(1);
break;
@@ -939,9 +1009,10 @@ int main(int argc, char *argv[]) {
case '?':
case 'h':
fprintf(stdout,
- "\t<" ON "p" OFF "> By path; <" ON "t" OFF "> By tasks; <" ON "c" OFF "> By CPU; <" ON "m" OFF "> By memory; <" ON "i" OFF "> By I/O\n"
+ "\t<" ON "p" OFF "> By path; <" ON "t" OFF "> By tasks/procs; <" ON "c" OFF "> By CPU; <" ON "m" OFF "> By memory; <" ON "i" OFF "> By I/O\n"
"\t<" ON "+" OFF "> Inc. delay; <" ON "-" OFF "> Dec. delay; <" ON "%%" OFF "> Toggle time; <" ON "SPACE" OFF "> Refresh\n"
- "\t<" ON "k" OFF "> Count kernel threads; <" ON "r" OFF "> Count recursively; <" ON "q" OFF "> Quit");
+ "\t<" ON "P" OFF "> Toggle count userspace processes; <" ON "k" OFF "> Toggle count all processes\n"
+ "\t<" ON "r" OFF "> Count processes recursively; <" ON "q" OFF "> Quit");
fflush(stdout);
sleep(3);
break;
diff --git a/src/core/automount.c b/src/core/automount.c
index 5bb61b95d3..c88e3311bc 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -129,10 +129,8 @@ static void automount_done(Unit *u) {
a->where = mfree(a->where);
- set_free(a->tokens);
- a->tokens = NULL;
- set_free(a->expire_tokens);
- a->expire_tokens = NULL;
+ a->tokens = set_free(a->tokens);
+ a->expire_tokens = set_free(a->expire_tokens);
a->expire_event_source = sd_event_source_unref(a->expire_event_source);
}
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index baa7cc5488..48000d4e6e 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -22,10 +22,11 @@
#include <fcntl.h>
#include <fnmatch.h>
-#include "process-util.h"
+#include "cgroup-util.h"
#include "path-util.h"
+#include "process-util.h"
#include "special.h"
-#include "cgroup-util.h"
+
#include "cgroup.h"
#define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC)
@@ -41,6 +42,7 @@ void cgroup_context_init(CGroupContext *c) {
c->memory_limit = (uint64_t) -1;
c->blockio_weight = (unsigned long) -1;
c->startup_blockio_weight = (unsigned long) -1;
+ c->tasks_max = (uint64_t) -1;
c->cpu_quota_per_sec_usec = USEC_INFINITY;
}
@@ -106,6 +108,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
"%sBlockIOWeight=%lu\n"
"%sStartupBlockIOWeight=%lu\n"
"%sMemoryLimit=%" PRIu64 "\n"
+ "%sTasksMax=%" PRIu64 "\n"
"%sDevicePolicy=%s\n"
"%sDelegate=%s\n",
prefix, yes_no(c->cpu_accounting),
@@ -117,6 +120,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
prefix, c->blockio_weight,
prefix, c->startup_blockio_weight,
prefix, c->memory_limit,
+ prefix, c->tasks_max,
prefix, cgroup_device_policy_to_string(c->device_policy),
prefix, yes_no(c->delegate));
@@ -466,6 +470,21 @@ void cgroup_context_apply(CGroupContext *c, CGroupMask mask, const char *path, M
log_debug("Ignoring device %s while writing cgroup attribute.", a->path);
}
}
+
+ if ((mask & CGROUP_MASK_PIDS) && !is_root) {
+
+ if (c->tasks_max != (uint64_t) -1) {
+ char buf[DECIMAL_STR_MAX(uint64_t) + 2];
+
+ sprintf(buf, "%" PRIu64 "\n", c->tasks_max);
+ r = cg_set_attribute("pids", path, "pids.max", buf);
+ } else
+ r = cg_set_attribute("pids", path, "pids.max", "max");
+
+ if (r < 0)
+ log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to set pids.max on %s: %m", path);
+ }
}
CGroupMask cgroup_context_get_mask(CGroupContext *c) {
@@ -494,6 +513,10 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) {
c->device_policy != CGROUP_AUTO)
mask |= CGROUP_MASK_DEVICES;
+ if (c->tasks_accounting ||
+ c->tasks_max != (uint64_t) -1)
+ mask |= CGROUP_MASK_PIDS;
+
return mask;
}
@@ -1459,6 +1482,28 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
return safe_atou64(v, ret);
}
+int unit_get_tasks_current(Unit *u, uint64_t *ret) {
+ _cleanup_free_ char *v = NULL;
+ int r;
+
+ assert(u);
+ assert(ret);
+
+ if (!u->cgroup_path)
+ return -ENODATA;
+
+ if ((u->cgroup_realized_mask & CGROUP_MASK_PIDS) == 0)
+ return -ENODATA;
+
+ r = cg_get_attribute("pids", u->cgroup_path, "pids.current", &v);
+ if (r == -ENOENT)
+ return -ENODATA;
+ if (r < 0)
+ return r;
+
+ return safe_atou64(v, ret);
+}
+
static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
_cleanup_free_ char *v = NULL;
uint64_t ns;
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index 438f5bf50f..3ba09d56a4 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -72,6 +72,7 @@ struct CGroupContext {
bool cpu_accounting;
bool blockio_accounting;
bool memory_accounting;
+ bool tasks_accounting;
unsigned long cpu_shares;
unsigned long startup_cpu_shares;
@@ -88,6 +89,8 @@ struct CGroupContext {
LIST_HEAD(CGroupDeviceAllow, device_allow);
bool delegate;
+
+ uint64_t tasks_max;
};
#include "unit.h"
@@ -137,6 +140,7 @@ int unit_search_main_pid(Unit *u, pid_t *ret);
int unit_watch_all_pids(Unit *u);
int unit_get_memory_current(Unit *u, uint64_t *ret);
+int unit_get_tasks_current(Unit *u, uint64_t *ret);
int unit_get_cpu_usage(Unit *u, nsec_t *ret);
int unit_reset_cpu_usage(Unit *u);
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index ba2f4e53b9..94de92c3dd 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -168,6 +168,8 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
+ SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, tasks_accounting), 0),
+ SD_BUS_PROPERTY("TasksMax", "t", NULL, offsetof(CGroupContext, tasks_max), 0),
SD_BUS_VTABLE_END
};
@@ -551,7 +553,11 @@ int bus_cgroup_set_property(
if (mode != UNIT_CHECK) {
c->memory_limit = limit;
u->cgroup_realized_mask &= ~CGROUP_MASK_MEMORY;
- unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, limit);
+
+ if (limit == (uint64_t) -1)
+ unit_write_drop_in_private(u, mode, name, "MemoryLimit=infinity");
+ else
+ unit_write_drop_in_private_format(u, mode, name, "MemoryLimit=%" PRIu64, limit);
}
return 1;
@@ -667,6 +673,39 @@ int bus_cgroup_set_property(
return 1;
+ } else if (streq(name, "TasksAccounting")) {
+ int b;
+
+ r = sd_bus_message_read(message, "b", &b);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ c->tasks_accounting = b;
+ u->cgroup_realized_mask &= ~CGROUP_MASK_PIDS;
+ unit_write_drop_in_private(u, mode, name, b ? "TasksAccounting=yes" : "TasksAccounting=no");
+ }
+
+ return 1;
+
+ } else if (streq(name, "TasksMax")) {
+ uint64_t limit;
+
+ r = sd_bus_message_read(message, "t", &limit);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ c->tasks_max = limit;
+ u->cgroup_realized_mask &= ~CGROUP_MASK_PIDS;
+
+ if (limit == (uint64_t) -1)
+ unit_write_drop_in_private(u, mode, name, "TasksMax=infinity");
+ else
+ unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu64, limit);
+ }
+
+ return 1;
}
if (u->transient && u->load_state == UNIT_STUB) {
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index f9275ed935..f7e9795928 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -736,6 +736,30 @@ static int property_get_current_memory(
return sd_bus_message_append(reply, "t", sz);
}
+static int property_get_current_tasks(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ uint64_t cn = (uint64_t) -1;
+ Unit *u = userdata;
+ int r;
+
+ assert(bus);
+ assert(reply);
+ assert(u);
+
+ r = unit_get_tasks_current(u, &cn);
+ if (r < 0 && r != -ENODATA)
+ log_unit_warning_errno(u, r, "Failed to get pids.current attribute: %m");
+
+ return sd_bus_message_append(reply, "t", cn);
+}
+
static int property_get_cpu_usage(
sd_bus *bus,
const char *path,
@@ -796,6 +820,7 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0),
SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
+ SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0),
SD_BUS_VTABLE_END
};
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 0a2180c6a7..2d6a1ff836 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -1055,12 +1055,10 @@ void bus_done(Manager *m) {
while ((b = set_steal_first(m->private_buses)))
destroy_bus(m, &b);
- set_free(m->private_buses);
- m->private_buses = NULL;
+ m->private_buses = set_free(m->private_buses);
m->subscribed = sd_bus_track_unref(m->subscribed);
- strv_free(m->deserialized_subscribed);
- m->deserialized_subscribed = NULL;
+ m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
if (m->private_listen_event_source)
m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
@@ -1191,8 +1189,7 @@ int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
}
}
- strv_free(*l);
- *l = NULL;
+ *l = strv_free(*l);
return r;
}
diff --git a/src/core/device.c b/src/core/device.c
index 7fdfacfddf..0b54518691 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -594,8 +594,7 @@ static void device_shutdown(Manager *m) {
m->udev_monitor = NULL;
}
- hashmap_free(m->devices_by_sysfs);
- m->devices_by_sysfs = NULL;
+ m->devices_by_sysfs = hashmap_free(m->devices_by_sysfs);
}
static int device_enumerate(Manager *m) {
diff --git a/src/core/execute.c b/src/core/execute.c
index 6abb0a5d5d..d1acda6682 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1992,11 +1992,8 @@ void exec_context_done(ExecContext *c) {
assert(c);
- strv_free(c->environment);
- c->environment = NULL;
-
- strv_free(c->environment_files);
- c->environment_files = NULL;
+ c->environment = strv_free(c->environment);
+ c->environment_files = strv_free(c->environment_files);
for (l = 0; l < ELEMENTSOF(c->rlimit); l++)
c->rlimit[l] = mfree(c->rlimit[l]);
@@ -2008,8 +2005,7 @@ void exec_context_done(ExecContext *c) {
c->user = mfree(c->user);
c->group = mfree(c->group);
- strv_free(c->supplementary_groups);
- c->supplementary_groups = NULL;
+ c->supplementary_groups = strv_free(c->supplementary_groups);
c->pam_name = mfree(c->pam_name);
@@ -2018,14 +2014,9 @@ void exec_context_done(ExecContext *c) {
c->capabilities = NULL;
}
- strv_free(c->read_only_dirs);
- c->read_only_dirs = NULL;
-
- strv_free(c->read_write_dirs);
- c->read_write_dirs = NULL;
-
- strv_free(c->inaccessible_dirs);
- c->inaccessible_dirs = NULL;
+ c->read_only_dirs = strv_free(c->read_only_dirs);
+ c->read_write_dirs = strv_free(c->read_write_dirs);
+ c->inaccessible_dirs = strv_free(c->inaccessible_dirs);
if (c->cpuset)
CPU_FREE(c->cpuset);
@@ -2034,17 +2025,11 @@ void exec_context_done(ExecContext *c) {
c->selinux_context = mfree(c->selinux_context);
c->apparmor_profile = mfree(c->apparmor_profile);
- set_free(c->syscall_filter);
- c->syscall_filter = NULL;
+ c->syscall_filter = set_free(c->syscall_filter);
+ c->syscall_archs = set_free(c->syscall_archs);
+ c->address_families = set_free(c->address_families);
- set_free(c->syscall_archs);
- c->syscall_archs = NULL;
-
- set_free(c->address_families);
- c->address_families = NULL;
-
- strv_free(c->runtime_directory);
- c->runtime_directory = NULL;
+ c->runtime_directory = strv_free(c->runtime_directory);
bus_endpoint_free(c->bus_endpoint);
c->bus_endpoint = NULL;
@@ -2079,8 +2064,7 @@ void exec_command_done(ExecCommand *c) {
c->path = mfree(c->path);
- strv_free(c->argv);
- c->argv = NULL;
+ c->argv = strv_free(c->argv);
}
void exec_command_done_array(ExecCommand *c, unsigned n) {
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index edd55b9e45..e056fd863c 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -124,6 +124,8 @@ $1.StartupBlockIOWeight, config_parse_blockio_weight, 0,
$1.BlockIODeviceWeight, config_parse_blockio_device_weight, 0, offsetof($1, cgroup_context)
$1.BlockIOReadBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context)
$1.BlockIOWriteBandwidth, config_parse_blockio_bandwidth, 0, offsetof($1, cgroup_context)
+$1.TasksAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.tasks_accounting)
+$1.TasksMax, config_parse_tasks_max, 0, offsetof($1, cgroup_context)
$1.Delegate, config_parse_bool, 0, offsetof($1, cgroup_context.delegate)'
)m4_dnl
Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index b695c57da8..f7a8539910 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1888,8 +1888,7 @@ int config_parse_unit_env_file(const char *unit,
if (isempty(rvalue)) {
/* Empty assignment frees the list */
- strv_free(*env);
- *env = NULL;
+ *env = strv_free(*env);
return 0;
}
@@ -1937,8 +1936,7 @@ int config_parse_environ(const char *unit,
if (isempty(rvalue)) {
/* Empty assignment resets the list */
- strv_free(*env);
- *env = NULL;
+ *env = strv_free(*env);
return 0;
}
@@ -2245,8 +2243,7 @@ int config_parse_documentation(const char *unit,
if (isempty(rvalue)) {
/* Empty assignment resets the list */
- strv_free(u->documentation);
- u->documentation = NULL;
+ u->documentation = strv_free(u->documentation);
return 0;
}
@@ -2305,8 +2302,7 @@ int config_parse_syscall_filter(
if (isempty(rvalue)) {
/* Empty assignment resets the list */
- set_free(c->syscall_filter);
- c->syscall_filter = NULL;
+ c->syscall_filter = set_free(c->syscall_filter);
c->syscall_whitelist = false;
return 0;
}
@@ -2404,8 +2400,7 @@ int config_parse_syscall_archs(
int r;
if (isempty(rvalue)) {
- set_free(*archs);
- *archs = NULL;
+ *archs = set_free(*archs);
return 0;
}
@@ -2501,8 +2496,7 @@ int config_parse_address_families(
if (isempty(rvalue)) {
/* Empty assignment resets the list */
- set_free(c->address_families);
- c->address_families = NULL;
+ c->address_families = set_free(c->address_families);
c->address_families_whitelist = false;
return 0;
}
@@ -2689,24 +2683,51 @@ int config_parse_memory_limit(
void *userdata) {
CGroupContext *c = data;
- off_t bytes;
+ uint64_t bytes;
int r;
- if (isempty(rvalue)) {
+ if (isempty(rvalue) || streq(rvalue, "infinity")) {
c->memory_limit = (uint64_t) -1;
return 0;
}
- assert_cc(sizeof(uint64_t) == sizeof(off_t));
-
r = parse_size(rvalue, 1024, &bytes);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Memory limit '%s' invalid. Ignoring.", rvalue);
+ if (r < 0 || bytes < 1) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Memory limit '%s' invalid. Ignoring.", rvalue);
+ return 0;
+ }
+
+ c->memory_limit = bytes;
+ return 0;
+}
+
+int config_parse_tasks_max(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ CGroupContext *c = data;
+ uint64_t u;
+ int r;
+
+ if (isempty(rvalue) || streq(rvalue, "infinity")) {
+ c->tasks_max = (uint64_t) -1;
+ return 0;
+ }
+
+ r = safe_atou64(rvalue, &u);
+ if (r < 0 || u < 1) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Maximum tasks value '%s' invalid. Ignoring.", rvalue);
return 0;
}
- c->memory_limit = (uint64_t) bytes;
return 0;
}
@@ -2893,7 +2914,7 @@ int config_parse_blockio_bandwidth(
CGroupBlockIODeviceBandwidth *b;
CGroupContext *c = data;
const char *bandwidth;
- off_t bytes;
+ uint64_t bytes;
bool read;
size_t n;
int r;
@@ -2947,7 +2968,7 @@ int config_parse_blockio_bandwidth(
b->path = path;
path = NULL;
- b->bandwidth = (uint64_t) bytes;
+ b->bandwidth = bytes;
b->read = read;
LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, b);
@@ -3011,8 +3032,7 @@ int config_parse_runtime_directory(
if (isempty(rvalue)) {
/* Empty assignment resets the list */
- strv_free(*rt);
- *rt = NULL;
+ *rt = strv_free(*rt);
return 0;
}
@@ -3140,8 +3160,7 @@ int config_parse_namespace_path_strv(
if (isempty(rvalue)) {
/* Empty assignment resets the list */
- strv_free(*sv);
- *sv = NULL;
+ *sv = strv_free(*sv);
return 0;
}
@@ -3622,7 +3641,7 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_int, "INTEGER" },
{ config_parse_unsigned, "UNSIGNED" },
{ config_parse_iec_size, "SIZE" },
- { config_parse_iec_off, "SIZE" },
+ { config_parse_iec_uint64, "SIZE" },
{ config_parse_si_size, "SIZE" },
{ config_parse_bool, "BOOLEAN" },
{ config_parse_string, "STRING" },
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 1d128716c4..638b343a6e 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -84,6 +84,7 @@ int config_parse_environ(const char *unit, const char *filename, unsigned line,
int config_parse_unit_slice(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_cpu_shares(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_memory_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_tasks_max(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_device_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_device_allow(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_blockio_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/core/main.c b/src/core/main.c
index be95dc68b2..200fe740da 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -114,6 +114,7 @@ static FILE* arg_serialization = NULL;
static bool arg_default_cpu_accounting = false;
static bool arg_default_blockio_accounting = false;
static bool arg_default_memory_accounting = false;
+static bool arg_default_tasks_accounting = false;
static void nop_handler(int sig) {}
@@ -676,6 +677,7 @@ static int parse_config_file(void) {
{ "Manager", "DefaultCPUAccounting", config_parse_bool, 0, &arg_default_cpu_accounting },
{ "Manager", "DefaultBlockIOAccounting", config_parse_bool, 0, &arg_default_blockio_accounting },
{ "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_default_memory_accounting },
+ { "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_default_tasks_accounting },
{}
};
@@ -704,6 +706,7 @@ static void manager_set_defaults(Manager *m) {
m->default_cpu_accounting = arg_default_cpu_accounting;
m->default_blockio_accounting = arg_default_blockio_accounting;
m->default_memory_accounting = arg_default_memory_accounting;
+ m->default_tasks_accounting = arg_default_tasks_accounting;
manager_set_default_rlimits(m, arg_default_rlimit);
manager_environment_add(m, NULL, arg_default_environment);
@@ -1846,8 +1849,7 @@ finish:
arg_default_environment = strv_free(arg_default_environment);
- set_free(arg_syscall_archs);
- arg_syscall_archs = NULL;
+ arg_syscall_archs = set_free(arg_syscall_archs);
mac_selinux_finish();
diff --git a/src/core/manager.h b/src/core/manager.h
index 9956cb7700..78a0e50a33 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -256,6 +256,7 @@ struct Manager {
bool default_cpu_accounting;
bool default_memory_accounting;
bool default_blockio_accounting;
+ bool default_tasks_accounting;
usec_t default_timer_accuracy_usec;
diff --git a/src/core/swap.c b/src/core/swap.c
index 311ce7ee04..bef457069f 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -1254,8 +1254,7 @@ static void swap_shutdown(Manager *m) {
m->proc_swaps = safe_fclose(m->proc_swaps);
- hashmap_free(m->swaps_by_devnode);
- m->swaps_by_devnode = NULL;
+ m->swaps_by_devnode = hashmap_free(m->swaps_by_devnode);
}
static int swap_enumerate(Manager *m) {
diff --git a/src/core/unit.c b/src/core/unit.c
index 24a6747b10..2ebfb09a7a 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -125,6 +125,7 @@ static void unit_init(Unit *u) {
cc->cpu_accounting = u->manager->default_cpu_accounting;
cc->blockio_accounting = u->manager->default_blockio_accounting;
cc->memory_accounting = u->manager->default_memory_accounting;
+ cc->tasks_accounting = u->manager->default_tasks_accounting;
}
ec = unit_get_exec_context(u);
@@ -445,8 +446,7 @@ static void unit_free_requires_mounts_for(Unit *u) {
}
}
- strv_free(u->requires_mounts_for);
- u->requires_mounts_for = NULL;
+ u->requires_mounts_for = strv_free(u->requires_mounts_for);
}
static void unit_done(Unit *u) {
@@ -674,8 +674,7 @@ static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitD
/* The move cannot fail. The caller must have performed a reservation. */
assert_se(complete_move(&u->dependencies[d], &other->dependencies[d]) == 0);
- set_free(other->dependencies[d]);
- other->dependencies[d] = NULL;
+ other->dependencies[d] = set_free(other->dependencies[d]);
}
int unit_merge(Unit *u, Unit *other) {
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 6fad8ad80c..ab91afec4d 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -330,7 +330,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
free(d->keyfile);
d->keyfile = uuid_value;
uuid_value = NULL;
- } else if (free_and_strdup(&arg_default_keyfile, value))
+ } else if (free_and_strdup(&arg_default_keyfile, value) < 0)
return log_oom();
} else if (STR_IN_SET(key, "luks.name", "rd.luks.name") && value) {
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index 44e029ef98..0e77197e34 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -314,7 +314,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
if (r < 0)
log_warning_errno(errno, "Failed to set file attributes on %s: %m", tp);
- r = copy_bytes(i->raw_job->disk_fd, dfd, (off_t) -1, true);
+ r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, true);
if (r < 0) {
unlink(tp);
return log_error_errno(r, "Failed to make writable copy of image: %m");
diff --git a/src/journal/compress.c b/src/journal/compress.c
index 383f6a6e96..c66043e503 100644
--- a/src/journal/compress.c
+++ b/src/journal/compress.c
@@ -342,11 +342,10 @@ int decompress_startswith(int compression,
return -EBADMSG;
}
-int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
#ifdef HAVE_XZ
_cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
lzma_ret ret;
-
uint8_t buf[BUFSIZ], out[BUFSIZ];
lzma_action action = LZMA_RUN;
@@ -364,8 +363,8 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
size_t m = sizeof(buf);
ssize_t n;
- if (max_bytes != -1 && m > (size_t) max_bytes)
- m = max_bytes;
+ if (max_bytes != (uint64_t) -1 && (uint64_t) m > max_bytes)
+ m = (size_t) max_bytes;
n = read(fdf, buf, m);
if (n < 0)
@@ -376,8 +375,8 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
s.next_in = buf;
s.avail_in = n;
- if (max_bytes != -1) {
- assert(max_bytes >= n);
+ if (max_bytes != (uint64_t) -1) {
+ assert(max_bytes >= (uint64_t) n);
max_bytes -= n;
}
}
@@ -419,7 +418,7 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
#define LZ4_BUFSIZE (512*1024)
-int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
#ifdef HAVE_LZ4
@@ -445,8 +444,8 @@ int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
int r;
m = LZ4_BUFSIZE;
- if (max_bytes != -1 && m > (size_t) max_bytes - total_in)
- m = max_bytes - total_in;
+ if (max_bytes != (uint64_t) -1 && (uint64_t) m > (max_bytes - total_in))
+ m = (size_t) (max_bytes - total_in);
n = read(fdf, buf, m);
if (n < 0)
@@ -497,7 +496,7 @@ int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
#endif
}
-int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {
+int decompress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
#ifdef HAVE_XZ
_cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
@@ -546,8 +545,8 @@ int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {
n = sizeof(out) - s.avail_out;
- if (max_bytes != -1) {
- if (max_bytes < n)
+ if (max_bytes != (uint64_t) -1) {
+ if (max_bytes < (uint64_t) n)
return -EFBIG;
max_bytes -= n;
@@ -572,7 +571,7 @@ int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {
#endif
}
-int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
+int decompress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
#ifdef HAVE_LZ4
_cleanup_free_ char *buf = NULL, *out = NULL;
@@ -626,8 +625,8 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
total_out += r;
- if (max_bytes != -1 && total_out > (size_t) max_bytes) {
- log_debug("Decompressed stream longer than %zd bytes", max_bytes);
+ if (max_bytes != (uint64_t) -1 && (uint64_t) total_out > max_bytes) {
+ log_debug("Decompressed stream longer than %" PRIu64 " bytes", max_bytes);
return -EFBIG;
}
@@ -647,7 +646,7 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
#endif
}
-int decompress_stream(const char *filename, int fdf, int fdt, off_t max_bytes) {
+int decompress_stream(const char *filename, int fdf, int fdt, uint64_t max_bytes) {
if (endswith(filename, ".lz4"))
return decompress_stream_lz4(fdf, fdt, max_bytes);
diff --git a/src/journal/compress.h b/src/journal/compress.h
index 6294f16faa..9a065eb763 100644
--- a/src/journal/compress.h
+++ b/src/journal/compress.h
@@ -67,11 +67,11 @@ int decompress_startswith(int compression,
const void *prefix, size_t prefix_len,
uint8_t extra);
-int compress_stream_xz(int fdf, int fdt, off_t max_bytes);
-int compress_stream_lz4(int fdf, int fdt, off_t max_bytes);
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes);
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes);
-int decompress_stream_xz(int fdf, int fdt, off_t max_size);
-int decompress_stream_lz4(int fdf, int fdt, off_t max_size);
+int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
+int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
#ifdef HAVE_LZ4
# define compress_stream compress_stream_lz4
@@ -81,4 +81,4 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_size);
# define COMPRESSED_EXT ".xz"
#endif
-int decompress_stream(const char *filename, int fdf, int fdt, off_t max_bytes);
+int decompress_stream(const char *filename, int fdf, int fdt, uint64_t max_bytes);
diff --git a/src/journal/coredump-vacuum.c b/src/journal/coredump-vacuum.c
index c0347ef569..efe418615a 100644
--- a/src/journal/coredump-vacuum.c
+++ b/src/journal/coredump-vacuum.c
@@ -28,10 +28,10 @@
#include "coredump-vacuum.h"
-#define DEFAULT_MAX_USE_LOWER (off_t) (1ULL*1024ULL*1024ULL) /* 1 MiB */
-#define DEFAULT_MAX_USE_UPPER (off_t) (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
-#define DEFAULT_KEEP_FREE_UPPER (off_t) (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
-#define DEFAULT_KEEP_FREE (off_t) (1024ULL*1024ULL) /* 1 MB */
+#define DEFAULT_MAX_USE_LOWER (uint64_t) (1ULL*1024ULL*1024ULL) /* 1 MiB */
+#define DEFAULT_MAX_USE_UPPER (uint64_t) (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
+#define DEFAULT_KEEP_FREE_UPPER (uint64_t) (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
+#define DEFAULT_KEEP_FREE (uint64_t) (1024ULL*1024ULL) /* 1 MB */
struct vacuum_candidate {
unsigned n_files;
@@ -82,8 +82,8 @@ static int uid_from_file_name(const char *filename, uid_t *uid) {
return parse_uid(u, uid);
}
-static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use) {
- off_t fs_size = 0, fs_free = (off_t) -1;
+static bool vacuum_necessary(int fd, uint64_t sum, uint64_t keep_free, uint64_t max_use) {
+ uint64_t fs_size = 0, fs_free = (uint64_t) -1;
struct statvfs sv;
assert(fd >= 0);
@@ -93,7 +93,7 @@ static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use)
fs_free = sv.f_frsize * sv.f_bfree;
}
- if (max_use == (off_t) -1) {
+ if (max_use == (uint64_t) -1) {
if (fs_size > 0) {
max_use = PAGE_ALIGN(fs_size / 10); /* 10% */
@@ -111,7 +111,7 @@ static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use)
if (max_use > 0 && sum > max_use)
return true;
- if (keep_free == (off_t) -1) {
+ if (keep_free == (uint64_t) -1) {
if (fs_size > 0) {
keep_free = PAGE_ALIGN((fs_size * 3) / 20); /* 15% */
@@ -129,7 +129,7 @@ static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use)
return false;
}
-int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use) {
+int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
_cleanup_closedir_ DIR *d = NULL;
struct stat exclude_st;
int r;
@@ -161,7 +161,7 @@ int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use) {
_cleanup_(vacuum_candidate_hasmap_freep) Hashmap *h = NULL;
struct vacuum_candidate *worst = NULL;
struct dirent *de;
- off_t sum = 0;
+ uint64_t sum = 0;
rewinddir(d);
diff --git a/src/journal/coredump-vacuum.h b/src/journal/coredump-vacuum.h
index 7ad4399305..7779c97574 100644
--- a/src/journal/coredump-vacuum.h
+++ b/src/journal/coredump-vacuum.h
@@ -21,6 +21,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <inttypes.h>
#include <sys/types.h>
-int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use);
+int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use);
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index 7d94b145c9..e1e66b9826 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -51,7 +51,7 @@
#include "process-util.h"
/* The maximum size up to which we process coredumps */
-#define PROCESS_SIZE_MAX ((off_t) (2LLU*1024LLU*1024LLU*1024LLU))
+#define PROCESS_SIZE_MAX ((uint64_t) (2LLU*1024LLU*1024LLU*1024LLU))
/* The maximum size up to which we leave the coredump around on
* disk */
@@ -97,21 +97,21 @@ static DEFINE_CONFIG_PARSE_ENUM(config_parse_coredump_storage, coredump_storage,
static CoredumpStorage arg_storage = COREDUMP_STORAGE_EXTERNAL;
static bool arg_compress = true;
-static off_t arg_process_size_max = PROCESS_SIZE_MAX;
-static off_t arg_external_size_max = EXTERNAL_SIZE_MAX;
+static uint64_t arg_process_size_max = PROCESS_SIZE_MAX;
+static uint64_t arg_external_size_max = EXTERNAL_SIZE_MAX;
static size_t arg_journal_size_max = JOURNAL_SIZE_MAX;
-static off_t arg_keep_free = (off_t) -1;
-static off_t arg_max_use = (off_t) -1;
+static uint64_t arg_keep_free = (uint64_t) -1;
+static uint64_t arg_max_use = (uint64_t) -1;
static int parse_config(void) {
static const ConfigTableItem items[] = {
{ "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage },
{ "Coredump", "Compress", config_parse_bool, 0, &arg_compress },
- { "Coredump", "ProcessSizeMax", config_parse_iec_off, 0, &arg_process_size_max },
- { "Coredump", "ExternalSizeMax", config_parse_iec_off, 0, &arg_external_size_max },
+ { "Coredump", "ProcessSizeMax", config_parse_iec_uint64, 0, &arg_process_size_max },
+ { "Coredump", "ExternalSizeMax", config_parse_iec_uint64, 0, &arg_external_size_max },
{ "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max },
- { "Coredump", "KeepFree", config_parse_iec_off, 0, &arg_keep_free },
- { "Coredump", "MaxUse", config_parse_iec_off, 0, &arg_max_use },
+ { "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free },
+ { "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use },
{}
};
@@ -224,7 +224,7 @@ static int fix_permissions(
return 0;
}
-static int maybe_remove_external_coredump(const char *filename, off_t size) {
+static int maybe_remove_external_coredump(const char *filename, uint64_t size) {
/* Returns 1 if might remove, 0 if will not remove, < 0 on error. */
@@ -285,7 +285,7 @@ static int save_external_coredump(
uid_t uid,
char **ret_filename,
int *ret_fd,
- off_t *ret_size) {
+ uint64_t *ret_size) {
_cleanup_free_ char *fn = NULL, *tmp = NULL;
_cleanup_close_ int fd = -1;
@@ -372,9 +372,9 @@ static int save_external_coredump(
/* OK, this worked, we can get rid of the uncompressed version now */
unlink_noerrno(tmp);
- *ret_filename = fn_compressed; /* compressed */
- *ret_fd = fd; /* uncompressed */
- *ret_size = st.st_size; /* uncompressed */
+ *ret_filename = fn_compressed; /* compressed */
+ *ret_fd = fd; /* uncompressed */
+ *ret_size = (uint64_t) st.st_size; /* uncompressed */
fn_compressed = NULL;
fd = -1;
@@ -393,7 +393,7 @@ uncompressed:
*ret_filename = fn;
*ret_fd = fd;
- *ret_size = st.st_size;
+ *ret_size = (uint64_t) st.st_size;
fn = NULL;
fd = -1;
@@ -544,7 +544,7 @@ int main(int argc, char* argv[]) {
_cleanup_close_ int coredump_fd = -1;
struct iovec iovec[26];
- off_t coredump_size;
+ uint64_t coredump_size;
int r, j = 0;
uid_t uid, owner_uid;
gid_t gid;
@@ -840,7 +840,7 @@ log:
/* Optionally store the entire coredump in the journal */
if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) &&
- coredump_size <= (off_t) arg_journal_size_max) {
+ coredump_size <= arg_journal_size_max) {
size_t sz = 0;
/* Store the coredump itself in the journal */
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 4f94799ce7..73d3a4bb9d 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -2542,7 +2542,7 @@ void journal_file_print_header(JournalFile *f) {
le64toh(f->header->n_entry_arrays));
if (fstat(f->fd, &st) >= 0)
- printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (off_t) st.st_blocks * 512ULL));
+ printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (uint64_t) st.st_blocks * 512ULL));
}
static int journal_file_warn_btrfs(JournalFile *f) {
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 576e4e4d03..9b483413e7 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -107,7 +107,7 @@ static bool arg_reverse = false;
static int arg_journal_type = 0;
static const char *arg_root = NULL;
static const char *arg_machine = NULL;
-static off_t arg_vacuum_size = (off_t) -1;
+static uint64_t arg_vacuum_size = (uint64_t) -1;
static usec_t arg_vacuum_time = USEC_INFINITY;
static enum {
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
index 74554c1c34..bf7c773009 100644
--- a/src/journal/journald-gperf.gperf
+++ b/src/journal/journald-gperf.gperf
@@ -21,12 +21,12 @@ Journal.Seal, config_parse_bool, 0, offsetof(Server, seal)
Journal.SyncIntervalSec, config_parse_sec, 0, offsetof(Server, sync_interval_usec)
Journal.RateLimitInterval, config_parse_sec, 0, offsetof(Server, rate_limit_interval)
Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst)
-Journal.SystemMaxUse, config_parse_iec_off, 0, offsetof(Server, system_metrics.max_use)
-Journal.SystemMaxFileSize, config_parse_iec_off, 0, offsetof(Server, system_metrics.max_size)
-Journal.SystemKeepFree, config_parse_iec_off, 0, offsetof(Server, system_metrics.keep_free)
-Journal.RuntimeMaxUse, config_parse_iec_off, 0, offsetof(Server, runtime_metrics.max_use)
-Journal.RuntimeMaxFileSize, config_parse_iec_off, 0, offsetof(Server, runtime_metrics.max_size)
-Journal.RuntimeKeepFree, config_parse_iec_off, 0, offsetof(Server, runtime_metrics.keep_free)
+Journal.SystemMaxUse, config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_use)
+Journal.SystemMaxFileSize, config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_size)
+Journal.SystemKeepFree, config_parse_iec_uint64, 0, offsetof(Server, system_metrics.keep_free)
+Journal.RuntimeMaxUse, config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.max_use)
+Journal.RuntimeMaxFileSize, config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.max_size)
+Journal.RuntimeKeepFree, config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.keep_free)
Journal.MaxRetentionSec, config_parse_sec, 0, offsetof(Server, max_retention_usec)
Journal.MaxFileSec, config_parse_sec, 0, offsetof(Server, max_file_usec)
Journal.ForwardToSyslog, config_parse_bool, 0, offsetof(Server, forward_to_syslog)
diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c
index 41a566d714..f17c00e60d 100644
--- a/src/journal/test-compress.c
+++ b/src/journal/test-compress.c
@@ -44,8 +44,8 @@ typedef int (decompress_sw_t)(const void *src, uint64_t src_size,
const void *prefix, size_t prefix_len,
uint8_t extra);
-typedef int (compress_stream_t)(int fdf, int fdt, off_t max_bytes);
-typedef int (decompress_stream_t)(int fdf, int fdt, off_t max_size);
+typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes);
+typedef int (decompress_stream_t)(int fdf, int fdt, uint64_t max_size);
static void test_compress_decompress(int compression,
compress_blob_t compress,
diff --git a/src/journal/test-coredump-vacuum.c b/src/journal/test-coredump-vacuum.c
index a4dd00125d..514dadc1dc 100644
--- a/src/journal/test-coredump-vacuum.c
+++ b/src/journal/test-coredump-vacuum.c
@@ -25,7 +25,7 @@
int main(int argc, char *argv[]) {
- if (coredump_vacuum(-1, (off_t) -1, 70 * 1024) < 0)
+ if (coredump_vacuum(-1, (uint64_t) -1, 70 * 1024) < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 6826e21665..3e8cb0b7d0 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -109,8 +109,7 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
c->supplementary_gids = mfree(c->supplementary_gids);
- strv_free(c->well_known_names);
- c->well_known_names = NULL;
+ c->well_known_names = strv_free(c->well_known_names);
bus_creds_done(c);
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index a1f0f30d6c..9a6d338231 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -1823,20 +1823,20 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_SIZE: {
- off_t o;
+ uint64_t sz;
- r = parse_size(optarg, 1024, &o);
+ r = parse_size(optarg, 1024, &sz);
if (r < 0) {
log_error("Failed to parse size: %s", optarg);
return r;
}
- if ((off_t) (size_t) o != o) {
+ if ((uint64_t) (size_t) sz != sz) {
log_error("Size out of range.");
return -E2BIG;
}
- arg_snaplen = (size_t) o;
+ arg_snaplen = (size_t) sz;
break;
}
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index f2c89e3653..47669afdef 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -879,15 +879,15 @@ int config_parse_tmpfs_size(
*sz = PAGE_ALIGN((size_t) ((physical_memory() * (uint64_t) ul) / (uint64_t) 100));
} else {
- off_t o;
+ uint64_t k;
- r = parse_size(rvalue, 1024, &o);
- if (r < 0 || (off_t) (size_t) o != o) {
- log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
+ r = parse_size(rvalue, 1024, &k);
+ if (r < 0 || (uint64_t) (size_t) k != k) {
+ log_syntax(unit, LOG_ERR, filename, line, r < 0 ? r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
return 0;
}
- *sz = PAGE_ALIGN((size_t) o);
+ *sz = PAGE_ALIGN((size_t) k);
}
return 0;
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index cc38116704..6aaaa8aa31 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -423,7 +423,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
_exit(EXIT_FAILURE);
}
- r = copy_bytes(fd, pair[1], (off_t) -1, false);
+ r = copy_bytes(fd, pair[1], (uint64_t) -1, false);
if (r < 0)
_exit(EXIT_FAILURE);
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 7b8f6d1fab..ab113efb28 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -2385,13 +2385,9 @@ static int set_limit(int argc, char *argv[], void *userdata) {
if (streq(argv[argc-1], "-"))
limit = (uint64_t) -1;
else {
- off_t off;
-
- r = parse_size(argv[argc-1], 1024, &off);
+ r = parse_size(argv[argc-1], 1024, &limit);
if (r < 0)
return log_error("Failed to parse size: %s", argv[argc-1]);
-
- limit = (uint64_t) off;
}
if (argc > 2)
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 33943a4b2f..5702df8ab4 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3601,7 +3601,7 @@ finish:
/* Try to flush whatever is still queued in the pty */
if (master >= 0)
- (void) copy_bytes(master, STDOUT_FILENO, (off_t) -1, false);
+ (void) copy_bytes(master, STDOUT_FILENO, (uint64_t) -1, false);
loop_remove(loop_nr, &image_fd);
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
index 674bb6af28..8a59bd1c3c 100644
--- a/src/resolve/resolved-dns-zone.c
+++ b/src/resolve/resolved-dns-zone.c
@@ -90,11 +90,8 @@ void dns_zone_flush(DnsZone *z) {
assert(hashmap_size(z->by_key) == 0);
assert(hashmap_size(z->by_name) == 0);
- hashmap_free(z->by_key);
- z->by_key = NULL;
-
- hashmap_free(z->by_name);
- z->by_name = NULL;
+ z->by_key = hashmap_free(z->by_key);
+ z->by_name = hashmap_free(z->by_name);
}
static DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr) {
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 47f461a37d..b9fd8e3dbc 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -238,8 +238,7 @@ static int link_update_domains(Link *l) {
if (!l->unicast_scope)
return 0;
- strv_free(l->unicast_scope->domains);
- l->unicast_scope->domains = NULL;
+ l->unicast_scope->domains = strv_free(l->unicast_scope->domains);
r = sd_network_link_get_domains(l->ifindex,
&l->unicast_scope->domains);
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 36c44227c5..4dc4ca581d 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -1421,7 +1421,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
return bus_log_create_error(r);
if (STR_IN_SET(field,
- "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
+ "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
"SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
"IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit")) {
@@ -1434,15 +1434,34 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_append(m, "v", "b", r);
} else if (streq(field, "MemoryLimit")) {
- off_t bytes;
+ uint64_t bytes;
- r = parse_size(eq, 1024, &bytes);
- if (r < 0) {
- log_error("Failed to parse bytes specification %s", assignment);
- return -EINVAL;
+ if (isempty(eq) || streq(eq, "infinity"))
+ bytes = (uint64_t) -1;
+ else {
+ r = parse_size(eq, 1024, &bytes);
+ if (r < 0) {
+ log_error("Failed to parse bytes specification %s", assignment);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append(m, "v", "t", bytes);
+
+ } else if (streq(field, "TasksMax")) {
+ uint64_t n;
+
+ if (isempty(eq) || streq(eq, "infinity"))
+ n = (uint64_t) -1;
+ else {
+ r = safe_atou64(eq, &n);
+ if (r < 0) {
+ log_error("Failed to parse maximum tasks specification %s", assignment);
+ return -EINVAL;
+ }
}
- r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
+ r = sd_bus_message_append(m, "v", "t", n);
} else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
uint64_t u;
@@ -1492,7 +1511,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_append(m, "v", "a(st)", 0);
else {
const char *path, *bandwidth, *e;
- off_t bytes;
+ uint64_t bytes;
e = strchr(eq, ' ');
if (e) {
@@ -1514,7 +1533,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
return -EINVAL;
}
- r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
+ r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
}
} else if (streq(field, "BlockIODeviceWeight")) {
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 23512f0d35..946eac6823 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -469,7 +469,7 @@ int config_parse_iec_size(const char* unit,
void *userdata) {
size_t *sz = data;
- off_t o;
+ uint64_t v;
int r;
assert(filename);
@@ -477,13 +477,13 @@ int config_parse_iec_size(const char* unit,
assert(rvalue);
assert(data);
- r = parse_size(rvalue, 1024, &o);
- if (r < 0 || (off_t) (size_t) o != o) {
- log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
+ r = parse_size(rvalue, 1024, &v);
+ if (r < 0 || (uint64_t) (size_t) v != v) {
+ log_syntax(unit, LOG_ERR, filename, line, r < 0 ? r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
return 0;
}
- *sz = (size_t) o;
+ *sz = (size_t) v;
return 0;
}
@@ -499,7 +499,7 @@ int config_parse_si_size(const char* unit,
void *userdata) {
size_t *sz = data;
- off_t o;
+ uint64_t v;
int r;
assert(filename);
@@ -507,17 +507,17 @@ int config_parse_si_size(const char* unit,
assert(rvalue);
assert(data);
- r = parse_size(rvalue, 1000, &o);
- if (r < 0 || (off_t) (size_t) o != o) {
- log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
+ r = parse_size(rvalue, 1000, &v);
+ if (r < 0 || (uint64_t) (size_t) v != v) {
+ log_syntax(unit, LOG_ERR, filename, line, r < 0 ? r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
return 0;
}
- *sz = (size_t) o;
+ *sz = (size_t) v;
return 0;
}
-int config_parse_iec_off(const char* unit,
+int config_parse_iec_uint64(const char* unit,
const char *filename,
unsigned line,
const char *section,
@@ -528,7 +528,7 @@ int config_parse_iec_off(const char* unit,
void *data,
void *userdata) {
- off_t *bytes = data;
+ uint64_t *bytes = data;
int r;
assert(filename);
@@ -536,11 +536,9 @@ int config_parse_iec_off(const char* unit,
assert(rvalue);
assert(data);
- assert_cc(sizeof(off_t) == sizeof(uint64_t));
-
r = parse_size(rvalue, 1024, bytes);
if (r < 0)
- log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse size value, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
return 0;
}
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index 34e3815782..4efed138c9 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -109,7 +109,7 @@ int config_parse_uint64(const char *unit, const char *filename, unsigned line, c
int config_parse_double(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_iec_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_si_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_iec_off(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_iec_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bool(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_tristate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_string(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c
index 70220bdd14..9c1e4d5e13 100644
--- a/src/shared/machine-image.c
+++ b/src/shared/machine-image.c
@@ -19,16 +19,18 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sys/statfs.h>
-#include <linux/fs.h>
#include <fcntl.h>
+#include <linux/fs.h>
+#include <sys/statfs.h>
-#include "utf8.h"
#include "btrfs-util.h"
-#include "path-util.h"
#include "copy.h"
#include "mkdir.h"
+#include "path-util.h"
#include "rm-rf.h"
+#include "strv.h"
+#include "utf8.h"
+
#include "machine-image.h"
static const char image_search_path[] =
@@ -47,6 +49,38 @@ Image *image_unref(Image *i) {
return NULL;
}
+static char **image_settings_path(Image *image) {
+ _cleanup_strv_free_ char **l = NULL;
+ char **ret;
+ const char *fn, *s;
+ unsigned i = 0;
+
+ assert(image);
+
+ l = new0(char*, 4);
+ if (!l)
+ return NULL;
+
+ fn = strjoina(image->name, ".nspawn");
+
+ FOREACH_STRING(s, "/etc/systemd/nspawn/", "/run/systemd/nspawn/") {
+ l[i] = strappend(s, fn);
+ if (!l[i])
+ return NULL;
+
+ i++;
+ }
+
+ l[i] = file_in_same_dir(image->path, fn);
+ if (!l[i])
+ return NULL;
+
+ ret = l;
+ l = NULL;
+
+ return ret;
+}
+
static int image_new(
ImageType t,
const char *pretty,
@@ -341,6 +375,8 @@ void image_hashmap_free(Hashmap *map) {
int image_remove(Image *i) {
_cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
+ _cleanup_strv_free_ char **settings = NULL;
+ char **j;
int r;
assert(i);
@@ -349,6 +385,10 @@ int image_remove(Image *i) {
path_startswith(i->path, "/usr"))
return -EROFS;
+ settings = image_settings_path(i);
+ if (!settings)
+ return -ENOMEM;
+
/* Make sure we don't interfere with a running nspawn */
r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0)
@@ -357,28 +397,56 @@ int image_remove(Image *i) {
switch (i->type) {
case IMAGE_SUBVOLUME:
- return btrfs_subvol_remove(i->path, true);
+ r = btrfs_subvol_remove(i->path, true);
+ if (r < 0)
+ return r;
+ break;
case IMAGE_DIRECTORY:
/* Allow deletion of read-only directories */
(void) chattr_path(i->path, false, FS_IMMUTABLE_FL);
- return rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+ r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+ if (r < 0)
+ return r;
+
+ break;
case IMAGE_RAW:
if (unlink(i->path) < 0)
return -errno;
-
- return 0;
+ break;
default:
return -EOPNOTSUPP;
}
+
+ STRV_FOREACH(j, settings) {
+ if (unlink(*j) < 0 && errno != ENOENT)
+ log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", *j);
+ }
+
+ return 0;
+}
+
+static int rename_settings_file(const char *path, const char *new_name) {
+ _cleanup_free_ char *rs = NULL;
+ const char *fn;
+
+ fn = strjoina(new_name, ".nspawn");
+
+ rs = file_in_same_dir(path, fn);
+ if (!rs)
+ return -ENOMEM;
+
+ return rename_noreplace(AT_FDCWD, path, AT_FDCWD, rs);
}
int image_rename(Image *i, const char *new_name) {
_cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT;
_cleanup_free_ char *new_path = NULL, *nn = NULL;
+ _cleanup_strv_free_ char **settings = NULL;
unsigned file_attr = 0;
+ char **j;
int r;
assert(i);
@@ -390,6 +458,10 @@ int image_rename(Image *i, const char *new_name) {
path_startswith(i->path, "/usr"))
return -EROFS;
+ settings = image_settings_path(i);
+ if (!settings)
+ return -ENOMEM;
+
/* Make sure we don't interfere with a running nspawn */
r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0)
@@ -458,12 +530,33 @@ int image_rename(Image *i, const char *new_name) {
i->name = nn;
nn = NULL;
+ STRV_FOREACH(j, settings) {
+ r = rename_settings_file(*j, new_name);
+ if (r < 0 && r != -ENOENT)
+ log_debug_errno(r, "Failed to rename settings file %s, ignoring: %m", *j);
+ }
+
return 0;
}
+static int clone_settings_file(const char *path, const char *new_name) {
+ _cleanup_free_ char *rs = NULL;
+ const char *fn;
+
+ fn = strjoina(new_name, ".nspawn");
+
+ rs = file_in_same_dir(path, fn);
+ if (!rs)
+ return -ENOMEM;
+
+ return copy_file_atomic(path, rs, 0664, false, 0);
+}
+
int image_clone(Image *i, const char *new_name, bool read_only) {
_cleanup_release_lock_file_ LockFile name_lock = LOCK_FILE_INIT;
+ _cleanup_strv_free_ char **settings = NULL;
const char *new_path;
+ char **j;
int r;
assert(i);
@@ -471,6 +564,10 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
if (!image_name_is_valid(new_name))
return -EINVAL;
+ settings = image_settings_path(i);
+ if (!settings)
+ return -ENOMEM;
+
/* Make sure nobody takes the new name, between the time we
* checked it is currently unused in all search paths, and the
* time we take possesion of it */
@@ -506,6 +603,12 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
if (r < 0)
return r;
+ STRV_FOREACH(j, settings) {
+ r = clone_settings_file(*j, new_name);
+ if (r < 0 && r != -ENOENT)
+ log_debug_errno(r, "Failed to clone settings %s, ignoring: %m", *j);
+ }
+
return 0;
}
diff --git a/src/shared/pager.c b/src/shared/pager.c
index 479a9d5e8d..41da820938 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -38,7 +38,7 @@ static pid_t pager_pid = 0;
noreturn static void pager_fallback(void) {
int r;
- r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (off_t) -1, false);
+ r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (uint64_t) -1, false);
if (r < 0) {
log_error_errno(r, "Internal pager failed: %m");
_exit(EXIT_FAILURE);
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
index f6a127174c..d803bbe07e 100644
--- a/src/shared/path-lookup.c
+++ b/src/shared/path-lookup.c
@@ -333,8 +333,7 @@ int lookup_paths_init(
log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
} else {
log_debug("Ignoring unit files.");
- strv_free(p->unit_path);
- p->unit_path = NULL;
+ p->unit_path = strv_free(p->unit_path);
}
if (running_as == MANAGER_SYSTEM) {
@@ -390,8 +389,7 @@ int lookup_paths_init(
log_debug("Looking for SysV init scripts in:\n\t%s", t);
} else {
log_debug("Ignoring SysV init scripts.");
- strv_free(p->sysvinit_path);
- p->sysvinit_path = NULL;
+ p->sysvinit_path = strv_free(p->sysvinit_path);
}
if (!strv_isempty(p->sysvrcnd_path)) {
@@ -403,8 +401,7 @@ int lookup_paths_init(
log_debug("Looking for SysV rcN.d links in:\n\t%s", t);
} else {
log_debug("Ignoring SysV rcN.d links.");
- strv_free(p->sysvrcnd_path);
- p->sysvrcnd_path = NULL;
+ p->sysvrcnd_path = strv_free(p->sysvrcnd_path);
}
#else
log_debug("SysV init scripts and rcN.d links support disabled");
@@ -417,8 +414,7 @@ int lookup_paths_init(
void lookup_paths_free(LookupPaths *p) {
assert(p);
- strv_free(p->unit_path);
- p->unit_path = NULL;
+ p->unit_path = strv_free(p->unit_path);
#ifdef HAVE_SYSV_COMPAT
strv_free(p->sysvinit_path);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 20ded4dc0a..d21ba9a566 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -20,59 +20,60 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sys/reboot.h>
-#include <linux/reboot.h>
-#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
#include <getopt.h>
+#include <linux/reboot.h>
#include <locale.h>
#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include <sys/reboot.h>
#include <sys/socket.h>
-#include <stddef.h>
+#include <unistd.h>
+#include "sd-bus.h"
#include "sd-daemon.h"
#include "sd-login.h"
-#include "sd-bus.h"
-#include "log.h"
-#include "util.h"
-#include "macro.h"
-#include "set.h"
-#include "utmp-wtmp.h"
-#include "special.h"
-#include "initreq.h"
-#include "path-util.h"
-#include "strv.h"
+
+#include "build.h"
+#include "bus-common-errors.h"
+#include "bus-error.h"
+#include "bus-message.h"
+#include "bus-util.h"
#include "cgroup-show.h"
#include "cgroup-util.h"
-#include "list.h"
-#include "path-lookup.h"
-#include "exit-status.h"
-#include "build.h"
-#include "unit-name.h"
-#include "pager.h"
-#include "spawn-ask-password-agent.h"
-#include "spawn-polkit-agent.h"
-#include "install.h"
-#include "logs-show.h"
-#include "socket-util.h"
-#include "fileio.h"
#include "copy.h"
-#include "env-util.h"
-#include "bus-util.h"
-#include "bus-message.h"
-#include "bus-error.h"
-#include "bus-common-errors.h"
-#include "mkdir.h"
#include "dropin.h"
#include "efivars.h"
+#include "env-util.h"
+#include "exit-status.h"
+#include "fileio.h"
#include "formats-util.h"
-#include "process-util.h"
-#include "terminal-util.h"
#include "hostname-util.h"
+#include "initreq.h"
+#include "install.h"
+#include "list.h"
+#include "log.h"
+#include "logs-show.h"
+#include "macro.h"
+#include "mkdir.h"
+#include "pager.h"
+#include "path-lookup.h"
+#include "path-util.h"
+#include "process-util.h"
+#include "set.h"
#include "signal-util.h"
+#include "socket-util.h"
+#include "spawn-ask-password-agent.h"
+#include "spawn-polkit-agent.h"
+#include "special.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "unit-name.h"
+#include "util.h"
+#include "utmp-wtmp.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
@@ -1477,6 +1478,8 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha
"BindsTo\0",
[DEPENDENCY_REVERSE] = "RequiredBy\0"
"RequiredByOverridable\0"
+ "RequisiteOf\0"
+ "RequisiteOfOverridable\0"
"WantedBy\0"
"PartOf\0"
"BoundBy\0",
@@ -3297,6 +3300,8 @@ typedef struct UnitStatusInfo {
uint64_t memory_current;
uint64_t memory_limit;
uint64_t cpu_usage_nsec;
+ uint64_t tasks_current;
+ uint64_t tasks_max;
LIST_HEAD(ExecStatusInfo, exec);
} UnitStatusInfo;
@@ -3555,6 +3560,15 @@ static void print_status_info(
if (i->status_errno > 0)
printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
+ if (i->tasks_current != (uint64_t) -1) {
+ printf(" Tasks: %" PRIu64, i->tasks_current);
+
+ if (i->tasks_max != (uint64_t) -1)
+ printf(" (limit: %" PRIi64 ")\n", i->tasks_max);
+ else
+ printf("\n");
+ }
+
if (i->memory_current != (uint64_t) -1) {
char buf[FORMAT_BYTES_MAX];
@@ -3790,6 +3804,10 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
i->memory_current = u;
else if (streq(name, "MemoryLimit"))
i->memory_limit = u;
+ else if (streq(name, "TasksCurrent"))
+ i->tasks_current = u;
+ else if (streq(name, "TasksMax"))
+ i->tasks_max = u;
else if (streq(name, "CPUUsageNSec"))
i->cpu_usage_nsec = u;
@@ -4266,6 +4284,8 @@ static int show_one(
.memory_current = (uint64_t) -1,
.memory_limit = (uint64_t) -1,
.cpu_usage_nsec = (uint64_t) -1,
+ .tasks_current = (uint64_t) -1,
+ .tasks_max = (uint64_t) -1,
};
ExecStatusInfo *p;
int r;
@@ -4641,7 +4661,7 @@ static int cat_file(const char *filename, bool newline) {
ansi_highlight_off());
fflush(stdout);
- return copy_bytes(fd, STDOUT_FILENO, (off_t) -1, false);
+ return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false);
}
static int cat(sd_bus *bus, char **args) {
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index b5e09cad26..aaa33354f4 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -207,7 +207,7 @@ static int make_backup(const char *target, const char *x) {
if (r < 0)
return r;
- r = copy_bytes(src, fileno(dst), (off_t) -1, true);
+ r = copy_bytes(src, fileno(dst), (uint64_t) -1, true);
if (r < 0)
goto fail;
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index b73c958ec5..a03a68bd43 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -146,7 +146,7 @@ static void test_copy_bytes(void) {
assert_se(pipe2(pipefd, O_CLOEXEC) == 0);
- r = copy_bytes(infd, pipefd[1], (off_t) -1, false);
+ r = copy_bytes(infd, pipefd[1], (uint64_t) -1, false);
assert_se(r == 0);
r = read(pipefd[0], buf, sizeof(buf));
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 8ceb71f22a..7935442dbb 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -893,7 +893,7 @@ static void test_protect_errno(void) {
}
static void test_parse_size(void) {
- off_t bytes;
+ uint64_t bytes;
assert_se(parse_size("111", 1024, &bytes) == 0);
assert_se(bytes == 111);
@@ -960,12 +960,12 @@ static void test_parse_size(void) {
assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
}
-static void test_config_parse_iec_off(void) {
- off_t offset = 0;
- assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
+static void test_config_parse_iec_uint64(void) {
+ uint64_t offset = 0;
+ assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
assert_se(offset == 4 * 1024 * 1024);
- assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
+ assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
}
static void test_strextend(void) {
@@ -2250,7 +2250,7 @@ int main(int argc, char *argv[]) {
test_u64log2();
test_protect_errno();
test_parse_size();
- test_config_parse_iec_off();
+ test_config_parse_iec_uint64();
test_strextend();
test_strrep();
test_split_pair();