LCOV - code coverage report
Current view: top level - core - target.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 47 87 54.0 %
Date: 2019-08-23 13:36:53 Functions: 6 11 54.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 31 90 34.4 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "dbus-target.h"
       4                 :            : #include "dbus-unit.h"
       5                 :            : #include "log.h"
       6                 :            : #include "serialize.h"
       7                 :            : #include "special.h"
       8                 :            : #include "string-util.h"
       9                 :            : #include "target.h"
      10                 :            : #include "unit-name.h"
      11                 :            : #include "unit.h"
      12                 :            : 
      13                 :            : static const UnitActiveState state_translation_table[_TARGET_STATE_MAX] = {
      14                 :            :         [TARGET_DEAD] = UNIT_INACTIVE,
      15                 :            :         [TARGET_ACTIVE] = UNIT_ACTIVE
      16                 :            : };
      17                 :            : 
      18                 :         72 : static void target_set_state(Target *t, TargetState state) {
      19                 :            :         TargetState old_state;
      20         [ -  + ]:         72 :         assert(t);
      21                 :            : 
      22         [ +  - ]:         72 :         if (t->state != state)
      23         [ +  - ]:         72 :                 bus_unit_send_pending_change_signal(UNIT(t), false);
      24                 :            : 
      25                 :         72 :         old_state = t->state;
      26                 :         72 :         t->state = state;
      27                 :            : 
      28         [ +  - ]:         72 :         if (state != old_state)
      29   [ -  +  #  # ]:         72 :                 log_debug("%s changed %s -> %s",
      30                 :            :                           UNIT(t)->id,
      31                 :            :                           target_state_to_string(old_state),
      32                 :            :                           target_state_to_string(state));
      33                 :            : 
      34         [ +  - ]:         72 :         unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0);
      35                 :         72 : }
      36                 :            : 
      37                 :        164 : static int target_add_default_dependencies(Target *t) {
      38                 :            : 
      39                 :            :         static const UnitDependency deps[] = {
      40                 :            :                 UNIT_REQUIRES,
      41                 :            :                 UNIT_REQUISITE,
      42                 :            :                 UNIT_WANTS,
      43                 :            :                 UNIT_BINDS_TO,
      44                 :            :                 UNIT_PART_OF
      45                 :            :         };
      46                 :            : 
      47                 :            :         int r;
      48                 :            :         unsigned k;
      49                 :            : 
      50         [ -  + ]:        164 :         assert(t);
      51                 :            : 
      52   [ +  -  +  + ]:        164 :         if (!UNIT(t)->default_dependencies)
      53                 :         32 :                 return 0;
      54                 :            : 
      55                 :            :         /* Imply ordering for requirement dependencies on target units. Note that when the user created a contradicting
      56                 :            :          * ordering manually we won't add anything in here to make sure we don't create a loop. */
      57                 :            : 
      58         [ +  + ]:        792 :         for (k = 0; k < ELEMENTSOF(deps); k++) {
      59                 :            :                 Unit *other;
      60                 :            :                 Iterator i;
      61                 :            :                 void *v;
      62                 :            : 
      63   [ +  -  +  + ]:       1012 :                 HASHMAP_FOREACH_KEY(v, other, UNIT(t)->dependencies[deps[k]], i) {
      64         [ +  - ]:        352 :                         r = unit_add_default_target_dependency(other, UNIT(t));
      65         [ -  + ]:        352 :                         if (r < 0)
      66                 :          0 :                                 return r;
      67                 :            :                 }
      68                 :            :         }
      69                 :            : 
      70   [ +  -  -  + ]:        132 :         if (unit_has_name(UNIT(t), SPECIAL_SHUTDOWN_TARGET))
      71                 :          0 :                 return 0;
      72                 :            : 
      73                 :            :         /* Make sure targets are unloaded on shutdown */
      74         [ +  - ]:        132 :         return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
      75                 :            : }
      76                 :            : 
      77                 :        440 : static int target_load(Unit *u) {
      78                 :        440 :         Target *t = TARGET(u);
      79                 :            :         int r;
      80                 :            : 
      81         [ -  + ]:        440 :         assert(t);
      82                 :            : 
      83                 :        440 :         r = unit_load_fragment_and_dropin(u);
      84         [ +  + ]:        440 :         if (r < 0)
      85                 :        276 :                 return r;
      86                 :            : 
      87                 :            :         /* This is a new unit? Then let's add in some extras */
      88         [ +  - ]:        164 :         if (u->load_state == UNIT_LOADED) {
      89                 :        164 :                 r = target_add_default_dependencies(t);
      90         [ -  + ]:        164 :                 if (r < 0)
      91                 :          0 :                         return r;
      92                 :            :         }
      93                 :            : 
      94                 :        164 :         return 0;
      95                 :            : }
      96                 :            : 
      97                 :          0 : static int target_coldplug(Unit *u) {
      98                 :          0 :         Target *t = TARGET(u);
      99                 :            : 
     100         [ #  # ]:          0 :         assert(t);
     101         [ #  # ]:          0 :         assert(t->state == TARGET_DEAD);
     102                 :            : 
     103         [ #  # ]:          0 :         if (t->deserialized_state != t->state)
     104                 :          0 :                 target_set_state(t, t->deserialized_state);
     105                 :            : 
     106                 :          0 :         return 0;
     107                 :            : }
     108                 :            : 
     109                 :        120 : static void target_dump(Unit *u, FILE *f, const char *prefix) {
     110                 :        120 :         Target *t = TARGET(u);
     111                 :            : 
     112         [ -  + ]:        120 :         assert(t);
     113         [ -  + ]:        120 :         assert(f);
     114                 :            : 
     115                 :        120 :         fprintf(f,
     116                 :            :                 "%sTarget State: %s\n",
     117                 :            :                 prefix, target_state_to_string(t->state));
     118                 :        120 : }
     119                 :            : 
     120                 :         72 : static int target_start(Unit *u) {
     121                 :         72 :         Target *t = TARGET(u);
     122                 :            :         int r;
     123                 :            : 
     124         [ -  + ]:         72 :         assert(t);
     125         [ -  + ]:         72 :         assert(t->state == TARGET_DEAD);
     126                 :            : 
     127                 :         72 :         r = unit_acquire_invocation_id(u);
     128         [ -  + ]:         72 :         if (r < 0)
     129                 :          0 :                 return r;
     130                 :            : 
     131                 :         72 :         target_set_state(t, TARGET_ACTIVE);
     132                 :         72 :         return 1;
     133                 :            : }
     134                 :            : 
     135                 :          0 : static int target_stop(Unit *u) {
     136                 :          0 :         Target *t = TARGET(u);
     137                 :            : 
     138         [ #  # ]:          0 :         assert(t);
     139         [ #  # ]:          0 :         assert(t->state == TARGET_ACTIVE);
     140                 :            : 
     141                 :          0 :         target_set_state(t, TARGET_DEAD);
     142                 :          0 :         return 1;
     143                 :            : }
     144                 :            : 
     145                 :          0 : static int target_serialize(Unit *u, FILE *f, FDSet *fds) {
     146                 :          0 :         Target *s = TARGET(u);
     147                 :            : 
     148         [ #  # ]:          0 :         assert(s);
     149         [ #  # ]:          0 :         assert(f);
     150         [ #  # ]:          0 :         assert(fds);
     151                 :            : 
     152                 :          0 :         (void) serialize_item(f, "state", target_state_to_string(s->state));
     153                 :          0 :         return 0;
     154                 :            : }
     155                 :            : 
     156                 :          0 : static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
     157                 :          0 :         Target *s = TARGET(u);
     158                 :            : 
     159         [ #  # ]:          0 :         assert(u);
     160         [ #  # ]:          0 :         assert(key);
     161         [ #  # ]:          0 :         assert(value);
     162         [ #  # ]:          0 :         assert(fds);
     163                 :            : 
     164         [ #  # ]:          0 :         if (streq(key, "state")) {
     165                 :            :                 TargetState state;
     166                 :            : 
     167                 :          0 :                 state = target_state_from_string(value);
     168         [ #  # ]:          0 :                 if (state < 0)
     169         [ #  # ]:          0 :                         log_debug("Failed to parse state value %s", value);
     170                 :            :                 else
     171                 :          0 :                         s->deserialized_state = state;
     172                 :            : 
     173                 :            :         } else
     174         [ #  # ]:          0 :                 log_debug("Unknown serialization key '%s'", key);
     175                 :            : 
     176                 :          0 :         return 0;
     177                 :            : }
     178                 :            : 
     179                 :       3068 : _pure_ static UnitActiveState target_active_state(Unit *u) {
     180         [ -  + ]:       3068 :         assert(u);
     181                 :            : 
     182                 :       3068 :         return state_translation_table[TARGET(u)->state];
     183                 :            : }
     184                 :            : 
     185                 :          0 : _pure_ static const char *target_sub_state_to_string(Unit *u) {
     186         [ #  # ]:          0 :         assert(u);
     187                 :            : 
     188                 :          0 :         return target_state_to_string(TARGET(u)->state);
     189                 :            : }
     190                 :            : 
     191                 :            : const UnitVTable target_vtable = {
     192                 :            :         .object_size = sizeof(Target),
     193                 :            : 
     194                 :            :         .sections =
     195                 :            :                 "Unit\0"
     196                 :            :                 "Target\0"
     197                 :            :                 "Install\0",
     198                 :            : 
     199                 :            :         .load = target_load,
     200                 :            :         .coldplug = target_coldplug,
     201                 :            : 
     202                 :            :         .dump = target_dump,
     203                 :            : 
     204                 :            :         .start = target_start,
     205                 :            :         .stop = target_stop,
     206                 :            : 
     207                 :            :         .serialize = target_serialize,
     208                 :            :         .deserialize_item = target_deserialize_item,
     209                 :            : 
     210                 :            :         .active_state = target_active_state,
     211                 :            :         .sub_state_to_string = target_sub_state_to_string,
     212                 :            : 
     213                 :            :         .bus_vtable = bus_target_vtable,
     214                 :            : 
     215                 :            :         .status_message_formats = {
     216                 :            :                 .finished_start_job = {
     217                 :            :                         [JOB_DONE]       = "Reached target %s.",
     218                 :            :                 },
     219                 :            :                 .finished_stop_job = {
     220                 :            :                         [JOB_DONE]       = "Stopped target %s.",
     221                 :            :                 },
     222                 :            :         },
     223                 :            : };

Generated by: LCOV version 1.14