]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/nspawn/nspawn-settings.c
util-lib: split string parsing related calls from util.[ch] into parse-util.[ch]
[thirdparty/systemd.git] / src / nspawn / nspawn-settings.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2015 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "util.h"
23 #include "conf-parser.h"
24 #include "strv.h"
25 #include "cap-list.h"
26
27 #include "nspawn-settings.h"
28
29 int settings_load(FILE *f, const char *path, Settings **ret) {
30 _cleanup_(settings_freep) Settings *s = NULL;
31 int r;
32
33 assert(path);
34 assert(ret);
35
36 s = new0(Settings, 1);
37 if (!s)
38 return -ENOMEM;
39
40 s->boot = -1;
41 s->personality = PERSONALITY_INVALID;
42
43 s->read_only = -1;
44 s->volatile_mode = _VOLATILE_MODE_INVALID;
45
46 s->private_network = -1;
47 s->network_veth = -1;
48
49 r = config_parse(NULL, path, f,
50 "Exec\0"
51 "Network\0"
52 "Files\0",
53 config_item_perf_lookup, nspawn_gperf_lookup,
54 false,
55 false,
56 true,
57 s);
58 if (r < 0)
59 return r;
60
61 *ret = s;
62 s = NULL;
63
64 return 0;
65 }
66
67 Settings* settings_free(Settings *s) {
68
69 if (!s)
70 return NULL;
71
72 strv_free(s->parameters);
73 strv_free(s->environment);
74 free(s->user);
75
76 strv_free(s->network_interfaces);
77 strv_free(s->network_macvlan);
78 strv_free(s->network_ipvlan);
79 free(s->network_bridge);
80 expose_port_free_all(s->expose_ports);
81
82 custom_mount_free_all(s->custom_mounts, s->n_custom_mounts);
83 free(s);
84
85 return NULL;
86 }
87
88 bool settings_private_network(Settings *s) {
89 assert(s);
90
91 return
92 s->private_network > 0 ||
93 s->network_veth > 0 ||
94 s->network_bridge ||
95 s->network_interfaces ||
96 s->network_macvlan ||
97 s->network_ipvlan;
98 }
99
100 bool settings_network_veth(Settings *s) {
101 assert(s);
102
103 return
104 s->network_veth > 0 ||
105 s->network_bridge;
106 }
107
108 DEFINE_CONFIG_PARSE_ENUM(config_parse_volatile_mode, volatile_mode, VolatileMode, "Failed to parse volatile mode");
109
110 int config_parse_expose_port(
111 const char *unit,
112 const char *filename,
113 unsigned line,
114 const char *section,
115 unsigned section_line,
116 const char *lvalue,
117 int ltype,
118 const char *rvalue,
119 void *data,
120 void *userdata) {
121
122 Settings *s = data;
123 int r;
124
125 assert(filename);
126 assert(lvalue);
127 assert(rvalue);
128
129 r = expose_port_parse(&s->expose_ports, rvalue);
130 if (r == -EEXIST) {
131 log_syntax(unit, LOG_ERR, filename, line, r, "Duplicate port specification, ignoring: %s", rvalue);
132 return 0;
133 }
134 if (r < 0) {
135 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse host port %s: %m", rvalue);
136 return 0;
137 }
138
139 return 0;
140 }
141
142 int config_parse_capability(
143 const char *unit,
144 const char *filename,
145 unsigned line,
146 const char *section,
147 unsigned section_line,
148 const char *lvalue,
149 int ltype,
150 const char *rvalue,
151 void *data,
152 void *userdata) {
153
154 uint64_t u = 0, *result = data;
155 int r;
156
157 assert(filename);
158 assert(lvalue);
159 assert(rvalue);
160
161 for (;;) {
162 _cleanup_free_ char *word = NULL;
163 int cap;
164
165 r = extract_first_word(&rvalue, &word, NULL, 0);
166 if (r < 0) {
167 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract capability string, ignoring: %s", rvalue);
168 return 0;
169 }
170 if (r == 0)
171 break;
172
173 cap = capability_from_name(word);
174 if (cap < 0) {
175 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability, ignoring: %s", word);
176 continue;
177 }
178
179 u |= 1 << ((uint64_t) cap);
180 }
181
182 if (u == 0)
183 return 0;
184
185 *result |= u;
186 return 0;
187 }
188
189 int config_parse_id128(
190 const char *unit,
191 const char *filename,
192 unsigned line,
193 const char *section,
194 unsigned section_line,
195 const char *lvalue,
196 int ltype,
197 const char *rvalue,
198 void *data,
199 void *userdata) {
200
201 sd_id128_t t, *result = data;
202 int r;
203
204 assert(filename);
205 assert(lvalue);
206 assert(rvalue);
207
208 r = sd_id128_from_string(rvalue, &t);
209 if (r < 0) {
210 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse 128bit ID/UUID, ignoring: %s", rvalue);
211 return 0;
212 }
213
214 *result = t;
215 return 0;
216 }
217
218 int config_parse_bind(
219 const char *unit,
220 const char *filename,
221 unsigned line,
222 const char *section,
223 unsigned section_line,
224 const char *lvalue,
225 int ltype,
226 const char *rvalue,
227 void *data,
228 void *userdata) {
229
230 Settings *settings = data;
231 int r;
232
233 assert(filename);
234 assert(lvalue);
235 assert(rvalue);
236
237 r = bind_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue, ltype);
238 if (r < 0) {
239 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid bind mount specification %s: %m", rvalue);
240 return 0;
241 }
242
243 return 0;
244 }
245
246 int config_parse_tmpfs(
247 const char *unit,
248 const char *filename,
249 unsigned line,
250 const char *section,
251 unsigned section_line,
252 const char *lvalue,
253 int ltype,
254 const char *rvalue,
255 void *data,
256 void *userdata) {
257
258 Settings *settings = data;
259 int r;
260
261 assert(filename);
262 assert(lvalue);
263 assert(rvalue);
264
265 r = tmpfs_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue);
266 if (r < 0) {
267 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid temporary file system specification %s: %m", rvalue);
268 return 0;
269 }
270
271 if (settings->network_bridge)
272 settings->network_veth = true;
273
274 if (settings->network_interfaces ||
275 settings->network_macvlan ||
276 settings->network_ipvlan ||
277 settings->network_bridge ||
278 settings->network_veth)
279 settings->private_network = true;
280
281 return 0;
282 }