]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
add00535 LP |
2 | /*** |
3 | This file is part of systemd. | |
4 | ||
5 | Copyright 2016 Lennart Poettering | |
add00535 LP |
6 | ***/ |
7 | ||
8 | #include <sched.h> | |
9 | ||
10 | #include "alloc-util.h" | |
11 | #include "extract-word.h" | |
12 | #include "nsflags.h" | |
add00535 LP |
13 | #include "string-util.h" |
14 | ||
15 | const struct namespace_flag_map namespace_flag_map[] = { | |
16 | { CLONE_NEWCGROUP, "cgroup" }, | |
17 | { CLONE_NEWIPC, "ipc" }, | |
18 | { CLONE_NEWNET, "net" }, | |
19 | /* So, the mount namespace flag is called CLONE_NEWNS for historical reasons. Let's expose it here under a more | |
20 | * explanatory name: "mnt". This is in-line with how the kernel exposes namespaces in /proc/$PID/ns. */ | |
21 | { CLONE_NEWNS, "mnt" }, | |
22 | { CLONE_NEWPID, "pid" }, | |
23 | { CLONE_NEWUSER, "user" }, | |
24 | { CLONE_NEWUTS, "uts" }, | |
25 | {} | |
26 | }; | |
27 | ||
28 | const char* namespace_flag_to_string(unsigned long flag) { | |
29 | unsigned i; | |
30 | ||
31 | flag &= NAMESPACE_FLAGS_ALL; | |
32 | ||
33 | for (i = 0; namespace_flag_map[i].name; i++) | |
34 | if (flag == namespace_flag_map[i].flag) | |
35 | return namespace_flag_map[i].name; | |
36 | ||
37 | return NULL; /* either unknown namespace flag, or a combination of many. This call supports neither. */ | |
38 | } | |
39 | ||
40 | unsigned long namespace_flag_from_string(const char *name) { | |
41 | unsigned i; | |
42 | ||
43 | if (isempty(name)) | |
44 | return 0; | |
45 | ||
46 | for (i = 0; namespace_flag_map[i].name; i++) | |
47 | if (streq(name, namespace_flag_map[i].name)) | |
48 | return namespace_flag_map[i].flag; | |
49 | ||
50 | return 0; | |
51 | } | |
52 | ||
53 | int namespace_flag_from_string_many(const char *name, unsigned long *ret) { | |
54 | unsigned long flags = 0; | |
55 | int r; | |
56 | ||
57 | assert_se(ret); | |
58 | ||
add00535 LP |
59 | for (;;) { |
60 | _cleanup_free_ char *word = NULL; | |
61 | unsigned long f; | |
62 | ||
63 | r = extract_first_word(&name, &word, NULL, 0); | |
64 | if (r < 0) | |
65 | return r; | |
66 | if (r == 0) | |
67 | break; | |
68 | ||
69 | f = namespace_flag_from_string(word); | |
70 | if (f == 0) | |
71 | return -EINVAL; | |
72 | ||
73 | flags |= f; | |
74 | } | |
75 | ||
76 | *ret = flags; | |
77 | return 0; | |
78 | } | |
79 | ||
80 | int namespace_flag_to_string_many(unsigned long flags, char **ret) { | |
81 | _cleanup_free_ char *s = NULL; | |
82 | unsigned i; | |
83 | ||
84 | for (i = 0; namespace_flag_map[i].name; i++) { | |
85 | if ((flags & namespace_flag_map[i].flag) != namespace_flag_map[i].flag) | |
86 | continue; | |
87 | ||
88 | if (!s) { | |
89 | s = strdup(namespace_flag_map[i].name); | |
90 | if (!s) | |
91 | return -ENOMEM; | |
92 | } else { | |
93 | if (!strextend(&s, " ", namespace_flag_map[i].name, NULL)) | |
94 | return -ENOMEM; | |
95 | } | |
96 | } | |
97 | ||
98 | if (!s) { | |
99 | s = strdup(""); | |
100 | if (!s) | |
101 | return -ENOMEM; | |
102 | } | |
103 | ||
ae2a15bc | 104 | *ret = TAKE_PTR(s); |
add00535 LP |
105 | |
106 | return 0; | |
107 | } |