LCOV - code coverage report
Current view: top level - core - dbus-cgroup.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 760 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 25 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 768 0.0 %

           Branch data     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