]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-cgroup.c
Merge pull request #20056 from calestyo/split-up-sysusers.d-systemd.conf.in
[thirdparty/systemd.git] / src / core / dbus-cgroup.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <arpa/inet.h>
4
5 #include "af-list.h"
6 #include "alloc-util.h"
7 #include "bpf-firewall.h"
8 #include "bpf-foreign.h"
9 #include "bus-get-properties.h"
10 #include "cgroup-util.h"
11 #include "cgroup.h"
12 #include "core-varlink.h"
13 #include "dbus-cgroup.h"
14 #include "dbus-util.h"
15 #include "errno-util.h"
16 #include "fd-util.h"
17 #include "fileio.h"
18 #include "in-addr-prefix-util.h"
19 #include "ip-protocol-list.h"
20 #include "limits-util.h"
21 #include "parse-util.h"
22 #include "path-util.h"
23 #include "percent-util.h"
24 #include "socket-util.h"
25
26 BUS_DEFINE_PROPERTY_GET(bus_property_get_tasks_max, "t", TasksMax, tasks_max_resolve);
27
28 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
29 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_managed_oom_mode, managed_oom_mode, ManagedOOMMode);
30 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_managed_oom_preference, managed_oom_preference, ManagedOOMPreference);
31
32 static int property_get_cgroup_mask(
33 sd_bus *bus,
34 const char *path,
35 const char *interface,
36 const char *property,
37 sd_bus_message *reply,
38 void *userdata,
39 sd_bus_error *error) {
40
41 CGroupMask *mask = userdata;
42 int r;
43
44 assert(bus);
45 assert(reply);
46
47 r = sd_bus_message_open_container(reply, 'a', "s");
48 if (r < 0)
49 return r;
50
51 for (CGroupController ctrl = 0; ctrl < _CGROUP_CONTROLLER_MAX; ctrl++) {
52 if ((*mask & CGROUP_CONTROLLER_TO_MASK(ctrl)) == 0)
53 continue;
54
55 r = sd_bus_message_append(reply, "s", cgroup_controller_to_string(ctrl));
56 if (r < 0)
57 return r;
58 }
59
60 return sd_bus_message_close_container(reply);
61 }
62
63 static int property_get_delegate_controllers(
64 sd_bus *bus,
65 const char *path,
66 const char *interface,
67 const char *property,
68 sd_bus_message *reply,
69 void *userdata,
70 sd_bus_error *error) {
71
72 CGroupContext *c = userdata;
73
74 assert(bus);
75 assert(reply);
76 assert(c);
77
78 if (!c->delegate)
79 return sd_bus_message_append(reply, "as", 0);
80
81 return property_get_cgroup_mask(bus, path, interface, property, reply, &c->delegate_controllers, error);
82 }
83
84 static int property_get_cpuset(
85 sd_bus *bus,
86 const char *path,
87 const char *interface,
88 const char *property,
89 sd_bus_message *reply,
90 void *userdata,
91 sd_bus_error *error) {
92
93 CPUSet *cpus = userdata;
94 _cleanup_free_ uint8_t *array = NULL;
95 size_t allocated;
96
97 assert(bus);
98 assert(reply);
99 assert(cpus);
100
101 (void) cpu_set_to_dbus(cpus, &array, &allocated);
102 return sd_bus_message_append_array(reply, 'y', array, allocated);
103 }
104
105 static int property_get_io_device_weight(
106 sd_bus *bus,
107 const char *path,
108 const char *interface,
109 const char *property,
110 sd_bus_message *reply,
111 void *userdata,
112 sd_bus_error *error) {
113
114 CGroupContext *c = userdata;
115 CGroupIODeviceWeight *w;
116 int r;
117
118 assert(bus);
119 assert(reply);
120 assert(c);
121
122 r = sd_bus_message_open_container(reply, 'a', "(st)");
123 if (r < 0)
124 return r;
125
126 LIST_FOREACH(device_weights, w, c->io_device_weights) {
127 r = sd_bus_message_append(reply, "(st)", w->path, w->weight);
128 if (r < 0)
129 return r;
130 }
131
132 return sd_bus_message_close_container(reply);
133 }
134
135 static int property_get_io_device_limits(
136 sd_bus *bus,
137 const char *path,
138 const char *interface,
139 const char *property,
140 sd_bus_message *reply,
141 void *userdata,
142 sd_bus_error *error) {
143
144 CGroupContext *c = userdata;
145 CGroupIODeviceLimit *l;
146 int r;
147
148 assert(bus);
149 assert(reply);
150 assert(c);
151
152 r = sd_bus_message_open_container(reply, 'a', "(st)");
153 if (r < 0)
154 return r;
155
156 LIST_FOREACH(device_limits, l, c->io_device_limits) {
157 CGroupIOLimitType type;
158
159 type = cgroup_io_limit_type_from_string(property);
160 if (type < 0 || l->limits[type] == cgroup_io_limit_defaults[type])
161 continue;
162
163 r = sd_bus_message_append(reply, "(st)", l->path, l->limits[type]);
164 if (r < 0)
165 return r;
166 }
167
168 return sd_bus_message_close_container(reply);
169 }
170
171 static int property_get_io_device_latency(
172 sd_bus *bus,
173 const char *path,
174 const char *interface,
175 const char *property,
176 sd_bus_message *reply,
177 void *userdata,
178 sd_bus_error *error) {
179
180 CGroupContext *c = userdata;
181 CGroupIODeviceLatency *l;
182 int r;
183
184 assert(bus);
185 assert(reply);
186 assert(c);
187
188 r = sd_bus_message_open_container(reply, 'a', "(st)");
189 if (r < 0)
190 return r;
191
192 LIST_FOREACH(device_latencies, l, c->io_device_latencies) {
193 r = sd_bus_message_append(reply, "(st)", l->path, l->target_usec);
194 if (r < 0)
195 return r;
196 }
197
198 return sd_bus_message_close_container(reply);
199 }
200
201 static int property_get_blockio_device_weight(
202 sd_bus *bus,
203 const char *path,
204 const char *interface,
205 const char *property,
206 sd_bus_message *reply,
207 void *userdata,
208 sd_bus_error *error) {
209
210 CGroupContext *c = userdata;
211 CGroupBlockIODeviceWeight *w;
212 int r;
213
214 assert(bus);
215 assert(reply);
216 assert(c);
217
218 r = sd_bus_message_open_container(reply, 'a', "(st)");
219 if (r < 0)
220 return r;
221
222 LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
223 r = sd_bus_message_append(reply, "(st)", w->path, w->weight);
224 if (r < 0)
225 return r;
226 }
227
228 return sd_bus_message_close_container(reply);
229 }
230
231 static int property_get_blockio_device_bandwidths(
232 sd_bus *bus,
233 const char *path,
234 const char *interface,
235 const char *property,
236 sd_bus_message *reply,
237 void *userdata,
238 sd_bus_error *error) {
239
240 CGroupContext *c = userdata;
241 CGroupBlockIODeviceBandwidth *b;
242 int r;
243
244 assert(bus);
245 assert(reply);
246 assert(c);
247
248 r = sd_bus_message_open_container(reply, 'a', "(st)");
249 if (r < 0)
250 return r;
251
252 LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
253 uint64_t v;
254
255 if (streq(property, "BlockIOReadBandwidth"))
256 v = b->rbps;
257 else
258 v = b->wbps;
259
260 if (v == CGROUP_LIMIT_MAX)
261 continue;
262
263 r = sd_bus_message_append(reply, "(st)", b->path, v);
264 if (r < 0)
265 return r;
266 }
267
268 return sd_bus_message_close_container(reply);
269 }
270
271 static int property_get_device_allow(
272 sd_bus *bus,
273 const char *path,
274 const char *interface,
275 const char *property,
276 sd_bus_message *reply,
277 void *userdata,
278 sd_bus_error *error) {
279
280 CGroupContext *c = userdata;
281 CGroupDeviceAllow *a;
282 int r;
283
284 assert(bus);
285 assert(reply);
286 assert(c);
287
288 r = sd_bus_message_open_container(reply, 'a', "(ss)");
289 if (r < 0)
290 return r;
291
292 LIST_FOREACH(device_allow, a, c->device_allow) {
293 unsigned k = 0;
294 char rwm[4];
295
296 if (a->r)
297 rwm[k++] = 'r';
298 if (a->w)
299 rwm[k++] = 'w';
300 if (a->m)
301 rwm[k++] = 'm';
302
303 rwm[k] = 0;
304
305 r = sd_bus_message_append(reply, "(ss)", a->path, rwm);
306 if (r < 0)
307 return r;
308 }
309
310 return sd_bus_message_close_container(reply);
311 }
312
313 static int property_get_ip_address_access(
314 sd_bus *bus,
315 const char *path,
316 const char *interface,
317 const char *property,
318 sd_bus_message *reply,
319 void *userdata,
320 sd_bus_error *error) {
321
322 Set **prefixes = userdata;
323 struct in_addr_prefix *i;
324 int r;
325
326 assert(prefixes);
327
328 r = sd_bus_message_open_container(reply, 'a', "(iayu)");
329 if (r < 0)
330 return r;
331
332 SET_FOREACH(i, *prefixes) {
333
334 r = sd_bus_message_open_container(reply, 'r', "iayu");
335 if (r < 0)
336 return r;
337
338 r = sd_bus_message_append(reply, "i", i->family);
339 if (r < 0)
340 return r;
341
342 r = sd_bus_message_append_array(reply, 'y', &i->address, FAMILY_ADDRESS_SIZE(i->family));
343 if (r < 0)
344 return r;
345
346 r = sd_bus_message_append(reply, "u", (uint32_t) i->prefixlen);
347 if (r < 0)
348 return r;
349
350 r = sd_bus_message_close_container(reply);
351 if (r < 0)
352 return r;
353 }
354
355 return sd_bus_message_close_container(reply);
356 }
357
358 static int property_get_bpf_foreign_program(
359 sd_bus *bus,
360 const char *path,
361 const char *interface,
362 const char *property,
363 sd_bus_message *reply,
364 void *userdata,
365 sd_bus_error *error) {
366 CGroupContext *c = userdata;
367 CGroupBPFForeignProgram *p;
368 int r;
369
370 r = sd_bus_message_open_container(reply, 'a', "(ss)");
371 if (r < 0)
372 return r;
373
374 LIST_FOREACH(programs, p, c->bpf_foreign_programs) {
375 const char *attach_type = bpf_cgroup_attach_type_to_string(p->attach_type);
376
377 r = sd_bus_message_append(reply, "(ss)", attach_type, p->bpffs_path);
378 if (r < 0)
379 return r;
380 }
381
382 return sd_bus_message_close_container(reply);
383 }
384
385 static int property_get_socket_bind(
386 sd_bus *bus,
387 const char *path,
388 const char *interface,
389 const char *property,
390 sd_bus_message *reply,
391 void *userdata,
392 sd_bus_error *error) {
393 CGroupSocketBindItem **items = userdata, *i;
394 int r;
395
396 assert(items);
397
398 r = sd_bus_message_open_container(reply, 'a', "(iiqq)");
399 if (r < 0)
400 return r;
401
402 LIST_FOREACH(socket_bind_items, i, *items) {
403 r = sd_bus_message_append(reply, "(iiqq)", i->address_family, i->ip_protocol, i->nr_ports, i->port_min);
404 if (r < 0)
405 return r;
406 }
407
408 return sd_bus_message_close_container(reply);
409 }
410
411 static int property_get_restrict_network_interfaces(
412 sd_bus *bus,
413 const char *path,
414 const char *interface,
415 const char *property,
416 sd_bus_message *reply,
417 void *userdata,
418 sd_bus_error *error) {
419 int r;
420 CGroupContext *c = userdata;
421 char *iface;
422
423 assert(bus);
424 assert(reply);
425 assert(c);
426
427 r = sd_bus_message_open_container(reply, 'r', "bas");
428 if (r < 0)
429 return r;
430
431 r = sd_bus_message_append(reply, "b", c->restrict_network_interfaces_is_allow_list);
432 if (r < 0)
433 return r;
434
435 r = sd_bus_message_open_container(reply, 'a', "s");
436 if (r < 0)
437 return r;
438
439 SET_FOREACH(iface, c->restrict_network_interfaces) {
440 r = sd_bus_message_append(reply, "s", iface);
441 if (r < 0)
442 return r;
443 }
444
445 r = sd_bus_message_close_container(reply);
446 if (r < 0)
447 return r;
448
449 return sd_bus_message_close_container(reply);
450 }
451
452 const sd_bus_vtable bus_cgroup_vtable[] = {
453 SD_BUS_VTABLE_START(0),
454 SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool, offsetof(CGroupContext, delegate), 0),
455 SD_BUS_PROPERTY("DelegateControllers", "as", property_get_delegate_controllers, 0, 0),
456 SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0),
457 SD_BUS_PROPERTY("CPUWeight", "t", NULL, offsetof(CGroupContext, cpu_weight), 0),
458 SD_BUS_PROPERTY("StartupCPUWeight", "t", NULL, offsetof(CGroupContext, startup_cpu_weight), 0),
459 SD_BUS_PROPERTY("CPUShares", "t", NULL, offsetof(CGroupContext, cpu_shares), 0),
460 SD_BUS_PROPERTY("StartupCPUShares", "t", NULL, offsetof(CGroupContext, startup_cpu_shares), 0),
461 SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0),
462 SD_BUS_PROPERTY("CPUQuotaPeriodUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_period_usec), 0),
463 SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_cpus), 0),
464 SD_BUS_PROPERTY("StartupAllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_cpus), 0),
465 SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_mems), 0),
466 SD_BUS_PROPERTY("StartupAllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_mems), 0),
467 SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0),
468 SD_BUS_PROPERTY("IOWeight", "t", NULL, offsetof(CGroupContext, io_weight), 0),
469 SD_BUS_PROPERTY("StartupIOWeight", "t", NULL, offsetof(CGroupContext, startup_io_weight), 0),
470 SD_BUS_PROPERTY("IODeviceWeight", "a(st)", property_get_io_device_weight, 0, 0),
471 SD_BUS_PROPERTY("IOReadBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
472 SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
473 SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
474 SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
475 SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency, 0, 0),
476 SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
477 SD_BUS_PROPERTY("BlockIOWeight", "t", NULL, offsetof(CGroupContext, blockio_weight), 0),
478 SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL, offsetof(CGroupContext, startup_blockio_weight), 0),
479 SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight, 0, 0),
480 SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
481 SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
482 SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
483 SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0),
484 SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL, offsetof(CGroupContext, default_memory_min), 0),
485 SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0),
486 SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0),
487 SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0),
488 SD_BUS_PROPERTY("MemoryMax", "t", NULL, offsetof(CGroupContext, memory_max), 0),
489 SD_BUS_PROPERTY("MemorySwapMax", "t", NULL, offsetof(CGroupContext, memory_swap_max), 0),
490 SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
491 SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
492 SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
493 SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, tasks_accounting), 0),
494 SD_BUS_PROPERTY("TasksMax", "t", bus_property_get_tasks_max, offsetof(CGroupContext, tasks_max), 0),
495 SD_BUS_PROPERTY("IPAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, ip_accounting), 0),
496 SD_BUS_PROPERTY("IPAddressAllow", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_allow), 0),
497 SD_BUS_PROPERTY("IPAddressDeny", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_deny), 0),
498 SD_BUS_PROPERTY("IPIngressFilterPath", "as", NULL, offsetof(CGroupContext, ip_filters_ingress), 0),
499 SD_BUS_PROPERTY("IPEgressFilterPath", "as", NULL, offsetof(CGroupContext, ip_filters_egress), 0),
500 SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask, offsetof(CGroupContext, disable_controllers), 0),
501 SD_BUS_PROPERTY("ManagedOOMSwap", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_swap), 0),
502 SD_BUS_PROPERTY("ManagedOOMMemoryPressure", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_mem_pressure), 0),
503 SD_BUS_PROPERTY("ManagedOOMMemoryPressureLimit", "u", NULL, offsetof(CGroupContext, moom_mem_pressure_limit), 0),
504 SD_BUS_PROPERTY("ManagedOOMPreference", "s", property_get_managed_oom_preference, offsetof(CGroupContext, moom_preference), 0),
505 SD_BUS_PROPERTY("BPFProgram", "a(ss)", property_get_bpf_foreign_program, 0, 0),
506 SD_BUS_PROPERTY("SocketBindAllow", "a(iiqq)", property_get_socket_bind, offsetof(CGroupContext, socket_bind_allow), 0),
507 SD_BUS_PROPERTY("SocketBindDeny", "a(iiqq)", property_get_socket_bind, offsetof(CGroupContext, socket_bind_deny), 0),
508 SD_BUS_PROPERTY("RestrictNetworkInterfaces", "(bas)", property_get_restrict_network_interfaces, 0, 0),
509 SD_BUS_VTABLE_END
510 };
511
512 static int bus_cgroup_set_transient_property(
513 Unit *u,
514 CGroupContext *c,
515 const char *name,
516 sd_bus_message *message,
517 UnitWriteFlags flags,
518 sd_bus_error *error) {
519
520 int r;
521
522 assert(u);
523 assert(c);
524 assert(name);
525 assert(message);
526
527 flags |= UNIT_PRIVATE;
528
529 if (streq(name, "Delegate")) {
530 int b;
531
532 if (!UNIT_VTABLE(u)->can_delegate)
533 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Delegation not available for unit type");
534
535 r = sd_bus_message_read(message, "b", &b);
536 if (r < 0)
537 return r;
538
539 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
540 c->delegate = b;
541 c->delegate_controllers = b ? _CGROUP_MASK_ALL : 0;
542
543 unit_write_settingf(u, flags, name, "Delegate=%s", yes_no(b));
544 }
545
546 return 1;
547
548 } else if (STR_IN_SET(name, "DelegateControllers", "DisableControllers")) {
549 CGroupMask mask = 0;
550
551 if (streq(name, "DelegateControllers") && !UNIT_VTABLE(u)->can_delegate)
552 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Delegation not available for unit type");
553
554 r = sd_bus_message_enter_container(message, 'a', "s");
555 if (r < 0)
556 return r;
557
558 for (;;) {
559 CGroupController cc;
560 const char *t;
561
562 r = sd_bus_message_read(message, "s", &t);
563 if (r < 0)
564 return r;
565 if (r == 0)
566 break;
567
568 cc = cgroup_controller_from_string(t);
569 if (cc < 0)
570 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown cgroup controller '%s'", t);
571
572 mask |= CGROUP_CONTROLLER_TO_MASK(cc);
573 }
574
575 r = sd_bus_message_exit_container(message);
576 if (r < 0)
577 return r;
578
579 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
580 _cleanup_free_ char *t = NULL;
581
582 r = cg_mask_to_string(mask, &t);
583 if (r < 0)
584 return r;
585
586 if (streq(name, "DelegateControllers")) {
587
588 c->delegate = true;
589 if (mask == 0)
590 c->delegate_controllers = 0;
591 else
592 c->delegate_controllers |= mask;
593
594 unit_write_settingf(u, flags, name, "Delegate=%s", strempty(t));
595
596 } else if (streq(name, "DisableControllers")) {
597
598 if (mask == 0)
599 c->disable_controllers = 0;
600 else
601 c->disable_controllers |= mask;
602
603 unit_write_settingf(u, flags, name, "%s=%s", name, strempty(t));
604 }
605 }
606
607 return 1;
608 } else if (STR_IN_SET(name, "IPIngressFilterPath", "IPEgressFilterPath")) {
609 char ***filters;
610 size_t n = 0;
611
612 filters = streq(name, "IPIngressFilterPath") ? &c->ip_filters_ingress : &c->ip_filters_egress;
613 r = sd_bus_message_enter_container(message, 'a', "s");
614 if (r < 0)
615 return r;
616
617 for (;;) {
618 const char *path;
619
620 r = sd_bus_message_read(message, "s", &path);
621 if (r < 0)
622 return r;
623 if (r == 0)
624 break;
625
626 if (!path_is_normalized(path) || !path_is_absolute(path))
627 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects a normalized absolute path.", name);
628
629 if (!UNIT_WRITE_FLAGS_NOOP(flags) && !strv_contains(*filters, path)) {
630 r = strv_extend(filters, path);
631 if (r < 0)
632 return log_oom();
633 }
634 n++;
635 }
636 r = sd_bus_message_exit_container(message);
637 if (r < 0)
638 return r;
639
640 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
641 _cleanup_free_ char *buf = NULL;
642 _cleanup_fclose_ FILE *f = NULL;
643 char **entry;
644 size_t size = 0;
645
646 if (n == 0)
647 *filters = strv_free(*filters);
648
649 unit_invalidate_cgroup_bpf(u);
650 f = open_memstream_unlocked(&buf, &size);
651 if (!f)
652 return -ENOMEM;
653
654 fputs(name, f);
655 fputs("=\n", f);
656
657 STRV_FOREACH(entry, *filters)
658 fprintf(f, "%s=%s\n", name, *entry);
659
660 r = fflush_and_check(f);
661 if (r < 0)
662 return r;
663
664 unit_write_setting(u, flags, name, buf);
665
666 if (*filters) {
667 r = bpf_firewall_supported();
668 if (r < 0)
669 return r;
670 if (r != BPF_FIREWALL_SUPPORTED_WITH_MULTI) {
671 static bool warned = false;
672
673 log_full(warned ? LOG_DEBUG : LOG_WARNING,
674 "Transient unit %s configures an IP firewall with BPF, but the local system does not support BPF/cgroup firewalling with multiple filters.\n"
675 "Starting this unit will fail! (This warning is only shown for the first started transient unit using IP firewalling.)", u->id);
676 warned = true;
677 }
678 }
679 }
680
681 return 1;
682 } else if (streq(name, "BPFProgram")) {
683 const char *a, *p;
684 size_t n = 0;
685
686 r = sd_bus_message_enter_container(message, 'a', "(ss)");
687 if (r < 0)
688 return r;
689
690 while ((r = sd_bus_message_read(message, "(ss)", &a, &p)) > 0) {
691 int attach_type = bpf_cgroup_attach_type_from_string(a);
692 if (attach_type < 0)
693 return sd_bus_error_setf(
694 error,
695 SD_BUS_ERROR_INVALID_ARGS,
696 "%s expects a valid BPF attach type, got '%s'.",
697 name, a);
698
699 if (!path_is_normalized(p) || !path_is_absolute(p))
700 return sd_bus_error_setf(
701 error,
702 SD_BUS_ERROR_INVALID_ARGS,
703 "%s= expects a normalized absolute path.",
704 name);
705
706 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
707 r = cgroup_add_bpf_foreign_program(c, attach_type, p);
708 if (r < 0)
709 return r;
710 }
711 n++;
712 }
713 if (r < 0)
714 return r;
715
716 r = sd_bus_message_exit_container(message);
717 if (r < 0)
718 return r;
719
720 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
721 _cleanup_free_ char *buf = NULL;
722 _cleanup_fclose_ FILE *f = NULL;
723 CGroupBPFForeignProgram *fp;
724 size_t size = 0;
725
726 if (n == 0)
727 while (c->bpf_foreign_programs)
728 cgroup_context_remove_bpf_foreign_program(c, c->bpf_foreign_programs);
729
730 f = open_memstream_unlocked(&buf, &size);
731 if (!f)
732 return -ENOMEM;
733
734 fputs(name, f);
735 fputs("=\n", f);
736
737 LIST_FOREACH(programs, fp, c->bpf_foreign_programs)
738 fprintf(f, "%s=%s:%s\n", name,
739 bpf_cgroup_attach_type_to_string(fp->attach_type),
740 fp->bpffs_path);
741
742 r = fflush_and_check(f);
743 if (r < 0)
744 return r;
745
746 unit_write_setting(u, flags, name, buf);
747
748 if (!LIST_IS_EMPTY(c->bpf_foreign_programs)) {
749 r = bpf_foreign_supported();
750 if (r < 0)
751 return r;
752 if (r == 0)
753 log_full(LOG_DEBUG,
754 "Transient unit %s configures a BPF program pinned to BPF "
755 "filesystem, but the local system does not support that.\n"
756 "Starting this unit will fail!", u->id);
757 }
758 }
759
760 return 1;
761 }
762
763 return 0;
764 }
765
766 static int bus_cgroup_set_boolean(
767 Unit *u,
768 const char *name,
769 bool *p,
770 CGroupMask mask,
771 sd_bus_message *message,
772 UnitWriteFlags flags,
773 sd_bus_error *error) {
774
775 int b, r;
776
777 assert(p);
778
779 r = sd_bus_message_read(message, "b", &b);
780 if (r < 0)
781 return r;
782
783 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
784 *p = b;
785 unit_invalidate_cgroup(u, mask);
786 unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
787 }
788
789 return 1;
790 }
791
792 #define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val) \
793 static int bus_cgroup_set_##function( \
794 Unit *u, \
795 const char *name, \
796 uint64_t *p, \
797 sd_bus_message *message, \
798 UnitWriteFlags flags, \
799 sd_bus_error *error) { \
800 \
801 uint64_t v; \
802 int r; \
803 \
804 assert(p); \
805 \
806 r = sd_bus_message_read(message, "t", &v); \
807 if (r < 0) \
808 return r; \
809 \
810 if (!check(v)) \
811 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
812 "Value specified in %s is out of range", name); \
813 \
814 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
815 *p = v; \
816 unit_invalidate_cgroup(u, mask); \
817 \
818 if (v == (val)) \
819 unit_write_settingf(u, flags, name, \
820 "%s=", name); \
821 else \
822 unit_write_settingf(u, flags, name, \
823 "%s=%" PRIu64, name, v); \
824 } \
825 \
826 return 1; \
827 }
828
829 #define BUS_DEFINE_SET_CGROUP_LIMIT(function, mask, scale, minimum) \
830 static int bus_cgroup_set_##function( \
831 Unit *u, \
832 const char *name, \
833 uint64_t *p, \
834 sd_bus_message *message, \
835 UnitWriteFlags flags, \
836 sd_bus_error *error) { \
837 \
838 uint64_t v; \
839 int r; \
840 \
841 assert(p); \
842 \
843 r = sd_bus_message_read(message, "t", &v); \
844 if (r < 0) \
845 return r; \
846 \
847 if (v < minimum) \
848 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
849 "Value specified in %s is out of range", name); \
850 \
851 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
852 *p = v; \
853 unit_invalidate_cgroup(u, mask); \
854 \
855 if (v == CGROUP_LIMIT_MAX) \
856 unit_write_settingf(u, flags, name, \
857 "%s=infinity", name); \
858 else \
859 unit_write_settingf(u, flags, name, \
860 "%s=%" PRIu64, name, v); \
861 } \
862 \
863 return 1; \
864 } \
865 static int bus_cgroup_set_##function##_scale( \
866 Unit *u, \
867 const char *name, \
868 uint64_t *p, \
869 sd_bus_message *message, \
870 UnitWriteFlags flags, \
871 sd_bus_error *error) { \
872 \
873 uint64_t v; \
874 uint32_t raw; \
875 int r; \
876 \
877 assert(p); \
878 \
879 r = sd_bus_message_read(message, "u", &raw); \
880 if (r < 0) \
881 return r; \
882 \
883 v = scale(raw, UINT32_MAX); \
884 if (v < minimum || v >= UINT64_MAX) \
885 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
886 "Value specified in %s is out of range", name); \
887 \
888 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
889 *p = v; \
890 unit_invalidate_cgroup(u, mask); \
891 \
892 /* Prepare to chop off suffix */ \
893 assert_se(endswith(name, "Scale")); \
894 \
895 int scaled = UINT32_SCALE_TO_PERMYRIAD(raw); \
896 unit_write_settingf(u, flags, name, "%.*s=" PERMYRIAD_AS_PERCENT_FORMAT_STR, \
897 (int)(strlen(name) - strlen("Scale")), name, \
898 PERMYRIAD_AS_PERCENT_FORMAT_VAL(scaled)); \
899 } \
900 \
901 return 1; \
902 }
903
904 DISABLE_WARNING_TYPE_LIMITS;
905 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
906 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID);
907 BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
908 BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID);
909 BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1);
910 BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
911 BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
912 REENABLE_WARNING;
913
914 static int bus_cgroup_set_tasks_max(
915 Unit *u,
916 const char *name,
917 TasksMax *p,
918 sd_bus_message *message,
919 UnitWriteFlags flags,
920 sd_bus_error *error) {
921
922 uint64_t v;
923 int r;
924
925 assert(p);
926
927 r = sd_bus_message_read(message, "t", &v);
928 if (r < 0)
929 return r;
930
931 if (v < 1)
932 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
933 "Value specified in %s is out of range", name);
934
935 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
936 *p = (TasksMax) { .value = v, .scale = 0 }; /* When .scale==0, .value is the absolute value */
937 unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
938
939 if (v == CGROUP_LIMIT_MAX)
940 unit_write_settingf(u, flags, name,
941 "%s=infinity", name);
942 else
943 unit_write_settingf(u, flags, name,
944 "%s=%" PRIu64, name, v);
945 }
946
947 return 1;
948 }
949
950 static int bus_cgroup_set_tasks_max_scale(
951 Unit *u,
952 const char *name,
953 TasksMax *p,
954 sd_bus_message *message,
955 UnitWriteFlags flags,
956 sd_bus_error *error) {
957
958 uint32_t v;
959 int r;
960
961 assert(p);
962
963 r = sd_bus_message_read(message, "u", &v);
964 if (r < 0)
965 return r;
966
967 if (v < 1 || v >= UINT32_MAX)
968 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
969 "Value specified in %s is out of range", name);
970
971 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
972 *p = (TasksMax) { v, UINT32_MAX }; /* .scale is not 0, so this is interpreted as v/UINT32_MAX. */
973 unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
974
975 uint32_t scaled = DIV_ROUND_UP((uint64_t) v * 100U, (uint64_t) UINT32_MAX);
976 unit_write_settingf(u, flags, name, "%s=%" PRIu32 ".%" PRIu32 "%%", "TasksMax",
977 scaled / 10, scaled % 10);
978 }
979
980 return 1;
981 }
982
983 int bus_cgroup_set_property(
984 Unit *u,
985 CGroupContext *c,
986 const char *name,
987 sd_bus_message *message,
988 UnitWriteFlags flags,
989 sd_bus_error *error) {
990
991 CGroupIOLimitType iol_type;
992 int r;
993
994 assert(u);
995 assert(c);
996 assert(name);
997 assert(message);
998
999 flags |= UNIT_PRIVATE;
1000
1001 if (streq(name, "CPUAccounting"))
1002 return bus_cgroup_set_boolean(u, name, &c->cpu_accounting, get_cpu_accounting_mask(), message, flags, error);
1003
1004 if (streq(name, "CPUWeight"))
1005 return bus_cgroup_set_cpu_weight(u, name, &c->cpu_weight, message, flags, error);
1006
1007 if (streq(name, "StartupCPUWeight"))
1008 return bus_cgroup_set_cpu_weight(u, name, &c->startup_cpu_weight, message, flags, error);
1009
1010 if (streq(name, "CPUShares"))
1011 return bus_cgroup_set_cpu_shares(u, name, &c->cpu_shares, message, flags, error);
1012
1013 if (streq(name, "StartupCPUShares"))
1014 return bus_cgroup_set_cpu_shares(u, name, &c->startup_cpu_shares, message, flags, error);
1015
1016 if (streq(name, "IOAccounting"))
1017 return bus_cgroup_set_boolean(u, name, &c->io_accounting, CGROUP_MASK_IO, message, flags, error);
1018
1019 if (streq(name, "IOWeight"))
1020 return bus_cgroup_set_io_weight(u, name, &c->io_weight, message, flags, error);
1021
1022 if (streq(name, "StartupIOWeight"))
1023 return bus_cgroup_set_io_weight(u, name, &c->startup_io_weight, message, flags, error);
1024
1025 if (streq(name, "BlockIOAccounting"))
1026 return bus_cgroup_set_boolean(u, name, &c->blockio_accounting, CGROUP_MASK_BLKIO, message, flags, error);
1027
1028 if (streq(name, "BlockIOWeight"))
1029 return bus_cgroup_set_blockio_weight(u, name, &c->blockio_weight, message, flags, error);
1030
1031 if (streq(name, "StartupBlockIOWeight"))
1032 return bus_cgroup_set_blockio_weight(u, name, &c->startup_blockio_weight, message, flags, error);
1033
1034 if (streq(name, "MemoryAccounting"))
1035 return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error);
1036
1037 if (streq(name, "MemoryMin")) {
1038 r = bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, error);
1039 if (r > 0)
1040 c->memory_min_set = true;
1041 return r;
1042 }
1043
1044 if (streq(name, "MemoryLow")) {
1045 r = bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, error);
1046 if (r > 0)
1047 c->memory_low_set = true;
1048 return r;
1049 }
1050
1051 if (streq(name, "DefaultMemoryMin")) {
1052 r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error);
1053 if (r > 0)
1054 c->default_memory_min_set = true;
1055 return r;
1056 }
1057
1058 if (streq(name, "DefaultMemoryLow")) {
1059 r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, error);
1060 if (r > 0)
1061 c->default_memory_low_set = true;
1062 return r;
1063 }
1064
1065 if (streq(name, "MemoryHigh"))
1066 return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error);
1067
1068 if (streq(name, "MemorySwapMax"))
1069 return bus_cgroup_set_swap(u, name, &c->memory_swap_max, message, flags, error);
1070
1071 if (streq(name, "MemoryMax"))
1072 return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error);
1073
1074 if (streq(name, "MemoryLimit"))
1075 return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error);
1076
1077 if (streq(name, "MemoryMinScale")) {
1078 r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error);
1079 if (r > 0)
1080 c->memory_min_set = true;
1081 return r;
1082 }
1083
1084 if (streq(name, "MemoryLowScale")) {
1085 r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, error);
1086 if (r > 0)
1087 c->memory_low_set = true;
1088 return r;
1089 }
1090
1091 if (streq(name, "DefaultMemoryMinScale")) {
1092 r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, error);
1093 if (r > 0)
1094 c->default_memory_min_set = true;
1095 return r;
1096 }
1097
1098 if (streq(name, "DefaultMemoryLowScale")) {
1099 r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, error);
1100 if (r > 0)
1101 c->default_memory_low_set = true;
1102 return r;
1103 }
1104
1105 if (streq(name, "MemoryHighScale"))
1106 return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error);
1107
1108 if (streq(name, "MemorySwapMaxScale"))
1109 return bus_cgroup_set_swap_scale(u, name, &c->memory_swap_max, message, flags, error);
1110
1111 if (streq(name, "MemoryMaxScale"))
1112 return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error);
1113
1114 if (streq(name, "MemoryLimitScale"))
1115 return bus_cgroup_set_memory_scale(u, name, &c->memory_limit, message, flags, error);
1116
1117 if (streq(name, "TasksAccounting"))
1118 return bus_cgroup_set_boolean(u, name, &c->tasks_accounting, CGROUP_MASK_PIDS, message, flags, error);
1119
1120 if (streq(name, "TasksMax"))
1121 return bus_cgroup_set_tasks_max(u, name, &c->tasks_max, message, flags, error);
1122
1123 if (streq(name, "TasksMaxScale"))
1124 return bus_cgroup_set_tasks_max_scale(u, name, &c->tasks_max, message, flags, error);
1125
1126 if (streq(name, "CPUQuotaPerSecUSec")) {
1127 uint64_t u64;
1128
1129 r = sd_bus_message_read(message, "t", &u64);
1130 if (r < 0)
1131 return r;
1132
1133 if (u64 <= 0)
1134 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "CPUQuotaPerSecUSec= value out of range");
1135
1136 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1137 c->cpu_quota_per_sec_usec = u64;
1138 u->warned_clamping_cpu_quota_period = false;
1139 unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
1140
1141 if (c->cpu_quota_per_sec_usec == USEC_INFINITY)
1142 unit_write_setting(u, flags, "CPUQuota", "CPUQuota=");
1143 else
1144 /* config_parse_cpu_quota() requires an integer, so truncating division is used on
1145 * purpose here. */
1146 unit_write_settingf(u, flags, "CPUQuota",
1147 "CPUQuota=%0.f%%",
1148 (double) (c->cpu_quota_per_sec_usec / 10000));
1149 }
1150
1151 return 1;
1152
1153 } else if (streq(name, "CPUQuotaPeriodUSec")) {
1154 uint64_t u64;
1155
1156 r = sd_bus_message_read(message, "t", &u64);
1157 if (r < 0)
1158 return r;
1159
1160 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1161 c->cpu_quota_period_usec = u64;
1162 u->warned_clamping_cpu_quota_period = false;
1163 unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
1164 if (c->cpu_quota_period_usec == USEC_INFINITY)
1165 unit_write_setting(u, flags, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec=");
1166 else
1167 unit_write_settingf(u, flags, "CPUQuotaPeriodSec",
1168 "CPUQuotaPeriodSec=%s",
1169 FORMAT_TIMESPAN(c->cpu_quota_period_usec, 1));
1170 }
1171
1172 return 1;
1173
1174 } else if (STR_IN_SET(name, "AllowedCPUs", "StartupAllowedCPUs", "AllowedMemoryNodes", "StartupAllowedMemoryNodes")) {
1175 const void *a;
1176 size_t n;
1177 _cleanup_(cpu_set_reset) CPUSet new_set = {};
1178
1179 r = sd_bus_message_read_array(message, 'y', &a, &n);
1180 if (r < 0)
1181 return r;
1182
1183 r = cpu_set_from_dbus(a, n, &new_set);
1184 if (r < 0)
1185 return r;
1186
1187 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1188 _cleanup_free_ char *setstr = NULL;
1189 CPUSet *set = NULL;
1190
1191 setstr = cpu_set_to_range_string(&new_set);
1192 if (!setstr)
1193 return -ENOMEM;
1194
1195 if (streq(name, "AllowedCPUs"))
1196 set = &c->cpuset_cpus;
1197 else if (streq(name, "StartupAllowedCPUs"))
1198 set = &c->startup_cpuset_cpus;
1199 else if (streq(name, "AllowedMemoryNodes"))
1200 set = &c->cpuset_mems;
1201 else if (streq(name, "StartupAllowedMemoryNodes"))
1202 set = &c->startup_cpuset_mems;
1203
1204 assert(set);
1205
1206 cpu_set_reset(set);
1207 *set = new_set;
1208 new_set = (CPUSet) {};
1209
1210 unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET);
1211 unit_write_settingf(u, flags, name, "%s=%s", name, setstr);
1212 }
1213
1214 return 1;
1215
1216 } else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) {
1217 const char *path;
1218 unsigned n = 0;
1219 uint64_t u64;
1220
1221 r = sd_bus_message_enter_container(message, 'a', "(st)");
1222 if (r < 0)
1223 return r;
1224
1225 while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
1226
1227 if (!path_is_normalized(path))
1228 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
1229
1230 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1231 CGroupIODeviceLimit *a = NULL, *b;
1232
1233 LIST_FOREACH(device_limits, b, c->io_device_limits) {
1234 if (path_equal(path, b->path)) {
1235 a = b;
1236 break;
1237 }
1238 }
1239
1240 if (!a) {
1241 CGroupIOLimitType type;
1242
1243 a = new0(CGroupIODeviceLimit, 1);
1244 if (!a)
1245 return -ENOMEM;
1246
1247 a->path = strdup(path);
1248 if (!a->path) {
1249 free(a);
1250 return -ENOMEM;
1251 }
1252
1253 for (type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++)
1254 a->limits[type] = cgroup_io_limit_defaults[type];
1255
1256 LIST_PREPEND(device_limits, c->io_device_limits, a);
1257 }
1258
1259 a->limits[iol_type] = u64;
1260 }
1261
1262 n++;
1263 }
1264 if (r < 0)
1265 return r;
1266
1267 r = sd_bus_message_exit_container(message);
1268 if (r < 0)
1269 return r;
1270
1271 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1272 CGroupIODeviceLimit *a;
1273 _cleanup_free_ char *buf = NULL;
1274 _cleanup_fclose_ FILE *f = NULL;
1275 size_t size = 0;
1276
1277 if (n == 0) {
1278 LIST_FOREACH(device_limits, a, c->io_device_limits)
1279 a->limits[iol_type] = cgroup_io_limit_defaults[iol_type];
1280 }
1281
1282 unit_invalidate_cgroup(u, CGROUP_MASK_IO);
1283
1284 f = open_memstream_unlocked(&buf, &size);
1285 if (!f)
1286 return -ENOMEM;
1287
1288 fprintf(f, "%s=\n", name);
1289 LIST_FOREACH(device_limits, a, c->io_device_limits)
1290 if (a->limits[iol_type] != cgroup_io_limit_defaults[iol_type])
1291 fprintf(f, "%s=%s %" PRIu64 "\n", name, a->path, a->limits[iol_type]);
1292
1293 r = fflush_and_check(f);
1294 if (r < 0)
1295 return r;
1296 unit_write_setting(u, flags, name, buf);
1297 }
1298
1299 return 1;
1300
1301 } else if (streq(name, "IODeviceWeight")) {
1302 const char *path;
1303 uint64_t weight;
1304 unsigned n = 0;
1305
1306 r = sd_bus_message_enter_container(message, 'a', "(st)");
1307 if (r < 0)
1308 return r;
1309
1310 while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) {
1311
1312 if (!path_is_normalized(path))
1313 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
1314
1315 if (!CGROUP_WEIGHT_IS_OK(weight) || weight == CGROUP_WEIGHT_INVALID)
1316 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "IODeviceWeight= value out of range");
1317
1318 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1319 CGroupIODeviceWeight *a = NULL, *b;
1320
1321 LIST_FOREACH(device_weights, b, c->io_device_weights) {
1322 if (path_equal(b->path, path)) {
1323 a = b;
1324 break;
1325 }
1326 }
1327
1328 if (!a) {
1329 a = new0(CGroupIODeviceWeight, 1);
1330 if (!a)
1331 return -ENOMEM;
1332
1333 a->path = strdup(path);
1334 if (!a->path) {
1335 free(a);
1336 return -ENOMEM;
1337 }
1338 LIST_PREPEND(device_weights, c->io_device_weights, a);
1339 }
1340
1341 a->weight = weight;
1342 }
1343
1344 n++;
1345 }
1346
1347 r = sd_bus_message_exit_container(message);
1348 if (r < 0)
1349 return r;
1350
1351 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1352 _cleanup_free_ char *buf = NULL;
1353 _cleanup_fclose_ FILE *f = NULL;
1354 CGroupIODeviceWeight *a;
1355 size_t size = 0;
1356
1357 if (n == 0) {
1358 while (c->io_device_weights)
1359 cgroup_context_free_io_device_weight(c, c->io_device_weights);
1360 }
1361
1362 unit_invalidate_cgroup(u, CGROUP_MASK_IO);
1363
1364 f = open_memstream_unlocked(&buf, &size);
1365 if (!f)
1366 return -ENOMEM;
1367
1368 fputs("IODeviceWeight=\n", f);
1369 LIST_FOREACH(device_weights, a, c->io_device_weights)
1370 fprintf(f, "IODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight);
1371
1372 r = fflush_and_check(f);
1373 if (r < 0)
1374 return r;
1375 unit_write_setting(u, flags, name, buf);
1376 }
1377
1378 return 1;
1379
1380 } else if (streq(name, "IODeviceLatencyTargetUSec")) {
1381 const char *path;
1382 uint64_t target;
1383 unsigned n = 0;
1384
1385 r = sd_bus_message_enter_container(message, 'a', "(st)");
1386 if (r < 0)
1387 return r;
1388
1389 while ((r = sd_bus_message_read(message, "(st)", &path, &target)) > 0) {
1390
1391 if (!path_is_normalized(path))
1392 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
1393
1394 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1395 CGroupIODeviceLatency *a = NULL, *b;
1396
1397 LIST_FOREACH(device_latencies, b, c->io_device_latencies) {
1398 if (path_equal(b->path, path)) {
1399 a = b;
1400 break;
1401 }
1402 }
1403
1404 if (!a) {
1405 a = new0(CGroupIODeviceLatency, 1);
1406 if (!a)
1407 return -ENOMEM;
1408
1409 a->path = strdup(path);
1410 if (!a->path) {
1411 free(a);
1412 return -ENOMEM;
1413 }
1414 LIST_PREPEND(device_latencies, c->io_device_latencies, a);
1415 }
1416
1417 a->target_usec = target;
1418 }
1419
1420 n++;
1421 }
1422
1423 r = sd_bus_message_exit_container(message);
1424 if (r < 0)
1425 return r;
1426
1427 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1428 _cleanup_free_ char *buf = NULL;
1429 _cleanup_fclose_ FILE *f = NULL;
1430 CGroupIODeviceLatency *a;
1431 size_t size = 0;
1432
1433 if (n == 0) {
1434 while (c->io_device_latencies)
1435 cgroup_context_free_io_device_latency(c, c->io_device_latencies);
1436 }
1437
1438 unit_invalidate_cgroup(u, CGROUP_MASK_IO);
1439
1440 f = open_memstream_unlocked(&buf, &size);
1441 if (!f)
1442 return -ENOMEM;
1443
1444 fputs("IODeviceLatencyTargetSec=\n", f);
1445 LIST_FOREACH(device_latencies, a, c->io_device_latencies)
1446 fprintf(f, "IODeviceLatencyTargetSec=%s %s\n",
1447 a->path, FORMAT_TIMESPAN(a->target_usec, 1));
1448
1449 r = fflush_and_check(f);
1450 if (r < 0)
1451 return r;
1452 unit_write_setting(u, flags, name, buf);
1453 }
1454
1455 return 1;
1456
1457 } else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1458 const char *path;
1459 bool read = true;
1460 unsigned n = 0;
1461 uint64_t u64;
1462
1463 if (streq(name, "BlockIOWriteBandwidth"))
1464 read = false;
1465
1466 r = sd_bus_message_enter_container(message, 'a', "(st)");
1467 if (r < 0)
1468 return r;
1469
1470 while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
1471
1472 if (!path_is_normalized(path))
1473 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
1474
1475 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1476 CGroupBlockIODeviceBandwidth *a = NULL, *b;
1477
1478 LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
1479 if (path_equal(path, b->path)) {
1480 a = b;
1481 break;
1482 }
1483 }
1484
1485 if (!a) {
1486 a = new0(CGroupBlockIODeviceBandwidth, 1);
1487 if (!a)
1488 return -ENOMEM;
1489
1490 a->rbps = CGROUP_LIMIT_MAX;
1491 a->wbps = CGROUP_LIMIT_MAX;
1492 a->path = strdup(path);
1493 if (!a->path) {
1494 free(a);
1495 return -ENOMEM;
1496 }
1497
1498 LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
1499 }
1500
1501 if (read)
1502 a->rbps = u64;
1503 else
1504 a->wbps = u64;
1505 }
1506
1507 n++;
1508 }
1509 if (r < 0)
1510 return r;
1511
1512 r = sd_bus_message_exit_container(message);
1513 if (r < 0)
1514 return r;
1515
1516 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1517 CGroupBlockIODeviceBandwidth *a;
1518 _cleanup_free_ char *buf = NULL;
1519 _cleanup_fclose_ FILE *f = NULL;
1520 size_t size = 0;
1521
1522 if (n == 0) {
1523 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) {
1524 if (read)
1525 a->rbps = CGROUP_LIMIT_MAX;
1526 else
1527 a->wbps = CGROUP_LIMIT_MAX;
1528 }
1529 }
1530
1531 unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
1532
1533 f = open_memstream_unlocked(&buf, &size);
1534 if (!f)
1535 return -ENOMEM;
1536
1537 if (read) {
1538 fputs("BlockIOReadBandwidth=\n", f);
1539 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
1540 if (a->rbps != CGROUP_LIMIT_MAX)
1541 fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->rbps);
1542 } else {
1543 fputs("BlockIOWriteBandwidth=\n", f);
1544 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
1545 if (a->wbps != CGROUP_LIMIT_MAX)
1546 fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->wbps);
1547 }
1548
1549 r = fflush_and_check(f);
1550 if (r < 0)
1551 return r;
1552
1553 unit_write_setting(u, flags, name, buf);
1554 }
1555
1556 return 1;
1557
1558 } else if (streq(name, "BlockIODeviceWeight")) {
1559 const char *path;
1560 uint64_t weight;
1561 unsigned n = 0;
1562
1563 r = sd_bus_message_enter_container(message, 'a', "(st)");
1564 if (r < 0)
1565 return r;
1566
1567 while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) {
1568
1569 if (!path_is_normalized(path))
1570 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
1571
1572 if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight) || weight == CGROUP_BLKIO_WEIGHT_INVALID)
1573 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIODeviceWeight= out of range");
1574
1575 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1576 CGroupBlockIODeviceWeight *a = NULL, *b;
1577
1578 LIST_FOREACH(device_weights, b, c->blockio_device_weights) {
1579 if (path_equal(b->path, path)) {
1580 a = b;
1581 break;
1582 }
1583 }
1584
1585 if (!a) {
1586 a = new0(CGroupBlockIODeviceWeight, 1);
1587 if (!a)
1588 return -ENOMEM;
1589
1590 a->path = strdup(path);
1591 if (!a->path) {
1592 free(a);
1593 return -ENOMEM;
1594 }
1595 LIST_PREPEND(device_weights, c->blockio_device_weights, a);
1596 }
1597
1598 a->weight = weight;
1599 }
1600
1601 n++;
1602 }
1603
1604 r = sd_bus_message_exit_container(message);
1605 if (r < 0)
1606 return r;
1607
1608 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1609 _cleanup_free_ char *buf = NULL;
1610 _cleanup_fclose_ FILE *f = NULL;
1611 CGroupBlockIODeviceWeight *a;
1612 size_t size = 0;
1613
1614 if (n == 0) {
1615 while (c->blockio_device_weights)
1616 cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
1617 }
1618
1619 unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
1620
1621 f = open_memstream_unlocked(&buf, &size);
1622 if (!f)
1623 return -ENOMEM;
1624
1625 fputs("BlockIODeviceWeight=\n", f);
1626 LIST_FOREACH(device_weights, a, c->blockio_device_weights)
1627 fprintf(f, "BlockIODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight);
1628
1629 r = fflush_and_check(f);
1630 if (r < 0)
1631 return r;
1632
1633 unit_write_setting(u, flags, name, buf);
1634 }
1635
1636 return 1;
1637
1638 } else if (streq(name, "DevicePolicy")) {
1639 const char *policy;
1640 CGroupDevicePolicy p;
1641
1642 r = sd_bus_message_read(message, "s", &policy);
1643 if (r < 0)
1644 return r;
1645
1646 p = cgroup_device_policy_from_string(policy);
1647 if (p < 0)
1648 return p;
1649
1650 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1651 c->device_policy = p;
1652 unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES);
1653 unit_write_settingf(u, flags, name, "DevicePolicy=%s", policy);
1654 }
1655
1656 return 1;
1657
1658 } else if (streq(name, "DeviceAllow")) {
1659 const char *path, *rwm;
1660 unsigned n = 0;
1661
1662 r = sd_bus_message_enter_container(message, 'a', "(ss)");
1663 if (r < 0)
1664 return r;
1665
1666 while ((r = sd_bus_message_read(message, "(ss)", &path, &rwm)) > 0) {
1667
1668 if (!valid_device_allow_pattern(path) || strpbrk(path, WHITESPACE))
1669 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node or pattern");
1670
1671 if (isempty(rwm))
1672 rwm = "rwm";
1673 else if (!in_charset(rwm, "rwm"))
1674 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags");
1675
1676 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1677 CGroupDeviceAllow *a = NULL, *b;
1678
1679 LIST_FOREACH(device_allow, b, c->device_allow) {
1680 if (path_equal(b->path, path)) {
1681 a = b;
1682 break;
1683 }
1684 }
1685
1686 if (!a) {
1687 a = new0(CGroupDeviceAllow, 1);
1688 if (!a)
1689 return -ENOMEM;
1690
1691 a->path = strdup(path);
1692 if (!a->path) {
1693 free(a);
1694 return -ENOMEM;
1695 }
1696
1697 LIST_PREPEND(device_allow, c->device_allow, a);
1698 }
1699
1700 a->r = strchr(rwm, 'r');
1701 a->w = strchr(rwm, 'w');
1702 a->m = strchr(rwm, 'm');
1703 }
1704
1705 n++;
1706 }
1707 if (r < 0)
1708 return r;
1709
1710 r = sd_bus_message_exit_container(message);
1711 if (r < 0)
1712 return r;
1713
1714 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1715 _cleanup_free_ char *buf = NULL;
1716 _cleanup_fclose_ FILE *f = NULL;
1717 CGroupDeviceAllow *a;
1718 size_t size = 0;
1719
1720 if (n == 0) {
1721 while (c->device_allow)
1722 cgroup_context_free_device_allow(c, c->device_allow);
1723 }
1724
1725 unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES);
1726
1727 f = open_memstream_unlocked(&buf, &size);
1728 if (!f)
1729 return -ENOMEM;
1730
1731 fputs("DeviceAllow=\n", f);
1732 LIST_FOREACH(device_allow, a, c->device_allow)
1733 fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
1734
1735 r = fflush_and_check(f);
1736 if (r < 0)
1737 return r;
1738 unit_write_setting(u, flags, name, buf);
1739 }
1740
1741 return 1;
1742
1743 } else if (streq(name, "IPAccounting")) {
1744 int b;
1745
1746 r = sd_bus_message_read(message, "b", &b);
1747 if (r < 0)
1748 return r;
1749
1750 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1751 c->ip_accounting = b;
1752
1753 unit_invalidate_cgroup_bpf(u);
1754 unit_write_settingf(u, flags, name, "IPAccounting=%s", yes_no(b));
1755 }
1756
1757 return 1;
1758
1759 } else if (STR_IN_SET(name, "IPAddressAllow", "IPAddressDeny")) {
1760 _cleanup_set_free_ Set *new_prefixes = NULL;
1761 size_t n = 0;
1762
1763 r = sd_bus_message_enter_container(message, 'a', "(iayu)");
1764 if (r < 0)
1765 return r;
1766
1767 for (;;) {
1768 const void *ap;
1769 int32_t family;
1770 uint32_t prefixlen;
1771 size_t an;
1772
1773 r = sd_bus_message_enter_container(message, 'r', "iayu");
1774 if (r < 0)
1775 return r;
1776 if (r == 0)
1777 break;
1778
1779 r = sd_bus_message_read(message, "i", &family);
1780 if (r < 0)
1781 return r;
1782
1783 if (!IN_SET(family, AF_INET, AF_INET6))
1784 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects IPv4 or IPv6 addresses only.", name);
1785
1786 r = sd_bus_message_read_array(message, 'y', &ap, &an);
1787 if (r < 0)
1788 return r;
1789
1790 if (an != FAMILY_ADDRESS_SIZE(family))
1791 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IP address has wrong size for family (%s, expected %zu, got %zu)",
1792 af_to_name(family), FAMILY_ADDRESS_SIZE(family), an);
1793
1794 r = sd_bus_message_read(message, "u", &prefixlen);
1795 if (r < 0)
1796 return r;
1797
1798 if (prefixlen > FAMILY_ADDRESS_SIZE(family)*8)
1799 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Prefix length %" PRIu32 " too large for address family %s.", prefixlen, af_to_name(family));
1800
1801 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1802 struct in_addr_prefix prefix = {
1803 .family = family,
1804 .prefixlen = prefixlen,
1805 };
1806
1807 memcpy(&prefix.address, ap, an);
1808
1809 r = in_addr_prefix_add(&new_prefixes, &prefix);
1810 if (r < 0)
1811 return r;
1812 }
1813
1814 r = sd_bus_message_exit_container(message);
1815 if (r < 0)
1816 return r;
1817
1818 n++;
1819 }
1820
1821 r = sd_bus_message_exit_container(message);
1822 if (r < 0)
1823 return r;
1824
1825 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1826 _cleanup_free_ char *buf = NULL;
1827 _cleanup_fclose_ FILE *f = NULL;
1828 size_t size = 0;
1829 Set **prefixes;
1830 bool *reduced;
1831
1832 unit_invalidate_cgroup_bpf(u);
1833 f = open_memstream_unlocked(&buf, &size);
1834 if (!f)
1835 return -ENOMEM;
1836
1837 prefixes = streq(name, "IPAddressAllow") ? &c->ip_address_allow : &c->ip_address_deny;
1838 reduced = streq(name, "IPAddressAllow") ? &c->ip_address_allow_reduced : &c->ip_address_deny_reduced;
1839
1840 if (n == 0) {
1841 *reduced = true;
1842 *prefixes = set_free(*prefixes);
1843 fputs(name, f);
1844 fputs("=\n", f);
1845 } else {
1846 struct in_addr_prefix *p;
1847
1848 *reduced = false;
1849
1850 r = in_addr_prefixes_merge(prefixes, new_prefixes);
1851 if (r < 0)
1852 return r;
1853
1854 SET_FOREACH(p, new_prefixes) {
1855 _cleanup_free_ char *buffer = NULL;
1856
1857 r = in_addr_prefix_to_string(p->family, &p->address, p->prefixlen, &buffer);
1858 if (r == -ENOMEM)
1859 return r;
1860 if (r < 0)
1861 continue;
1862
1863 fprintf(f, "%s=%s\n", name, buffer);
1864 }
1865 }
1866
1867 r = fflush_and_check(f);
1868 if (r < 0)
1869 return r;
1870
1871 unit_write_setting(u, flags, name, buf);
1872 }
1873
1874 return 1;
1875 }
1876
1877 if (STR_IN_SET(name, "ManagedOOMSwap", "ManagedOOMMemoryPressure")) {
1878 ManagedOOMMode *cgroup_mode = streq(name, "ManagedOOMSwap") ? &c->moom_swap : &c->moom_mem_pressure;
1879 ManagedOOMMode m;
1880 const char *mode;
1881
1882 if (!UNIT_VTABLE(u)->can_set_managed_oom)
1883 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set %s for this unit type", name);
1884
1885 r = sd_bus_message_read(message, "s", &mode);
1886 if (r < 0)
1887 return r;
1888
1889 m = managed_oom_mode_from_string(mode);
1890 if (m < 0)
1891 return -EINVAL;
1892
1893 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1894 *cgroup_mode = m;
1895 unit_write_settingf(u, flags, name, "%s=%s", name, mode);
1896 }
1897
1898 (void) manager_varlink_send_managed_oom_update(u);
1899 return 1;
1900 }
1901
1902 if (streq(name, "ManagedOOMMemoryPressureLimit")) {
1903 uint32_t v;
1904
1905 if (!UNIT_VTABLE(u)->can_set_managed_oom)
1906 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set %s for this unit type", name);
1907
1908 r = sd_bus_message_read(message, "u", &v);
1909 if (r < 0)
1910 return r;
1911
1912 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1913 c->moom_mem_pressure_limit = v;
1914 unit_write_settingf(u, flags, name,
1915 "ManagedOOMMemoryPressureLimit=" PERMYRIAD_AS_PERCENT_FORMAT_STR,
1916 PERMYRIAD_AS_PERCENT_FORMAT_VAL(UINT32_SCALE_TO_PERMYRIAD(v)));
1917 }
1918
1919 if (c->moom_mem_pressure == MANAGED_OOM_KILL)
1920 (void) manager_varlink_send_managed_oom_update(u);
1921
1922 return 1;
1923 }
1924
1925 if (streq(name, "ManagedOOMPreference")) {
1926 ManagedOOMPreference p;
1927 const char *pref;
1928
1929 r = sd_bus_message_read(message, "s", &pref);
1930 if (r < 0)
1931 return r;
1932
1933 p = managed_oom_preference_from_string(pref);
1934 if (p < 0)
1935 return p;
1936
1937 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1938 c->moom_preference = p;
1939 unit_write_settingf(u, flags, name, "ManagedOOMPreference=%s", pref);
1940 }
1941
1942 return 1;
1943 }
1944 if (STR_IN_SET(name, "SocketBindAllow", "SocketBindDeny")) {
1945 CGroupSocketBindItem **list;
1946 uint16_t nr_ports, port_min;
1947 size_t n = 0;
1948 int32_t family, ip_protocol;
1949
1950 list = streq(name, "SocketBindAllow") ? &c->socket_bind_allow : &c->socket_bind_deny;
1951
1952 r = sd_bus_message_enter_container(message, 'a', "(iiqq)");
1953 if (r < 0)
1954 return r;
1955
1956 while ((r = sd_bus_message_read(message, "(iiqq)", &family, &ip_protocol, &nr_ports, &port_min)) > 0) {
1957
1958 if (!IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6))
1959 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects INET or INET6 family, if specified.", name);
1960
1961 if (!IN_SET(ip_protocol, 0, IPPROTO_TCP, IPPROTO_UDP))
1962 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects TCP or UDP protocol, if specified.", name);
1963
1964 if (port_min + (uint32_t) nr_ports > (1 << 16))
1965 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects maximum port value lesser than 65536.", name);
1966
1967 if (port_min == 0 && nr_ports != 0)
1968 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects port range starting with positive value.", name);
1969
1970 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1971 _cleanup_free_ CGroupSocketBindItem *item = NULL;
1972
1973 item = new(CGroupSocketBindItem, 1);
1974 if (!item)
1975 return log_oom();
1976
1977 *item = (CGroupSocketBindItem) {
1978 .address_family = family,
1979 .ip_protocol = ip_protocol,
1980 .nr_ports = nr_ports,
1981 .port_min = port_min
1982 };
1983
1984 LIST_PREPEND(socket_bind_items, *list, TAKE_PTR(item));
1985 }
1986 n++;
1987 }
1988 if (r < 0)
1989 return r;
1990
1991 r = sd_bus_message_exit_container(message);
1992 if (r < 0)
1993 return r;
1994
1995 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1996 _cleanup_free_ char *buf = NULL;
1997 _cleanup_fclose_ FILE *f = NULL;
1998 CGroupSocketBindItem *item;
1999 size_t size = 0;
2000
2001 if (n == 0)
2002 cgroup_context_remove_socket_bind(list);
2003 else {
2004 if ((u->manager->cgroup_supported & CGROUP_MASK_BPF_SOCKET_BIND) == 0)
2005 log_full(LOG_DEBUG,
2006 "Unit %s configures source compiled BPF programs "
2007 "but the local system does not support that.\n"
2008 "Starting this unit will fail!", u->id);
2009 }
2010
2011 f = open_memstream_unlocked(&buf, &size);
2012 if (!f)
2013 return -ENOMEM;
2014
2015 fprintf(f, "%s:", name);
2016
2017 LIST_FOREACH(socket_bind_items, item, *list)
2018 cgroup_context_dump_socket_bind_item(item, f);
2019
2020 fputc('\n', f);
2021
2022 r = fflush_and_check(f);
2023 if (r < 0)
2024 return r;
2025
2026 unit_write_setting(u, flags, name, buf);
2027 }
2028
2029 return 1;
2030 }
2031 if (streq(name, "RestrictNetworkInterfaces")) {
2032 int is_allow_list;
2033 _cleanup_strv_free_ char **l = NULL;
2034
2035 r = sd_bus_message_enter_container(message, 'r', "bas");
2036 if (r < 0)
2037 return r;
2038
2039 r = sd_bus_message_read(message, "b", &is_allow_list);
2040 if (r < 0)
2041 return r;
2042
2043 r = sd_bus_message_read_strv(message, &l);
2044 if (r < 0)
2045 return r;
2046
2047 r = sd_bus_message_exit_container(message);
2048 if (r < 0)
2049 return r;
2050
2051 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2052 _cleanup_free_ char *joined = NULL;
2053 char **s;
2054
2055 if (strv_isempty(l)) {
2056 c->restrict_network_interfaces_is_allow_list = false;
2057 c->restrict_network_interfaces = set_free(c->restrict_network_interfaces);
2058
2059 unit_write_settingf(u, flags, name, "%s=", name);
2060 return 1;
2061 }
2062
2063 if (set_isempty(c->restrict_network_interfaces))
2064 c->restrict_network_interfaces_is_allow_list = is_allow_list;
2065
2066 STRV_FOREACH(s, l) {
2067 if (!ifname_valid(*s)) {
2068 log_full(LOG_WARNING, "Invalid interface name, ignoring: %s", *s);
2069 continue;
2070 }
2071 if (c->restrict_network_interfaces_is_allow_list != (bool) is_allow_list)
2072 free(set_remove(c->restrict_network_interfaces, *s));
2073 else {
2074 r = set_put_strdup(&c->restrict_network_interfaces, *s);
2075 if (r < 0)
2076 return log_oom();
2077 }
2078 }
2079
2080 joined = strv_join(l, " ");
2081 if (!joined)
2082 return -ENOMEM;
2083
2084 unit_write_settingf(u, flags, name, "%s=%s%s", name, is_allow_list ? "" : "~", joined);
2085 }
2086
2087 return 1;
2088 }
2089
2090 if (streq(name, "DisableControllers") || (u->transient && u->load_state == UNIT_STUB))
2091 return bus_cgroup_set_transient_property(u, c, name, message, flags, error);
2092
2093 return 0;
2094 }