LCOV - code coverage report
Current view: top level - core - dbus-cgroup.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 0 760 0.0 %
Date: 2019-08-22 15:41:25 Functions: 0 25 0.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <arpa/inet.h>
       4             : 
       5             : #include "af-list.h"
       6             : #include "alloc-util.h"
       7             : #include "bpf-firewall.h"
       8             : #include "bus-util.h"
       9             : #include "cgroup-util.h"
      10             : #include "cgroup.h"
      11             : #include "dbus-cgroup.h"
      12             : #include "dbus-util.h"
      13             : #include "errno-util.h"
      14             : #include "fd-util.h"
      15             : #include "fileio.h"
      16             : #include "limits-util.h"
      17             : #include "path-util.h"
      18             : 
      19           0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
      20             : 
      21           0 : static int property_get_cgroup_mask(
      22             :                 sd_bus *bus,
      23             :                 const char *path,
      24             :                 const char *interface,
      25             :                 const char *property,
      26             :                 sd_bus_message *reply,
      27             :                 void *userdata,
      28             :                 sd_bus_error *error) {
      29             : 
      30           0 :         CGroupMask *mask = userdata;
      31             :         CGroupController ctrl;
      32             :         int r;
      33             : 
      34           0 :         assert(bus);
      35           0 :         assert(reply);
      36             : 
      37           0 :         r = sd_bus_message_open_container(reply, 'a', "s");
      38           0 :         if (r < 0)
      39           0 :                 return r;
      40             : 
      41           0 :         for (ctrl = 0; ctrl < _CGROUP_CONTROLLER_MAX; ctrl++) {
      42           0 :                 if ((*mask & CGROUP_CONTROLLER_TO_MASK(ctrl)) == 0)
      43           0 :                         continue;
      44             : 
      45           0 :                 r = sd_bus_message_append(reply, "s", cgroup_controller_to_string(ctrl));
      46           0 :                 if (r < 0)
      47           0 :                         return r;
      48             :         }
      49             : 
      50           0 :         return sd_bus_message_close_container(reply);
      51             : }
      52             : 
      53           0 : static int property_get_delegate_controllers(
      54             :                 sd_bus *bus,
      55             :                 const char *path,
      56             :                 const char *interface,
      57             :                 const char *property,
      58             :                 sd_bus_message *reply,
      59             :                 void *userdata,
      60             :                 sd_bus_error *error) {
      61             : 
      62           0 :         CGroupContext *c = userdata;
      63             : 
      64           0 :         assert(bus);
      65           0 :         assert(reply);
      66           0 :         assert(c);
      67             : 
      68           0 :         if (!c->delegate)
      69           0 :                 return sd_bus_message_append(reply, "as", 0);
      70             : 
      71           0 :         return property_get_cgroup_mask(bus, path, interface, property, reply, &c->delegate_controllers, error);
      72             : }
      73             : 
      74           0 : static int property_get_io_device_weight(
      75             :                 sd_bus *bus,
      76             :                 const char *path,
      77             :                 const char *interface,
      78             :                 const char *property,
      79             :                 sd_bus_message *reply,
      80             :                 void *userdata,
      81             :                 sd_bus_error *error) {
      82             : 
      83           0 :         CGroupContext *c = userdata;
      84             :         CGroupIODeviceWeight *w;
      85             :         int r;
      86             : 
      87           0 :         assert(bus);
      88           0 :         assert(reply);
      89           0 :         assert(c);
      90             : 
      91           0 :         r = sd_bus_message_open_container(reply, 'a', "(st)");
      92           0 :         if (r < 0)
      93           0 :                 return r;
      94             : 
      95           0 :         LIST_FOREACH(device_weights, w, c->io_device_weights) {
      96           0 :                 r = sd_bus_message_append(reply, "(st)", w->path, w->weight);
      97           0 :                 if (r < 0)
      98           0 :                         return r;
      99             :         }
     100             : 
     101           0 :         return sd_bus_message_close_container(reply);
     102             : }
     103             : 
     104           0 : static int property_get_io_device_limits(
     105             :                 sd_bus *bus,
     106             :                 const char *path,
     107             :                 const char *interface,
     108             :                 const char *property,
     109             :                 sd_bus_message *reply,
     110             :                 void *userdata,
     111             :                 sd_bus_error *error) {
     112             : 
     113           0 :         CGroupContext *c = userdata;
     114             :         CGroupIODeviceLimit *l;
     115             :         int r;
     116             : 
     117           0 :         assert(bus);
     118           0 :         assert(reply);
     119           0 :         assert(c);
     120             : 
     121           0 :         r = sd_bus_message_open_container(reply, 'a', "(st)");
     122           0 :         if (r < 0)
     123           0 :                 return r;
     124             : 
     125           0 :         LIST_FOREACH(device_limits, l, c->io_device_limits) {
     126             :                 CGroupIOLimitType type;
     127             : 
     128           0 :                 type = cgroup_io_limit_type_from_string(property);
     129           0 :                 if (type < 0 || l->limits[type] == cgroup_io_limit_defaults[type])
     130           0 :                         continue;
     131             : 
     132           0 :                 r = sd_bus_message_append(reply, "(st)", l->path, l->limits[type]);
     133           0 :                 if (r < 0)
     134           0 :                         return r;
     135             :         }
     136             : 
     137           0 :         return sd_bus_message_close_container(reply);
     138             : }
     139             : 
     140           0 : static int property_get_io_device_latency(
     141             :                 sd_bus *bus,
     142             :                 const char *path,
     143             :                 const char *interface,
     144             :                 const char *property,
     145             :                 sd_bus_message *reply,
     146             :                 void *userdata,
     147             :                 sd_bus_error *error) {
     148             : 
     149           0 :         CGroupContext *c = userdata;
     150             :         CGroupIODeviceLatency *l;
     151             :         int r;
     152             : 
     153           0 :         assert(bus);
     154           0 :         assert(reply);
     155           0 :         assert(c);
     156             : 
     157           0 :         r = sd_bus_message_open_container(reply, 'a', "(st)");
     158           0 :         if (r < 0)
     159           0 :                 return r;
     160             : 
     161           0 :         LIST_FOREACH(device_latencies, l, c->io_device_latencies) {
     162           0 :                 r = sd_bus_message_append(reply, "(st)", l->path, l->target_usec);
     163           0 :                 if (r < 0)
     164           0 :                         return r;
     165             :         }
     166             : 
     167           0 :         return sd_bus_message_close_container(reply);
     168             : }
     169             : 
     170           0 : static int property_get_blockio_device_weight(
     171             :                 sd_bus *bus,
     172             :                 const char *path,
     173             :                 const char *interface,
     174             :                 const char *property,
     175             :                 sd_bus_message *reply,
     176             :                 void *userdata,
     177             :                 sd_bus_error *error) {
     178             : 
     179           0 :         CGroupContext *c = userdata;
     180             :         CGroupBlockIODeviceWeight *w;
     181             :         int r;
     182             : 
     183           0 :         assert(bus);
     184           0 :         assert(reply);
     185           0 :         assert(c);
     186             : 
     187           0 :         r = sd_bus_message_open_container(reply, 'a', "(st)");
     188           0 :         if (r < 0)
     189           0 :                 return r;
     190             : 
     191           0 :         LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
     192           0 :                 r = sd_bus_message_append(reply, "(st)", w->path, w->weight);
     193           0 :                 if (r < 0)
     194           0 :                         return r;
     195             :         }
     196             : 
     197           0 :         return sd_bus_message_close_container(reply);
     198             : }
     199             : 
     200           0 : static int property_get_blockio_device_bandwidths(
     201             :                 sd_bus *bus,
     202             :                 const char *path,
     203             :                 const char *interface,
     204             :                 const char *property,
     205             :                 sd_bus_message *reply,
     206             :                 void *userdata,
     207             :                 sd_bus_error *error) {
     208             : 
     209           0 :         CGroupContext *c = userdata;
     210             :         CGroupBlockIODeviceBandwidth *b;
     211             :         int r;
     212             : 
     213           0 :         assert(bus);
     214           0 :         assert(reply);
     215           0 :         assert(c);
     216             : 
     217           0 :         r = sd_bus_message_open_container(reply, 'a', "(st)");
     218           0 :         if (r < 0)
     219           0 :                 return r;
     220             : 
     221           0 :         LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
     222             :                 uint64_t v;
     223             : 
     224           0 :                 if (streq(property, "BlockIOReadBandwidth"))
     225           0 :                         v = b->rbps;
     226             :                 else
     227           0 :                         v = b->wbps;
     228             : 
     229           0 :                 if (v == CGROUP_LIMIT_MAX)
     230           0 :                         continue;
     231             : 
     232           0 :                 r = sd_bus_message_append(reply, "(st)", b->path, v);
     233           0 :                 if (r < 0)
     234           0 :                         return r;
     235             :         }
     236             : 
     237           0 :         return sd_bus_message_close_container(reply);
     238             : }
     239             : 
     240           0 : static int property_get_device_allow(
     241             :                 sd_bus *bus,
     242             :                 const char *path,
     243             :                 const char *interface,
     244             :                 const char *property,
     245             :                 sd_bus_message *reply,
     246             :                 void *userdata,
     247             :                 sd_bus_error *error) {
     248             : 
     249           0 :         CGroupContext *c = userdata;
     250             :         CGroupDeviceAllow *a;
     251             :         int r;
     252             : 
     253           0 :         assert(bus);
     254           0 :         assert(reply);
     255           0 :         assert(c);
     256             : 
     257           0 :         r = sd_bus_message_open_container(reply, 'a', "(ss)");
     258           0 :         if (r < 0)
     259           0 :                 return r;
     260             : 
     261           0 :         LIST_FOREACH(device_allow, a, c->device_allow) {
     262           0 :                 unsigned k = 0;
     263             :                 char rwm[4];
     264             : 
     265           0 :                 if (a->r)
     266           0 :                         rwm[k++] = 'r';
     267           0 :                 if (a->w)
     268           0 :                         rwm[k++] = 'w';
     269           0 :                 if (a->m)
     270           0 :                         rwm[k++] = 'm';
     271             : 
     272           0 :                 rwm[k] = 0;
     273             : 
     274           0 :                 r = sd_bus_message_append(reply, "(ss)", a->path, rwm);
     275           0 :                 if (r < 0)
     276           0 :                         return r;
     277             :         }
     278             : 
     279           0 :         return sd_bus_message_close_container(reply);
     280             : }
     281             : 
     282           0 : static int property_get_ip_address_access(
     283             :                 sd_bus *bus,
     284             :                 const char *path,
     285             :                 const char *interface,
     286             :                 const char *property,
     287             :                 sd_bus_message *reply,
     288             :                 void *userdata,
     289             :                 sd_bus_error *error) {
     290             : 
     291           0 :         IPAddressAccessItem** items = userdata, *i;
     292             :         int r;
     293             : 
     294           0 :         r = sd_bus_message_open_container(reply, 'a', "(iayu)");
     295           0 :         if (r < 0)
     296           0 :                 return r;
     297             : 
     298           0 :         LIST_FOREACH(items, i, *items) {
     299             : 
     300           0 :                 r = sd_bus_message_open_container(reply, 'r', "iayu");
     301           0 :                 if (r < 0)
     302           0 :                         return r;
     303             : 
     304           0 :                 r = sd_bus_message_append(reply, "i", i->family);
     305           0 :                 if (r < 0)
     306           0 :                         return r;
     307             : 
     308           0 :                 r = sd_bus_message_append_array(reply, 'y', &i->address, FAMILY_ADDRESS_SIZE(i->family));
     309           0 :                 if (r < 0)
     310           0 :                         return r;
     311             : 
     312           0 :                 r = sd_bus_message_append(reply, "u", (uint32_t) i->prefixlen);
     313           0 :                 if (r < 0)
     314           0 :                         return r;
     315             : 
     316           0 :                 r = sd_bus_message_close_container(reply);
     317           0 :                 if (r < 0)
     318           0 :                         return r;
     319             :         }
     320             : 
     321           0 :         return sd_bus_message_close_container(reply);
     322             : }
     323             : 
     324             : const sd_bus_vtable bus_cgroup_vtable[] = {
     325             :         SD_BUS_VTABLE_START(0),
     326             :         SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool, offsetof(CGroupContext, delegate), 0),
     327             :         SD_BUS_PROPERTY("DelegateControllers", "as", property_get_delegate_controllers, 0, 0),
     328             :         SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0),
     329             :         SD_BUS_PROPERTY("CPUWeight", "t", NULL, offsetof(CGroupContext, cpu_weight), 0),
     330             :         SD_BUS_PROPERTY("StartupCPUWeight", "t", NULL, offsetof(CGroupContext, startup_cpu_weight), 0),
     331             :         SD_BUS_PROPERTY("CPUShares", "t", NULL, offsetof(CGroupContext, cpu_shares), 0),
     332             :         SD_BUS_PROPERTY("StartupCPUShares", "t", NULL, offsetof(CGroupContext, startup_cpu_shares), 0),
     333             :         SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0),
     334             :         SD_BUS_PROPERTY("CPUQuotaPeriodUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_period_usec), 0),
     335             :         SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0),
     336             :         SD_BUS_PROPERTY("IOWeight", "t", NULL, offsetof(CGroupContext, io_weight), 0),
     337             :         SD_BUS_PROPERTY("StartupIOWeight", "t", NULL, offsetof(CGroupContext, startup_io_weight), 0),
     338             :         SD_BUS_PROPERTY("IODeviceWeight", "a(st)", property_get_io_device_weight, 0, 0),
     339             :         SD_BUS_PROPERTY("IOReadBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
     340             :         SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits, 0, 0),
     341             :         SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
     342             :         SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
     343             :         SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency, 0, 0),
     344             :         SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
     345             :         SD_BUS_PROPERTY("BlockIOWeight", "t", NULL, offsetof(CGroupContext, blockio_weight), 0),
     346             :         SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL, offsetof(CGroupContext, startup_blockio_weight), 0),
     347             :         SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight, 0, 0),
     348             :         SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
     349             :         SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
     350             :         SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
     351             :         SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0),
     352             :         SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL, offsetof(CGroupContext, default_memory_min), 0),
     353             :         SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0),
     354             :         SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0),
     355             :         SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0),
     356             :         SD_BUS_PROPERTY("MemoryMax", "t", NULL, offsetof(CGroupContext, memory_max), 0),
     357             :         SD_BUS_PROPERTY("MemorySwapMax", "t", NULL, offsetof(CGroupContext, memory_swap_max), 0),
     358             :         SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
     359             :         SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
     360             :         SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
     361             :         SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, tasks_accounting), 0),
     362             :         SD_BUS_PROPERTY("TasksMax", "t", NULL, offsetof(CGroupContext, tasks_max), 0),
     363             :         SD_BUS_PROPERTY("IPAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, ip_accounting), 0),
     364             :         SD_BUS_PROPERTY("IPAddressAllow", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_allow), 0),
     365             :         SD_BUS_PROPERTY("IPAddressDeny", "a(iayu)", property_get_ip_address_access, offsetof(CGroupContext, ip_address_deny), 0),
     366             :         SD_BUS_PROPERTY("IPIngressFilterPath", "as", NULL, offsetof(CGroupContext, ip_filters_ingress), 0),
     367             :         SD_BUS_PROPERTY("IPEgressFilterPath", "as", NULL, offsetof(CGroupContext, ip_filters_egress), 0),
     368             :         SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask, offsetof(CGroupContext, disable_controllers), 0),
     369             :         SD_BUS_VTABLE_END
     370             : };
     371             : 
     372           0 : static int bus_cgroup_set_transient_property(
     373             :                 Unit *u,
     374             :                 CGroupContext *c,
     375             :                 const char *name,
     376             :                 sd_bus_message *message,
     377             :                 UnitWriteFlags flags,
     378             :                 sd_bus_error *error) {
     379             : 
     380             :         int r;
     381             : 
     382           0 :         assert(u);
     383           0 :         assert(c);
     384           0 :         assert(name);
     385           0 :         assert(message);
     386             : 
     387           0 :         flags |= UNIT_PRIVATE;
     388             : 
     389           0 :         if (streq(name, "Delegate")) {
     390             :                 int b;
     391             : 
     392           0 :                 if (!UNIT_VTABLE(u)->can_delegate)
     393           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delegation not available for unit type");
     394             : 
     395           0 :                 r = sd_bus_message_read(message, "b", &b);
     396           0 :                 if (r < 0)
     397           0 :                         return r;
     398             : 
     399           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     400           0 :                         c->delegate = b;
     401           0 :                         c->delegate_controllers = b ? _CGROUP_MASK_ALL : 0;
     402             : 
     403           0 :                         unit_write_settingf(u, flags, name, "Delegate=%s", yes_no(b));
     404             :                 }
     405             : 
     406           0 :                 return 1;
     407             : 
     408           0 :         } else if (STR_IN_SET(name, "DelegateControllers", "DisableControllers")) {
     409           0 :                 CGroupMask mask = 0;
     410             : 
     411           0 :                 if (streq(name, "DelegateControllers") && !UNIT_VTABLE(u)->can_delegate)
     412           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Delegation not available for unit type");
     413             : 
     414           0 :                 r = sd_bus_message_enter_container(message, 'a', "s");
     415           0 :                 if (r < 0)
     416           0 :                         return r;
     417             : 
     418           0 :                 for (;;) {
     419             :                         CGroupController cc;
     420             :                         const char *t;
     421             : 
     422           0 :                         r = sd_bus_message_read(message, "s", &t);
     423           0 :                         if (r < 0)
     424           0 :                                 return r;
     425           0 :                         if (r == 0)
     426           0 :                                 break;
     427             : 
     428           0 :                         cc = cgroup_controller_from_string(t);
     429           0 :                         if (cc < 0)
     430           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown cgroup controller '%s'", t);
     431             : 
     432           0 :                         mask |= CGROUP_CONTROLLER_TO_MASK(cc);
     433             :                 }
     434             : 
     435           0 :                 r = sd_bus_message_exit_container(message);
     436           0 :                 if (r < 0)
     437           0 :                         return r;
     438             : 
     439           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     440           0 :                         _cleanup_free_ char *t = NULL;
     441             : 
     442           0 :                         r = cg_mask_to_string(mask, &t);
     443           0 :                         if (r < 0)
     444           0 :                                 return r;
     445             : 
     446           0 :                         if (streq(name, "DelegateControllers")) {
     447             : 
     448           0 :                                 c->delegate = true;
     449           0 :                                 if (mask == 0)
     450           0 :                                         c->delegate_controllers = 0;
     451             :                                 else
     452           0 :                                         c->delegate_controllers |= mask;
     453             : 
     454           0 :                                 unit_write_settingf(u, flags, name, "Delegate=%s", strempty(t));
     455             : 
     456           0 :                         } else if (streq(name, "DisableControllers")) {
     457             : 
     458           0 :                                 if (mask == 0)
     459           0 :                                         c->disable_controllers = 0;
     460             :                                 else
     461           0 :                                         c->disable_controllers |= mask;
     462             : 
     463           0 :                                 unit_write_settingf(u, flags, name, "%s=%s", name, strempty(t));
     464             :                         }
     465             :                 }
     466             : 
     467           0 :                 return 1;
     468           0 :         } else if (STR_IN_SET(name, "IPIngressFilterPath", "IPEgressFilterPath")) {
     469             :                 char ***filters;
     470           0 :                 size_t n = 0;
     471             : 
     472           0 :                 filters = streq(name, "IPIngressFilterPath") ? &c->ip_filters_ingress : &c->ip_filters_egress;
     473           0 :                 r = sd_bus_message_enter_container(message, 'a', "s");
     474           0 :                 if (r < 0)
     475           0 :                         return r;
     476             : 
     477           0 :                 for (;;) {
     478             :                         const char *path;
     479             : 
     480           0 :                         r = sd_bus_message_read(message, "s", &path);
     481           0 :                         if (r < 0)
     482           0 :                                 return r;
     483           0 :                         if (r == 0)
     484           0 :                                 break;
     485             : 
     486           0 :                         if (!path_is_normalized(path) || !path_is_absolute(path))
     487           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects a normalized absolute path.", name);
     488             : 
     489           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags) && !strv_contains(*filters, path)) {
     490           0 :                                 r = strv_extend(filters, path);
     491           0 :                                 if (r < 0)
     492           0 :                                         return log_oom();
     493             :                         }
     494           0 :                         n++;
     495             :                 }
     496           0 :                 r = sd_bus_message_exit_container(message);
     497           0 :                 if (r < 0)
     498           0 :                         return r;
     499             : 
     500           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     501           0 :                         _cleanup_free_ char *buf = NULL;
     502           0 :                         _cleanup_fclose_ FILE *f = NULL;
     503             :                         char **entry;
     504           0 :                         size_t size = 0;
     505             : 
     506           0 :                         if (n == 0)
     507           0 :                                 *filters = strv_free(*filters);
     508             : 
     509           0 :                         unit_invalidate_cgroup_bpf(u);
     510           0 :                         f = open_memstream_unlocked(&buf, &size);
     511           0 :                         if (!f)
     512           0 :                                 return -ENOMEM;
     513             : 
     514           0 :                         fputs(name, f);
     515           0 :                         fputs("=\n", f);
     516             : 
     517           0 :                         STRV_FOREACH(entry, *filters)
     518           0 :                                 fprintf(f, "%s=%s\n", name, *entry);
     519             : 
     520           0 :                         r = fflush_and_check(f);
     521           0 :                         if (r < 0)
     522           0 :                                 return r;
     523             : 
     524           0 :                         unit_write_setting(u, flags, name, buf);
     525             : 
     526           0 :                         if (*filters) {
     527           0 :                                 r = bpf_firewall_supported();
     528           0 :                                 if (r < 0)
     529           0 :                                         return r;
     530           0 :                                 if (r != BPF_FIREWALL_SUPPORTED_WITH_MULTI) {
     531             :                                         static bool warned = false;
     532             : 
     533           0 :                                         log_full(warned ? LOG_DEBUG : LOG_WARNING,
     534             :                                                  "Transient unit %s configures an IP firewall with BPF, but the local system does not support BPF/cgroup firewalling with mulitiple filters.\n"
     535             :                                                  "Starting this unit will fail! (This warning is only shown for the first started transient unit using IP firewalling.)", u->id);
     536           0 :                                         warned = true;
     537             :                                 }
     538             :                         }
     539             :                 }
     540             : 
     541           0 :                 return 1;
     542             :         }
     543             : 
     544           0 :         return 0;
     545             : }
     546             : 
     547           0 : static int bus_cgroup_set_boolean(
     548             :                 Unit *u,
     549             :                 const char *name,
     550             :                 bool *p,
     551             :                 CGroupMask mask,
     552             :                 sd_bus_message *message,
     553             :                 UnitWriteFlags flags,
     554             :                 sd_bus_error *error) {
     555             : 
     556             :         int b, r;
     557             : 
     558           0 :         assert(p);
     559             : 
     560           0 :         r = sd_bus_message_read(message, "b", &b);
     561           0 :         if (r < 0)
     562           0 :                 return r;
     563             : 
     564           0 :         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     565           0 :                 *p = b;
     566           0 :                 unit_invalidate_cgroup(u, mask);
     567           0 :                 unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
     568             :         }
     569             : 
     570           0 :         return 1;
     571             : }
     572             : 
     573             : #define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val)        \
     574             :         static int bus_cgroup_set_##function(                           \
     575             :                         Unit *u,                                        \
     576             :                         const char *name,                               \
     577             :                         uint64_t *p,                                    \
     578             :                         sd_bus_message *message,                        \
     579             :                         UnitWriteFlags flags,                           \
     580             :                         sd_bus_error *error) {                          \
     581             :                                                                         \
     582             :                 uint64_t v;                                             \
     583             :                 int r;                                                  \
     584             :                                                                         \
     585             :                 assert(p);                                              \
     586             :                                                                         \
     587             :                 r = sd_bus_message_read(message, "t", &v);              \
     588             :                 if (r < 0)                                              \
     589             :                         return r;                                       \
     590             :                                                                         \
     591             :                 if (!check(v))                                          \
     592             :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
     593             :                                                  "Value specified in %s is out of range", name); \
     594             :                                                                         \
     595             :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {                    \
     596             :                         *p = v;                                         \
     597             :                         unit_invalidate_cgroup(u, (mask));              \
     598             :                                                                         \
     599             :                         if (v == (val))                                 \
     600             :                                 unit_write_settingf(u, flags, name,     \
     601             :                                                     "%s=", name);       \
     602             :                         else                                            \
     603             :                                 unit_write_settingf(u, flags, name,     \
     604             :                                                     "%s=%" PRIu64, name, v); \
     605             :                 }                                                       \
     606             :                                                                         \
     607             :                 return 1;                                               \
     608             :         }
     609             : 
     610             : #define BUS_DEFINE_SET_CGROUP_LIMIT(function, mask, scale, minimum)     \
     611             :         static int bus_cgroup_set_##function(                           \
     612             :                         Unit *u,                                        \
     613             :                         const char *name,                               \
     614             :                         uint64_t *p,                                    \
     615             :                         sd_bus_message *message,                        \
     616             :                         UnitWriteFlags flags,                           \
     617             :                         sd_bus_error *error) {                          \
     618             :                                                                         \
     619             :                 uint64_t v;                                             \
     620             :                 int r;                                                  \
     621             :                                                                         \
     622             :                 assert(p);                                              \
     623             :                                                                         \
     624             :                 r = sd_bus_message_read(message, "t", &v);              \
     625             :                 if (r < 0)                                              \
     626             :                         return r;                                       \
     627             :                                                                         \
     628             :                 if (v < minimum)                                        \
     629             :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
     630             :                                                  "Value specified in %s is out of range", name); \
     631             :                                                                         \
     632             :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {                    \
     633             :                         *p = v;                                         \
     634             :                         unit_invalidate_cgroup(u, (mask));              \
     635             :                                                                         \
     636             :                         if (v == CGROUP_LIMIT_MAX)                      \
     637             :                                 unit_write_settingf(u, flags, name,     \
     638             :                                                     "%s=infinity", name); \
     639             :                         else                                            \
     640             :                                 unit_write_settingf(u, flags, name,     \
     641             :                                                     "%s=%" PRIu64, name, v); \
     642             :                 }                                                       \
     643             :                                                                         \
     644             :                 return 1;                                               \
     645             :         }                                                               \
     646             :         static int bus_cgroup_set_##function##_scale(                   \
     647             :                         Unit *u,                                        \
     648             :                         const char *name,                               \
     649             :                         uint64_t *p,                                    \
     650             :                         sd_bus_message *message,                        \
     651             :                         UnitWriteFlags flags,                           \
     652             :                         sd_bus_error *error) {                          \
     653             :                                                                         \
     654             :                 uint64_t v;                                             \
     655             :                 uint32_t raw;                                           \
     656             :                 int r;                                                  \
     657             :                                                                         \
     658             :                 assert(p);                                              \
     659             :                                                                         \
     660             :                 r = sd_bus_message_read(message, "u", &raw);            \
     661             :                 if (r < 0)                                              \
     662             :                         return r;                                       \
     663             :                                                                         \
     664             :                 v = scale(raw, UINT32_MAX);                             \
     665             :                 if (v < minimum || v >= UINT64_MAX)                     \
     666             :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
     667             :                                                  "Value specified in %s is out of range", name); \
     668             :                                                                         \
     669             :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {                    \
     670             :                         const char *e;                                  \
     671             :                                                                         \
     672             :                         *p = v;                                         \
     673             :                         unit_invalidate_cgroup(u, (mask));              \
     674             :                                                                         \
     675             :                         /* Chop off suffix */                           \
     676             :                         assert_se(e = endswith(name, "Scale"));         \
     677             :                         name = strndupa(name, e - name);                \
     678             :                                                                         \
     679             :                         unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \
     680             :                                             (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \
     681             :                 }                                                       \
     682             :                                                                         \
     683             :                 return 1;                                               \
     684             :         }
     685             : 
     686             : #pragma GCC diagnostic push
     687             : #pragma GCC diagnostic ignored "-Wtype-limits"
     688           0 : BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
     689           0 : BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID);
     690           0 : BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
     691           0 : BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID);
     692           0 : BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1);
     693           0 : BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
     694           0 : BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
     695           0 : BUS_DEFINE_SET_CGROUP_LIMIT(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale, 1);
     696             : #pragma GCC diagnostic pop
     697             : 
     698           0 : int bus_cgroup_set_property(
     699             :                 Unit *u,
     700             :                 CGroupContext *c,
     701             :                 const char *name,
     702             :                 sd_bus_message *message,
     703             :                 UnitWriteFlags flags,
     704             :                 sd_bus_error *error) {
     705             : 
     706             :         CGroupIOLimitType iol_type;
     707             :         int r;
     708             : 
     709           0 :         assert(u);
     710           0 :         assert(c);
     711           0 :         assert(name);
     712           0 :         assert(message);
     713             : 
     714           0 :         flags |= UNIT_PRIVATE;
     715             : 
     716           0 :         if (streq(name, "CPUAccounting"))
     717           0 :                 return bus_cgroup_set_boolean(u, name, &c->cpu_accounting, get_cpu_accounting_mask(), message, flags, error);
     718             : 
     719           0 :         if (streq(name, "CPUWeight"))
     720           0 :                 return bus_cgroup_set_cpu_weight(u, name, &c->cpu_weight, message, flags, error);
     721             : 
     722           0 :         if (streq(name, "StartupCPUWeight"))
     723           0 :                 return bus_cgroup_set_cpu_weight(u, name, &c->startup_cpu_weight, message, flags, error);
     724             : 
     725           0 :         if (streq(name, "CPUShares"))
     726           0 :                 return bus_cgroup_set_cpu_shares(u, name, &c->cpu_shares, message, flags, error);
     727             : 
     728           0 :         if (streq(name, "StartupCPUShares"))
     729           0 :                 return bus_cgroup_set_cpu_shares(u, name, &c->startup_cpu_shares, message, flags, error);
     730             : 
     731           0 :         if (streq(name, "IOAccounting"))
     732           0 :                 return bus_cgroup_set_boolean(u, name, &c->io_accounting, CGROUP_MASK_IO, message, flags, error);
     733             : 
     734           0 :         if (streq(name, "IOWeight"))
     735           0 :                 return bus_cgroup_set_io_weight(u, name, &c->io_weight, message, flags, error);
     736             : 
     737           0 :         if (streq(name, "StartupIOWeight"))
     738           0 :                 return bus_cgroup_set_io_weight(u, name, &c->startup_io_weight, message, flags, error);
     739             : 
     740           0 :         if (streq(name, "BlockIOAccounting"))
     741           0 :                 return bus_cgroup_set_boolean(u, name, &c->blockio_accounting, CGROUP_MASK_BLKIO, message, flags, error);
     742             : 
     743           0 :         if (streq(name, "BlockIOWeight"))
     744           0 :                 return bus_cgroup_set_blockio_weight(u, name, &c->blockio_weight, message, flags, error);
     745             : 
     746           0 :         if (streq(name, "StartupBlockIOWeight"))
     747           0 :                 return bus_cgroup_set_blockio_weight(u, name, &c->startup_blockio_weight, message, flags, error);
     748             : 
     749           0 :         if (streq(name, "MemoryAccounting"))
     750           0 :                 return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error);
     751             : 
     752           0 :         if (streq(name, "MemoryMin"))
     753           0 :                 return bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, error);
     754             : 
     755           0 :         if (streq(name, "MemoryLow"))
     756           0 :                 return bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, error);
     757             : 
     758           0 :         if (streq(name, "DefaultMemoryMin"))
     759           0 :                 return bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error);
     760             : 
     761           0 :         if (streq(name, "DefaultMemoryLow"))
     762           0 :                 return bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, error);
     763             : 
     764           0 :         if (streq(name, "MemoryHigh"))
     765           0 :                 return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error);
     766             : 
     767           0 :         if (streq(name, "MemorySwapMax"))
     768           0 :                 return bus_cgroup_set_swap(u, name, &c->memory_swap_max, message, flags, error);
     769             : 
     770           0 :         if (streq(name, "MemoryMax"))
     771           0 :                 return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error);
     772             : 
     773           0 :         if (streq(name, "MemoryLimit"))
     774           0 :                 return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error);
     775             : 
     776           0 :         if (streq(name, "MemoryMinScale"))
     777           0 :                 return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error);
     778             : 
     779           0 :         if (streq(name, "MemoryLowScale"))
     780           0 :                 return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, error);
     781             : 
     782           0 :         if (streq(name, "DefaultMemoryMinScale"))
     783           0 :                 return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, error);
     784             : 
     785           0 :         if (streq(name, "DefaultMemoryLowScale"))
     786           0 :                 return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, error);
     787             : 
     788           0 :         if (streq(name, "MemoryHighScale"))
     789           0 :                 return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error);
     790             : 
     791           0 :         if (streq(name, "MemorySwapMaxScale"))
     792           0 :                 return bus_cgroup_set_swap_scale(u, name, &c->memory_swap_max, message, flags, error);
     793             : 
     794           0 :         if (streq(name, "MemoryMaxScale"))
     795           0 :                 return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error);
     796             : 
     797           0 :         if (streq(name, "MemoryLimitScale"))
     798           0 :                 return bus_cgroup_set_memory_scale(u, name, &c->memory_limit, message, flags, error);
     799             : 
     800           0 :         if (streq(name, "TasksAccounting"))
     801           0 :                 return bus_cgroup_set_boolean(u, name, &c->tasks_accounting, CGROUP_MASK_PIDS, message, flags, error);
     802             : 
     803           0 :         if (streq(name, "TasksMax"))
     804           0 :                 return bus_cgroup_set_tasks_max(u, name, &c->tasks_max, message, flags, error);
     805             : 
     806           0 :         if (streq(name, "TasksMaxScale"))
     807           0 :                 return bus_cgroup_set_tasks_max_scale(u, name, &c->tasks_max, message, flags, error);
     808             : 
     809           0 :         if (streq(name, "CPUQuotaPerSecUSec")) {
     810             :                 uint64_t u64;
     811             : 
     812           0 :                 r = sd_bus_message_read(message, "t", &u64);
     813           0 :                 if (r < 0)
     814           0 :                         return r;
     815             : 
     816           0 :                 if (u64 <= 0)
     817           0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUQuotaPerSecUSec= value out of range");
     818             : 
     819           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     820           0 :                         c->cpu_quota_per_sec_usec = u64;
     821           0 :                         u->warned_clamping_cpu_quota_period = false;
     822           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
     823             : 
     824           0 :                         if (c->cpu_quota_per_sec_usec == USEC_INFINITY)
     825           0 :                                 unit_write_setting(u, flags, "CPUQuota", "CPUQuota=");
     826             :                         else
     827             :                                 /* config_parse_cpu_quota() requires an integer, so truncating division is used on
     828             :                                  * purpose here. */
     829           0 :                                 unit_write_settingf(u, flags, "CPUQuota",
     830             :                                                     "CPUQuota=%0.f%%",
     831           0 :                                                     (double) (c->cpu_quota_per_sec_usec / 10000));
     832             :                 }
     833             : 
     834           0 :                 return 1;
     835             : 
     836           0 :         } else if (streq(name, "CPUQuotaPeriodUSec")) {
     837             :                 uint64_t u64;
     838             : 
     839           0 :                 r = sd_bus_message_read(message, "t", &u64);
     840           0 :                 if (r < 0)
     841           0 :                         return r;
     842             : 
     843           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     844           0 :                         c->cpu_quota_period_usec = u64;
     845           0 :                         u->warned_clamping_cpu_quota_period = false;
     846           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
     847           0 :                         if (c->cpu_quota_period_usec == USEC_INFINITY)
     848           0 :                                 unit_write_setting(u, flags, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec=");
     849             :                         else {
     850             :                                 char v[FORMAT_TIMESPAN_MAX];
     851           0 :                                 unit_write_settingf(u, flags, "CPUQuotaPeriodSec",
     852             :                                                     "CPUQuotaPeriodSec=%s",
     853             :                                                     format_timespan(v, sizeof(v), c->cpu_quota_period_usec, 1));
     854             :                         }
     855             :                 }
     856             : 
     857           0 :                 return 1;
     858             : 
     859           0 :         } else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) {
     860             :                 const char *path;
     861           0 :                 unsigned n = 0;
     862             :                 uint64_t u64;
     863             : 
     864           0 :                 r = sd_bus_message_enter_container(message, 'a', "(st)");
     865           0 :                 if (r < 0)
     866           0 :                         return r;
     867             : 
     868           0 :                 while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
     869             : 
     870           0 :                         if (!path_is_normalized(path))
     871           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
     872             : 
     873           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     874           0 :                                 CGroupIODeviceLimit *a = NULL, *b;
     875             : 
     876           0 :                                 LIST_FOREACH(device_limits, b, c->io_device_limits) {
     877           0 :                                         if (path_equal(path, b->path)) {
     878           0 :                                                 a = b;
     879           0 :                                                 break;
     880             :                                         }
     881             :                                 }
     882             : 
     883           0 :                                 if (!a) {
     884             :                                         CGroupIOLimitType type;
     885             : 
     886           0 :                                         a = new0(CGroupIODeviceLimit, 1);
     887           0 :                                         if (!a)
     888           0 :                                                 return -ENOMEM;
     889             : 
     890           0 :                                         a->path = strdup(path);
     891           0 :                                         if (!a->path) {
     892           0 :                                                 free(a);
     893           0 :                                                 return -ENOMEM;
     894             :                                         }
     895             : 
     896           0 :                                         for (type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++)
     897           0 :                                                 a->limits[type] = cgroup_io_limit_defaults[type];
     898             : 
     899           0 :                                         LIST_PREPEND(device_limits, c->io_device_limits, a);
     900             :                                 }
     901             : 
     902           0 :                                 a->limits[iol_type] = u64;
     903             :                         }
     904             : 
     905           0 :                         n++;
     906             :                 }
     907           0 :                 if (r < 0)
     908           0 :                         return r;
     909             : 
     910           0 :                 r = sd_bus_message_exit_container(message);
     911           0 :                 if (r < 0)
     912           0 :                         return r;
     913             : 
     914           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     915             :                         CGroupIODeviceLimit *a;
     916           0 :                         _cleanup_free_ char *buf = NULL;
     917           0 :                         _cleanup_fclose_ FILE *f = NULL;
     918           0 :                         size_t size = 0;
     919             : 
     920           0 :                         if (n == 0) {
     921           0 :                                 LIST_FOREACH(device_limits, a, c->io_device_limits)
     922           0 :                                         a->limits[iol_type] = cgroup_io_limit_defaults[iol_type];
     923             :                         }
     924             : 
     925           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_IO);
     926             : 
     927           0 :                         f = open_memstream_unlocked(&buf, &size);
     928           0 :                         if (!f)
     929           0 :                                 return -ENOMEM;
     930             : 
     931           0 :                         fprintf(f, "%s=\n", name);
     932           0 :                         LIST_FOREACH(device_limits, a, c->io_device_limits)
     933           0 :                                         if (a->limits[iol_type] != cgroup_io_limit_defaults[iol_type])
     934           0 :                                                 fprintf(f, "%s=%s %" PRIu64 "\n", name, a->path, a->limits[iol_type]);
     935             : 
     936           0 :                         r = fflush_and_check(f);
     937           0 :                         if (r < 0)
     938           0 :                                 return r;
     939           0 :                         unit_write_setting(u, flags, name, buf);
     940             :                 }
     941             : 
     942           0 :                 return 1;
     943             : 
     944           0 :         } else if (streq(name, "IODeviceWeight")) {
     945             :                 const char *path;
     946             :                 uint64_t weight;
     947           0 :                 unsigned n = 0;
     948             : 
     949           0 :                 r = sd_bus_message_enter_container(message, 'a', "(st)");
     950           0 :                 if (r < 0)
     951           0 :                         return r;
     952             : 
     953           0 :                 while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) {
     954             : 
     955           0 :                         if (!path_is_normalized(path))
     956           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
     957             : 
     958           0 :                         if (!CGROUP_WEIGHT_IS_OK(weight) || weight == CGROUP_WEIGHT_INVALID)
     959           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IODeviceWeight= value out of range");
     960             : 
     961           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     962           0 :                                 CGroupIODeviceWeight *a = NULL, *b;
     963             : 
     964           0 :                                 LIST_FOREACH(device_weights, b, c->io_device_weights) {
     965           0 :                                         if (path_equal(b->path, path)) {
     966           0 :                                                 a = b;
     967           0 :                                                 break;
     968             :                                         }
     969             :                                 }
     970             : 
     971           0 :                                 if (!a) {
     972           0 :                                         a = new0(CGroupIODeviceWeight, 1);
     973           0 :                                         if (!a)
     974           0 :                                                 return -ENOMEM;
     975             : 
     976           0 :                                         a->path = strdup(path);
     977           0 :                                         if (!a->path) {
     978           0 :                                                 free(a);
     979           0 :                                                 return -ENOMEM;
     980             :                                         }
     981           0 :                                         LIST_PREPEND(device_weights, c->io_device_weights, a);
     982             :                                 }
     983             : 
     984           0 :                                 a->weight = weight;
     985             :                         }
     986             : 
     987           0 :                         n++;
     988             :                 }
     989             : 
     990           0 :                 r = sd_bus_message_exit_container(message);
     991           0 :                 if (r < 0)
     992           0 :                         return r;
     993             : 
     994           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     995           0 :                         _cleanup_free_ char *buf = NULL;
     996           0 :                         _cleanup_fclose_ FILE *f = NULL;
     997             :                         CGroupIODeviceWeight *a;
     998           0 :                         size_t size = 0;
     999             : 
    1000           0 :                         if (n == 0) {
    1001           0 :                                 while (c->io_device_weights)
    1002           0 :                                         cgroup_context_free_io_device_weight(c, c->io_device_weights);
    1003             :                         }
    1004             : 
    1005           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_IO);
    1006             : 
    1007           0 :                         f = open_memstream_unlocked(&buf, &size);
    1008           0 :                         if (!f)
    1009           0 :                                 return -ENOMEM;
    1010             : 
    1011           0 :                         fputs("IODeviceWeight=\n", f);
    1012           0 :                         LIST_FOREACH(device_weights, a, c->io_device_weights)
    1013           0 :                                 fprintf(f, "IODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight);
    1014             : 
    1015           0 :                         r = fflush_and_check(f);
    1016           0 :                         if (r < 0)
    1017           0 :                                 return r;
    1018           0 :                         unit_write_setting(u, flags, name, buf);
    1019             :                 }
    1020             : 
    1021           0 :                 return 1;
    1022             : 
    1023           0 :         } else if (streq(name, "IODeviceLatencyTargetUSec")) {
    1024             :                 const char *path;
    1025             :                 uint64_t target;
    1026           0 :                 unsigned n = 0;
    1027             : 
    1028           0 :                 r = sd_bus_message_enter_container(message, 'a', "(st)");
    1029           0 :                 if (r < 0)
    1030           0 :                         return r;
    1031             : 
    1032           0 :                 while ((r = sd_bus_message_read(message, "(st)", &path, &target)) > 0) {
    1033             : 
    1034           0 :                         if (!path_is_normalized(path))
    1035           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
    1036             : 
    1037           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1038           0 :                                 CGroupIODeviceLatency *a = NULL, *b;
    1039             : 
    1040           0 :                                 LIST_FOREACH(device_latencies, b, c->io_device_latencies) {
    1041           0 :                                         if (path_equal(b->path, path)) {
    1042           0 :                                                 a = b;
    1043           0 :                                                 break;
    1044             :                                         }
    1045             :                                 }
    1046             : 
    1047           0 :                                 if (!a) {
    1048           0 :                                         a = new0(CGroupIODeviceLatency, 1);
    1049           0 :                                         if (!a)
    1050           0 :                                                 return -ENOMEM;
    1051             : 
    1052           0 :                                         a->path = strdup(path);
    1053           0 :                                         if (!a->path) {
    1054           0 :                                                 free(a);
    1055           0 :                                                 return -ENOMEM;
    1056             :                                         }
    1057           0 :                                         LIST_PREPEND(device_latencies, c->io_device_latencies, a);
    1058             :                                 }
    1059             : 
    1060           0 :                                 a->target_usec = target;
    1061             :                         }
    1062             : 
    1063           0 :                         n++;
    1064             :                 }
    1065             : 
    1066           0 :                 r = sd_bus_message_exit_container(message);
    1067           0 :                 if (r < 0)
    1068           0 :                         return r;
    1069             : 
    1070           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1071           0 :                         _cleanup_free_ char *buf = NULL;
    1072           0 :                         _cleanup_fclose_ FILE *f = NULL;
    1073             :                         char ts[FORMAT_TIMESPAN_MAX];
    1074             :                         CGroupIODeviceLatency *a;
    1075           0 :                         size_t size = 0;
    1076             : 
    1077           0 :                         if (n == 0) {
    1078           0 :                                 while (c->io_device_latencies)
    1079           0 :                                         cgroup_context_free_io_device_latency(c, c->io_device_latencies);
    1080             :                         }
    1081             : 
    1082           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_IO);
    1083             : 
    1084           0 :                         f = open_memstream_unlocked(&buf, &size);
    1085           0 :                         if (!f)
    1086           0 :                                 return -ENOMEM;
    1087             : 
    1088           0 :                         fputs("IODeviceLatencyTargetSec=\n", f);
    1089           0 :                         LIST_FOREACH(device_latencies, a, c->io_device_latencies)
    1090           0 :                                 fprintf(f, "IODeviceLatencyTargetSec=%s %s\n",
    1091             :                                         a->path, format_timespan(ts, sizeof(ts), a->target_usec, 1));
    1092             : 
    1093           0 :                         r = fflush_and_check(f);
    1094           0 :                         if (r < 0)
    1095           0 :                                 return r;
    1096           0 :                         unit_write_setting(u, flags, name, buf);
    1097             :                 }
    1098             : 
    1099           0 :                 return 1;
    1100             : 
    1101           0 :         } else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
    1102             :                 const char *path;
    1103           0 :                 bool read = true;
    1104           0 :                 unsigned n = 0;
    1105             :                 uint64_t u64;
    1106             : 
    1107           0 :                 if (streq(name, "BlockIOWriteBandwidth"))
    1108           0 :                         read = false;
    1109             : 
    1110           0 :                 r = sd_bus_message_enter_container(message, 'a', "(st)");
    1111           0 :                 if (r < 0)
    1112           0 :                         return r;
    1113             : 
    1114           0 :                 while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) {
    1115             : 
    1116           0 :                         if (!path_is_normalized(path))
    1117           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
    1118             : 
    1119           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1120           0 :                                 CGroupBlockIODeviceBandwidth *a = NULL, *b;
    1121             : 
    1122           0 :                                 LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
    1123           0 :                                         if (path_equal(path, b->path)) {
    1124           0 :                                                 a = b;
    1125           0 :                                                 break;
    1126             :                                         }
    1127             :                                 }
    1128             : 
    1129           0 :                                 if (!a) {
    1130           0 :                                         a = new0(CGroupBlockIODeviceBandwidth, 1);
    1131           0 :                                         if (!a)
    1132           0 :                                                 return -ENOMEM;
    1133             : 
    1134           0 :                                         a->rbps = CGROUP_LIMIT_MAX;
    1135           0 :                                         a->wbps = CGROUP_LIMIT_MAX;
    1136           0 :                                         a->path = strdup(path);
    1137           0 :                                         if (!a->path) {
    1138           0 :                                                 free(a);
    1139           0 :                                                 return -ENOMEM;
    1140             :                                         }
    1141             : 
    1142           0 :                                         LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
    1143             :                                 }
    1144             : 
    1145           0 :                                 if (read)
    1146           0 :                                         a->rbps = u64;
    1147             :                                 else
    1148           0 :                                         a->wbps = u64;
    1149             :                         }
    1150             : 
    1151           0 :                         n++;
    1152             :                 }
    1153           0 :                 if (r < 0)
    1154           0 :                         return r;
    1155             : 
    1156           0 :                 r = sd_bus_message_exit_container(message);
    1157           0 :                 if (r < 0)
    1158           0 :                         return r;
    1159             : 
    1160           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1161             :                         CGroupBlockIODeviceBandwidth *a;
    1162           0 :                         _cleanup_free_ char *buf = NULL;
    1163           0 :                         _cleanup_fclose_ FILE *f = NULL;
    1164           0 :                         size_t size = 0;
    1165             : 
    1166           0 :                         if (n == 0) {
    1167           0 :                                 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) {
    1168           0 :                                         if (read)
    1169           0 :                                                 a->rbps = CGROUP_LIMIT_MAX;
    1170             :                                         else
    1171           0 :                                                 a->wbps = CGROUP_LIMIT_MAX;
    1172             :                                 }
    1173             :                         }
    1174             : 
    1175           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
    1176             : 
    1177           0 :                         f = open_memstream_unlocked(&buf, &size);
    1178           0 :                         if (!f)
    1179           0 :                                 return -ENOMEM;
    1180             : 
    1181           0 :                         if (read) {
    1182           0 :                                 fputs("BlockIOReadBandwidth=\n", f);
    1183           0 :                                 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
    1184           0 :                                         if (a->rbps != CGROUP_LIMIT_MAX)
    1185           0 :                                                 fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->rbps);
    1186             :                         } else {
    1187           0 :                                 fputs("BlockIOWriteBandwidth=\n", f);
    1188           0 :                                 LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths)
    1189           0 :                                         if (a->wbps != CGROUP_LIMIT_MAX)
    1190           0 :                                                 fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->wbps);
    1191             :                         }
    1192             : 
    1193           0 :                         r = fflush_and_check(f);
    1194           0 :                         if (r < 0)
    1195           0 :                                 return r;
    1196             : 
    1197           0 :                         unit_write_setting(u, flags, name, buf);
    1198             :                 }
    1199             : 
    1200           0 :                 return 1;
    1201             : 
    1202           0 :         } else if (streq(name, "BlockIODeviceWeight")) {
    1203             :                 const char *path;
    1204             :                 uint64_t weight;
    1205           0 :                 unsigned n = 0;
    1206             : 
    1207           0 :                 r = sd_bus_message_enter_container(message, 'a', "(st)");
    1208           0 :                 if (r < 0)
    1209           0 :                         return r;
    1210             : 
    1211           0 :                 while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) {
    1212             : 
    1213           0 :                         if (!path_is_normalized(path))
    1214           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' specified in %s= is not normalized.", name, path);
    1215             : 
    1216           0 :                         if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight) || weight == CGROUP_BLKIO_WEIGHT_INVALID)
    1217           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIODeviceWeight= out of range");
    1218             : 
    1219           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1220           0 :                                 CGroupBlockIODeviceWeight *a = NULL, *b;
    1221             : 
    1222           0 :                                 LIST_FOREACH(device_weights, b, c->blockio_device_weights) {
    1223           0 :                                         if (path_equal(b->path, path)) {
    1224           0 :                                                 a = b;
    1225           0 :                                                 break;
    1226             :                                         }
    1227             :                                 }
    1228             : 
    1229           0 :                                 if (!a) {
    1230           0 :                                         a = new0(CGroupBlockIODeviceWeight, 1);
    1231           0 :                                         if (!a)
    1232           0 :                                                 return -ENOMEM;
    1233             : 
    1234           0 :                                         a->path = strdup(path);
    1235           0 :                                         if (!a->path) {
    1236           0 :                                                 free(a);
    1237           0 :                                                 return -ENOMEM;
    1238             :                                         }
    1239           0 :                                         LIST_PREPEND(device_weights, c->blockio_device_weights, a);
    1240             :                                 }
    1241             : 
    1242           0 :                                 a->weight = weight;
    1243             :                         }
    1244             : 
    1245           0 :                         n++;
    1246             :                 }
    1247             : 
    1248           0 :                 r = sd_bus_message_exit_container(message);
    1249           0 :                 if (r < 0)
    1250           0 :                         return r;
    1251             : 
    1252           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1253           0 :                         _cleanup_free_ char *buf = NULL;
    1254           0 :                         _cleanup_fclose_ FILE *f = NULL;
    1255             :                         CGroupBlockIODeviceWeight *a;
    1256           0 :                         size_t size = 0;
    1257             : 
    1258           0 :                         if (n == 0) {
    1259           0 :                                 while (c->blockio_device_weights)
    1260           0 :                                         cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
    1261             :                         }
    1262             : 
    1263           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
    1264             : 
    1265           0 :                         f = open_memstream_unlocked(&buf, &size);
    1266           0 :                         if (!f)
    1267           0 :                                 return -ENOMEM;
    1268             : 
    1269           0 :                         fputs("BlockIODeviceWeight=\n", f);
    1270           0 :                         LIST_FOREACH(device_weights, a, c->blockio_device_weights)
    1271           0 :                                 fprintf(f, "BlockIODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight);
    1272             : 
    1273           0 :                         r = fflush_and_check(f);
    1274           0 :                         if (r < 0)
    1275           0 :                                 return r;
    1276             : 
    1277           0 :                         unit_write_setting(u, flags, name, buf);
    1278             :                 }
    1279             : 
    1280           0 :                 return 1;
    1281             : 
    1282           0 :         } else if (streq(name, "DevicePolicy")) {
    1283             :                 const char *policy;
    1284             :                 CGroupDevicePolicy p;
    1285             : 
    1286           0 :                 r = sd_bus_message_read(message, "s", &policy);
    1287           0 :                 if (r < 0)
    1288           0 :                         return r;
    1289             : 
    1290           0 :                 p = cgroup_device_policy_from_string(policy);
    1291           0 :                 if (p < 0)
    1292           0 :                         return -EINVAL;
    1293             : 
    1294           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1295           0 :                         c->device_policy = p;
    1296           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES);
    1297           0 :                         unit_write_settingf(u, flags, name, "DevicePolicy=%s", policy);
    1298             :                 }
    1299             : 
    1300           0 :                 return 1;
    1301             : 
    1302           0 :         } else if (streq(name, "DeviceAllow")) {
    1303             :                 const char *path, *rwm;
    1304           0 :                 unsigned n = 0;
    1305             : 
    1306           0 :                 r = sd_bus_message_enter_container(message, 'a', "(ss)");
    1307           0 :                 if (r < 0)
    1308           0 :                         return r;
    1309             : 
    1310           0 :                 while ((r = sd_bus_message_read(message, "(ss)", &path, &rwm)) > 0) {
    1311             : 
    1312           0 :                         if (!valid_device_allow_pattern(path) || strpbrk(path, WHITESPACE))
    1313           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node or pattern");
    1314             : 
    1315           0 :                         if (isempty(rwm))
    1316           0 :                                 rwm = "rwm";
    1317           0 :                         else if (!in_charset(rwm, "rwm"))
    1318           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags");
    1319             : 
    1320           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1321           0 :                                 CGroupDeviceAllow *a = NULL, *b;
    1322             : 
    1323           0 :                                 LIST_FOREACH(device_allow, b, c->device_allow) {
    1324           0 :                                         if (path_equal(b->path, path)) {
    1325           0 :                                                 a = b;
    1326           0 :                                                 break;
    1327             :                                         }
    1328             :                                 }
    1329             : 
    1330           0 :                                 if (!a) {
    1331           0 :                                         a = new0(CGroupDeviceAllow, 1);
    1332           0 :                                         if (!a)
    1333           0 :                                                 return -ENOMEM;
    1334             : 
    1335           0 :                                         a->path = strdup(path);
    1336           0 :                                         if (!a->path) {
    1337           0 :                                                 free(a);
    1338           0 :                                                 return -ENOMEM;
    1339             :                                         }
    1340             : 
    1341           0 :                                         LIST_PREPEND(device_allow, c->device_allow, a);
    1342             :                                 }
    1343             : 
    1344           0 :                                 a->r = !!strchr(rwm, 'r');
    1345           0 :                                 a->w = !!strchr(rwm, 'w');
    1346           0 :                                 a->m = !!strchr(rwm, 'm');
    1347             :                         }
    1348             : 
    1349           0 :                         n++;
    1350             :                 }
    1351           0 :                 if (r < 0)
    1352           0 :                         return r;
    1353             : 
    1354           0 :                 r = sd_bus_message_exit_container(message);
    1355           0 :                 if (r < 0)
    1356           0 :                         return r;
    1357             : 
    1358           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1359           0 :                         _cleanup_free_ char *buf = NULL;
    1360           0 :                         _cleanup_fclose_ FILE *f = NULL;
    1361             :                         CGroupDeviceAllow *a;
    1362           0 :                         size_t size = 0;
    1363             : 
    1364           0 :                         if (n == 0) {
    1365           0 :                                 while (c->device_allow)
    1366           0 :                                         cgroup_context_free_device_allow(c, c->device_allow);
    1367             :                         }
    1368             : 
    1369           0 :                         unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES);
    1370             : 
    1371           0 :                         f = open_memstream_unlocked(&buf, &size);
    1372           0 :                         if (!f)
    1373           0 :                                 return -ENOMEM;
    1374             : 
    1375           0 :                         fputs("DeviceAllow=\n", f);
    1376           0 :                         LIST_FOREACH(device_allow, a, c->device_allow)
    1377           0 :                                 fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : "");
    1378             : 
    1379           0 :                         r = fflush_and_check(f);
    1380           0 :                         if (r < 0)
    1381           0 :                                 return r;
    1382           0 :                         unit_write_setting(u, flags, name, buf);
    1383             :                 }
    1384             : 
    1385           0 :                 return 1;
    1386             : 
    1387           0 :         } else if (streq(name, "IPAccounting")) {
    1388             :                 int b;
    1389             : 
    1390           0 :                 r = sd_bus_message_read(message, "b", &b);
    1391           0 :                 if (r < 0)
    1392           0 :                         return r;
    1393             : 
    1394           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1395           0 :                         c->ip_accounting = b;
    1396             : 
    1397           0 :                         unit_invalidate_cgroup_bpf(u);
    1398           0 :                         unit_write_settingf(u, flags, name, "IPAccounting=%s", yes_no(b));
    1399             :                 }
    1400             : 
    1401           0 :                 return 1;
    1402             : 
    1403           0 :         } else if (STR_IN_SET(name, "IPAddressAllow", "IPAddressDeny")) {
    1404             :                 IPAddressAccessItem **list;
    1405           0 :                 size_t n = 0;
    1406             : 
    1407           0 :                 list = streq(name, "IPAddressAllow") ? &c->ip_address_allow : &c->ip_address_deny;
    1408             : 
    1409           0 :                 r = sd_bus_message_enter_container(message, 'a', "(iayu)");
    1410           0 :                 if (r < 0)
    1411           0 :                         return r;
    1412             : 
    1413           0 :                 for (;;) {
    1414             :                         const void *ap;
    1415             :                         int32_t family;
    1416             :                         uint32_t prefixlen;
    1417             :                         size_t an;
    1418             : 
    1419           0 :                         r = sd_bus_message_enter_container(message, 'r', "iayu");
    1420           0 :                         if (r < 0)
    1421           0 :                                 return r;
    1422           0 :                         if (r == 0)
    1423           0 :                                 break;
    1424             : 
    1425           0 :                         r = sd_bus_message_read(message, "i", &family);
    1426           0 :                         if (r < 0)
    1427           0 :                                 return r;
    1428             : 
    1429           0 :                         if (!IN_SET(family, AF_INET, AF_INET6))
    1430           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects IPv4 or IPv6 addresses only.", name);
    1431             : 
    1432           0 :                         r = sd_bus_message_read_array(message, 'y', &ap, &an);
    1433           0 :                         if (r < 0)
    1434           0 :                                 return r;
    1435             : 
    1436           0 :                         if (an != FAMILY_ADDRESS_SIZE(family))
    1437           0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IP address has wrong size for family (%s, expected %zu, got %zu)",
    1438             :                                                                af_to_name(family), FAMILY_ADDRESS_SIZE(family), an);
    1439             : 
    1440           0 :                         r = sd_bus_message_read(message, "u", &prefixlen);
    1441           0 :                         if (r < 0)
    1442           0 :                                 return r;
    1443             : 
    1444           0 :                         if (prefixlen > FAMILY_ADDRESS_SIZE(family)*8)
    1445           0 :                                 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));
    1446             : 
    1447           0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1448             :                                 IPAddressAccessItem *item;
    1449             : 
    1450           0 :                                 item = new0(IPAddressAccessItem, 1);
    1451           0 :                                 if (!item)
    1452           0 :                                         return -ENOMEM;
    1453             : 
    1454           0 :                                 item->family = family;
    1455           0 :                                 item->prefixlen = prefixlen;
    1456           0 :                                 memcpy(&item->address, ap, an);
    1457             : 
    1458           0 :                                 LIST_PREPEND(items, *list, item);
    1459             :                         }
    1460             : 
    1461           0 :                         r = sd_bus_message_exit_container(message);
    1462           0 :                         if (r < 0)
    1463           0 :                                 return r;
    1464             : 
    1465           0 :                         n++;
    1466             :                 }
    1467             : 
    1468           0 :                 r = sd_bus_message_exit_container(message);
    1469           0 :                 if (r < 0)
    1470           0 :                         return r;
    1471             : 
    1472           0 :                 *list = ip_address_access_reduce(*list);
    1473             : 
    1474           0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1475           0 :                         _cleanup_free_ char *buf = NULL;
    1476           0 :                         _cleanup_fclose_ FILE *f = NULL;
    1477             :                         IPAddressAccessItem *item;
    1478           0 :                         size_t size = 0;
    1479             : 
    1480           0 :                         if (n == 0)
    1481           0 :                                 *list = ip_address_access_free_all(*list);
    1482             : 
    1483           0 :                         unit_invalidate_cgroup_bpf(u);
    1484           0 :                         f = open_memstream_unlocked(&buf, &size);
    1485           0 :                         if (!f)
    1486           0 :                                 return -ENOMEM;
    1487             : 
    1488           0 :                         fputs(name, f);
    1489           0 :                         fputs("=\n", f);
    1490             : 
    1491           0 :                         LIST_FOREACH(items, item, *list) {
    1492             :                                 char buffer[CONST_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
    1493             : 
    1494           0 :                                 errno = 0;
    1495           0 :                                 if (!inet_ntop(item->family, &item->address, buffer, sizeof(buffer)))
    1496           0 :                                         return errno_or_else(EINVAL);
    1497             : 
    1498           0 :                                 fprintf(f, "%s=%s/%u\n", name, buffer, item->prefixlen);
    1499             :                         }
    1500             : 
    1501           0 :                         r = fflush_and_check(f);
    1502           0 :                         if (r < 0)
    1503           0 :                                 return r;
    1504             : 
    1505           0 :                         unit_write_setting(u, flags, name, buf);
    1506             :                 }
    1507             : 
    1508           0 :                 return 1;
    1509             :         }
    1510             : 
    1511           0 :         if (streq(name, "DisableControllers") || (u->transient && u->load_state == UNIT_STUB))
    1512           0 :                 return bus_cgroup_set_transient_property(u, c, name, message, flags, error);
    1513             : 
    1514           0 :         return 0;
    1515             : }

Generated by: LCOV version 1.14