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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "sd-bus.h"
       4                 :            : 
       5                 :            : #include "bus-error.h"
       6                 :            : #include "bus-unit-util.h"
       7                 :            : #include "bus-util.h"
       8                 :            : #include "bus-wait-for-jobs.h"
       9                 :            : #include "nspawn-register.h"
      10                 :            : #include "special.h"
      11                 :            : #include "stat-util.h"
      12                 :            : #include "strv.h"
      13                 :            : #include "util.h"
      14                 :            : 
      15                 :          0 : static int append_machine_properties(
      16                 :            :                 sd_bus_message *m,
      17                 :            :                 CustomMount *mounts,
      18                 :            :                 unsigned n_mounts,
      19                 :            :                 int kill_signal) {
      20                 :            : 
      21                 :            :         unsigned j;
      22                 :            :         int r;
      23                 :            : 
      24         [ #  # ]:          0 :         assert(m);
      25                 :            : 
      26                 :          0 :         r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
      27         [ #  # ]:          0 :         if (r < 0)
      28         [ #  # ]:          0 :                 return bus_log_create_error(r);
      29                 :            : 
      30                 :            :         /* If you make changes here, also make sure to update systemd-nspawn@.service, to keep the device policies in
      31                 :            :          * sync regardless if we are run with or without the --keep-unit switch. */
      32                 :          0 :         r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
      33                 :            :                                   /* Allow the container to
      34                 :            :                                    * access and create the API
      35                 :            :                                    * device nodes, so that
      36                 :            :                                    * PrivateDevices= in the
      37                 :            :                                    * container can work
      38                 :            :                                    * fine */
      39                 :            :                                   "/dev/net/tun", "rwm",
      40                 :            :                                   /* Allow the container
      41                 :            :                                    * access to ptys. However,
      42                 :            :                                    * do not permit the
      43                 :            :                                    * container to ever create
      44                 :            :                                    * these device nodes. */
      45                 :            :                                   "char-pts", "rw");
      46         [ #  # ]:          0 :         if (r < 0)
      47         [ #  # ]:          0 :                 return bus_log_create_error(r);
      48                 :            : 
      49         [ #  # ]:          0 :         for (j = 0; j < n_mounts; j++) {
      50                 :          0 :                 CustomMount *cm = mounts + j;
      51                 :            : 
      52         [ #  # ]:          0 :                 if (cm->type != CUSTOM_MOUNT_BIND)
      53                 :          0 :                         continue;
      54                 :            : 
      55                 :          0 :                 r = is_device_node(cm->source);
      56         [ #  # ]:          0 :                 if (r == -ENOENT) {
      57                 :            :                         /* The bind source might only appear as the image is put together, hence don't complain */
      58         [ #  # ]:          0 :                         log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
      59                 :          0 :                         continue;
      60                 :            :                 }
      61         [ #  # ]:          0 :                 if (r < 0)
      62         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to stat %s: %m", cm->source);
      63                 :            : 
      64         [ #  # ]:          0 :                 if (r) {
      65                 :          0 :                         r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
      66         [ #  # ]:          0 :                                                   cm->source, cm->read_only ? "r" : "rw");
      67         [ #  # ]:          0 :                         if (r < 0)
      68         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to append message arguments: %m");
      69                 :            :                 }
      70                 :            :         }
      71                 :            : 
      72         [ #  # ]:          0 :         if (kill_signal != 0) {
      73                 :          0 :                 r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
      74         [ #  # ]:          0 :                 if (r < 0)
      75         [ #  # ]:          0 :                         return bus_log_create_error(r);
      76                 :            : 
      77                 :          0 :                 r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
      78         [ #  # ]:          0 :                 if (r < 0)
      79         [ #  # ]:          0 :                         return bus_log_create_error(r);
      80                 :            :         }
      81                 :            : 
      82                 :          0 :         return 0;
      83                 :            : }
      84                 :            : 
      85                 :          0 : static int append_controller_property(sd_bus *bus, sd_bus_message *m) {
      86                 :            :         const char *unique;
      87                 :            :         int r;
      88                 :            : 
      89         [ #  # ]:          0 :         assert(bus);
      90         [ #  # ]:          0 :         assert(m);
      91                 :            : 
      92                 :          0 :         r = sd_bus_get_unique_name(bus, &unique);
      93         [ #  # ]:          0 :         if (r < 0)
      94         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to get unique name: %m");
      95                 :            : 
      96                 :          0 :         r = sd_bus_message_append(m, "(sv)", "Controller", "s", unique);
      97         [ #  # ]:          0 :         if (r < 0)
      98         [ #  # ]:          0 :                 return bus_log_create_error(r);
      99                 :            : 
     100                 :          0 :         return 0;
     101                 :            : }
     102                 :            : 
     103                 :          0 : int register_machine(
     104                 :            :                 sd_bus *bus,
     105                 :            :                 const char *machine_name,
     106                 :            :                 pid_t pid,
     107                 :            :                 const char *directory,
     108                 :            :                 sd_id128_t uuid,
     109                 :            :                 int local_ifindex,
     110                 :            :                 const char *slice,
     111                 :            :                 CustomMount *mounts,
     112                 :            :                 unsigned n_mounts,
     113                 :            :                 int kill_signal,
     114                 :            :                 char **properties,
     115                 :            :                 sd_bus_message *properties_message,
     116                 :            :                 bool keep_unit,
     117                 :            :                 const char *service) {
     118                 :            : 
     119                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
     120                 :            :         int r;
     121                 :            : 
     122         [ #  # ]:          0 :         assert(bus);
     123                 :            : 
     124         [ #  # ]:          0 :         if (keep_unit) {
     125                 :          0 :                 r = sd_bus_call_method(
     126                 :            :                                 bus,
     127                 :            :                                 "org.freedesktop.machine1",
     128                 :            :                                 "/org/freedesktop/machine1",
     129                 :            :                                 "org.freedesktop.machine1.Manager",
     130                 :            :                                 "RegisterMachineWithNetwork",
     131                 :            :                                 &error,
     132                 :            :                                 NULL,
     133                 :            :                                 "sayssusai",
     134                 :            :                                 machine_name,
     135                 :          0 :                                 SD_BUS_MESSAGE_APPEND_ID128(uuid),
     136                 :            :                                 service,
     137                 :            :                                 "container",
     138                 :            :                                 (uint32_t) pid,
     139                 :            :                                 strempty(directory),
     140                 :            :                                 local_ifindex > 0 ? 1 : 0, local_ifindex);
     141                 :            :         } else {
     142         [ #  # ]:          0 :                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
     143                 :            : 
     144                 :          0 :                 r = sd_bus_message_new_method_call(
     145                 :            :                                 bus,
     146                 :            :                                 &m,
     147                 :            :                                 "org.freedesktop.machine1",
     148                 :            :                                 "/org/freedesktop/machine1",
     149                 :            :                                 "org.freedesktop.machine1.Manager",
     150                 :            :                                 "CreateMachineWithNetwork");
     151         [ #  # ]:          0 :                 if (r < 0)
     152         [ #  # ]:          0 :                         return bus_log_create_error(r);
     153                 :            : 
     154                 :          0 :                 r = sd_bus_message_append(
     155                 :            :                                 m,
     156                 :            :                                 "sayssusai",
     157                 :            :                                 machine_name,
     158                 :          0 :                                 SD_BUS_MESSAGE_APPEND_ID128(uuid),
     159                 :            :                                 service,
     160                 :            :                                 "container",
     161                 :            :                                 (uint32_t) pid,
     162                 :            :                                 strempty(directory),
     163                 :            :                                 local_ifindex > 0 ? 1 : 0, local_ifindex);
     164         [ #  # ]:          0 :                 if (r < 0)
     165         [ #  # ]:          0 :                         return bus_log_create_error(r);
     166                 :            : 
     167                 :          0 :                 r = sd_bus_message_open_container(m, 'a', "(sv)");
     168         [ #  # ]:          0 :                 if (r < 0)
     169         [ #  # ]:          0 :                         return bus_log_create_error(r);
     170                 :            : 
     171         [ #  # ]:          0 :                 if (!isempty(slice)) {
     172                 :          0 :                         r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
     173         [ #  # ]:          0 :                         if (r < 0)
     174         [ #  # ]:          0 :                                 return bus_log_create_error(r);
     175                 :            :                 }
     176                 :            : 
     177                 :          0 :                 r = append_controller_property(bus, m);
     178         [ #  # ]:          0 :                 if (r < 0)
     179                 :          0 :                         return r;
     180                 :            : 
     181                 :          0 :                 r = append_machine_properties(
     182                 :            :                                 m,
     183                 :            :                                 mounts,
     184                 :            :                                 n_mounts,
     185                 :            :                                 kill_signal);
     186         [ #  # ]:          0 :                 if (r < 0)
     187                 :          0 :                         return r;
     188                 :            : 
     189         [ #  # ]:          0 :                 if (properties_message) {
     190                 :          0 :                         r = sd_bus_message_copy(m, properties_message, true);
     191         [ #  # ]:          0 :                         if (r < 0)
     192         [ #  # ]:          0 :                                 return bus_log_create_error(r);
     193                 :            :                 }
     194                 :            : 
     195                 :          0 :                 r = bus_append_unit_property_assignment_many(m, UNIT_SERVICE, properties);
     196         [ #  # ]:          0 :                 if (r < 0)
     197                 :          0 :                         return r;
     198                 :            : 
     199                 :          0 :                 r = sd_bus_message_close_container(m);
     200         [ #  # ]:          0 :                 if (r < 0)
     201         [ #  # ]:          0 :                         return bus_log_create_error(r);
     202                 :            : 
     203                 :          0 :                 r = sd_bus_call(bus, m, 0, &error, NULL);
     204                 :            :         }
     205                 :            : 
     206         [ #  # ]:          0 :         if (r < 0)
     207         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
     208                 :            : 
     209                 :          0 :         return 0;
     210                 :            : }
     211                 :            : 
     212                 :          0 : int terminate_machine(
     213                 :            :                 sd_bus *bus,
     214                 :            :                 const char *machine_name) {
     215                 :            : 
     216                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
     217                 :            :         int r;
     218                 :            : 
     219         [ #  # ]:          0 :         assert(bus);
     220                 :            : 
     221                 :          0 :         r = sd_bus_call_method(
     222                 :            :                         bus,
     223                 :            :                         "org.freedesktop.machine1",
     224                 :            :                         "/org/freedesktop/machine1",
     225                 :            :                         "org.freedesktop.machine1.Manager",
     226                 :            :                         "TerminateMachine",
     227                 :            :                         &error,
     228                 :            :                         NULL,
     229                 :            :                         "s",
     230                 :            :                         machine_name);
     231         [ #  # ]:          0 :         if (r < 0)
     232         [ #  # ]:          0 :                 log_debug("Failed to terminate machine: %s", bus_error_message(&error, r));
     233                 :            : 
     234                 :          0 :         return 0;
     235                 :            : }
     236                 :            : 
     237                 :          0 : int allocate_scope(
     238                 :            :                 sd_bus *bus,
     239                 :            :                 const char *machine_name,
     240                 :            :                 pid_t pid,
     241                 :            :                 const char *slice,
     242                 :            :                 CustomMount *mounts,
     243                 :            :                 unsigned n_mounts,
     244                 :            :                 int kill_signal,
     245                 :            :                 char **properties,
     246                 :            :                 sd_bus_message *properties_message) {
     247                 :            : 
     248                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
     249                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
     250                 :          0 :         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
     251                 :          0 :         _cleanup_free_ char *scope = NULL;
     252                 :            :         const char *description, *object;
     253                 :            :         int r;
     254                 :            : 
     255         [ #  # ]:          0 :         assert(bus);
     256                 :            : 
     257                 :          0 :         r = bus_wait_for_jobs_new(bus, &w);
     258         [ #  # ]:          0 :         if (r < 0)
     259         [ #  # ]:          0 :                 return log_error_errno(r, "Could not watch job: %m");
     260                 :            : 
     261                 :          0 :         r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope);
     262         [ #  # ]:          0 :         if (r < 0)
     263         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to mangle scope name: %m");
     264                 :            : 
     265                 :          0 :         r = sd_bus_message_new_method_call(
     266                 :            :                         bus,
     267                 :            :                         &m,
     268                 :            :                         "org.freedesktop.systemd1",
     269                 :            :                         "/org/freedesktop/systemd1",
     270                 :            :                         "org.freedesktop.systemd1.Manager",
     271                 :            :                         "StartTransientUnit");
     272         [ #  # ]:          0 :         if (r < 0)
     273         [ #  # ]:          0 :                 return bus_log_create_error(r);
     274                 :            : 
     275                 :          0 :         r = sd_bus_message_append(m, "ss", scope, "fail");
     276         [ #  # ]:          0 :         if (r < 0)
     277         [ #  # ]:          0 :                 return bus_log_create_error(r);
     278                 :            : 
     279                 :            :         /* Properties */
     280                 :          0 :         r = sd_bus_message_open_container(m, 'a', "(sv)");
     281         [ #  # ]:          0 :         if (r < 0)
     282         [ #  # ]:          0 :                 return bus_log_create_error(r);
     283                 :            : 
     284   [ #  #  #  #  :          0 :         description = strjoina("Container ", machine_name);
          #  #  #  #  #  
                #  #  # ]
     285                 :            : 
     286         [ #  # ]:          0 :         r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)(sv)",
     287                 :            :                                   "PIDs", "au", 1, pid,
     288                 :            :                                   "Description", "s", description,
     289                 :            :                                   "Delegate", "b", 1,
     290                 :            :                                   "CollectMode", "s", "inactive-or-failed",
     291                 :            :                                   "AddRef", "b", 1,
     292                 :          0 :                                   "Slice", "s", isempty(slice) ? SPECIAL_MACHINE_SLICE : slice);
     293         [ #  # ]:          0 :         if (r < 0)
     294         [ #  # ]:          0 :                 return bus_log_create_error(r);
     295                 :            : 
     296                 :          0 :         r = append_controller_property(bus, m);
     297         [ #  # ]:          0 :         if (r < 0)
     298                 :          0 :                 return r;
     299                 :            : 
     300         [ #  # ]:          0 :         if (properties_message) {
     301                 :          0 :                 r = sd_bus_message_copy(m, properties_message, true);
     302         [ #  # ]:          0 :                 if (r < 0)
     303         [ #  # ]:          0 :                         return bus_log_create_error(r);
     304                 :            :         }
     305                 :            : 
     306                 :          0 :         r = append_machine_properties(
     307                 :            :                         m,
     308                 :            :                         mounts,
     309                 :            :                         n_mounts,
     310                 :            :                         kill_signal);
     311         [ #  # ]:          0 :         if (r < 0)
     312                 :          0 :                 return r;
     313                 :            : 
     314                 :          0 :         r = bus_append_unit_property_assignment_many(m, UNIT_SCOPE, properties);
     315         [ #  # ]:          0 :         if (r < 0)
     316                 :          0 :                 return r;
     317                 :            : 
     318                 :          0 :         r = sd_bus_message_close_container(m);
     319         [ #  # ]:          0 :         if (r < 0)
     320         [ #  # ]:          0 :                 return bus_log_create_error(r);
     321                 :            : 
     322                 :            :         /* No auxiliary units */
     323                 :          0 :         r = sd_bus_message_append(
     324                 :            :                         m,
     325                 :            :                         "a(sa(sv))",
     326                 :            :                         0);
     327         [ #  # ]:          0 :         if (r < 0)
     328         [ #  # ]:          0 :                 return bus_log_create_error(r);
     329                 :            : 
     330                 :          0 :         r = sd_bus_call(bus, m, 0, &error, &reply);
     331         [ #  # ]:          0 :         if (r < 0)
     332         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to allocate scope: %s", bus_error_message(&error, r));
     333                 :            : 
     334                 :          0 :         r = sd_bus_message_read(reply, "o", &object);
     335         [ #  # ]:          0 :         if (r < 0)
     336         [ #  # ]:          0 :                 return bus_log_parse_error(r);
     337                 :            : 
     338                 :          0 :         r = bus_wait_for_jobs_one(w, object, false);
     339         [ #  # ]:          0 :         if (r < 0)
     340                 :          0 :                 return r;
     341                 :            : 
     342                 :          0 :         return 0;
     343                 :            : }
     344                 :            : 
     345                 :          0 : int terminate_scope(
     346                 :            :                 sd_bus *bus,
     347                 :            :                 const char *machine_name) {
     348                 :            : 
     349                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
     350                 :          0 :         _cleanup_free_ char *scope = NULL;
     351                 :            :         int r;
     352                 :            : 
     353                 :          0 :         r = unit_name_mangle_with_suffix(machine_name, 0, ".scope", &scope);
     354         [ #  # ]:          0 :         if (r < 0)
     355         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to mangle scope name: %m");
     356                 :            : 
     357                 :          0 :         r = sd_bus_call_method(
     358                 :            :                         bus,
     359                 :            :                         "org.freedesktop.systemd1",
     360                 :            :                         "/org/freedesktop/systemd1",
     361                 :            :                         "org.freedesktop.systemd1.Manager",
     362                 :            :                         "AbandonScope",
     363                 :            :                         &error,
     364                 :            :                         NULL,
     365                 :            :                         "s",
     366                 :            :                         scope);
     367         [ #  # ]:          0 :         if (r < 0) {
     368         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to abandon scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
     369                 :          0 :                 sd_bus_error_free(&error);
     370                 :            :         }
     371                 :            : 
     372                 :          0 :         r = sd_bus_call_method(
     373                 :            :                         bus,
     374                 :            :                         "org.freedesktop.systemd1",
     375                 :            :                         "/org/freedesktop/systemd1",
     376                 :            :                         "org.freedesktop.systemd1.Manager",
     377                 :            :                         "KillUnit",
     378                 :            :                         &error,
     379                 :            :                         NULL,
     380                 :            :                         "ssi",
     381                 :            :                         scope,
     382                 :            :                         "all",
     383                 :            :                         (int32_t) SIGKILL);
     384         [ #  # ]:          0 :         if (r < 0) {
     385         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to SIGKILL scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
     386                 :          0 :                 sd_bus_error_free(&error);
     387                 :            :         }
     388                 :            : 
     389                 :          0 :         r = sd_bus_call_method(
     390                 :            :                         bus,
     391                 :            :                         "org.freedesktop.systemd1",
     392                 :            :                         "/org/freedesktop/systemd1",
     393                 :            :                         "org.freedesktop.systemd1.Manager",
     394                 :            :                         "UnrefUnit",
     395                 :            :                         &error,
     396                 :            :                         NULL,
     397                 :            :                         "s",
     398                 :            :                         scope);
     399         [ #  # ]:          0 :         if (r < 0)
     400         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to drop reference to scope '%s', ignoring: %s", scope, bus_error_message(&error, r));
     401                 :            : 
     402                 :          0 :         return 0;
     403                 :            : }

Generated by: LCOV version 1.14