LCOV - code coverage report
Current view: top level - shared - generator.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 11 193 5.7 %
Date: 2019-08-23 13:36:53 Functions: 2 12 16.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 20 298 6.7 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <unistd.h>
       5                 :            : 
       6                 :            : #include "alloc-util.h"
       7                 :            : #include "dropin.h"
       8                 :            : #include "escape.h"
       9                 :            : #include "fd-util.h"
      10                 :            : #include "fileio.h"
      11                 :            : #include "fstab-util.h"
      12                 :            : #include "generator.h"
      13                 :            : #include "log.h"
      14                 :            : #include "macro.h"
      15                 :            : #include "mkdir.h"
      16                 :            : #include "path-util.h"
      17                 :            : #include "special.h"
      18                 :            : #include "specifier.h"
      19                 :            : #include "string-util.h"
      20                 :            : #include "time-util.h"
      21                 :            : #include "unit-name.h"
      22                 :            : #include "util.h"
      23                 :            : 
      24                 :          0 : int generator_open_unit_file(
      25                 :            :                 const char *dest,
      26                 :            :                 const char *source,
      27                 :            :                 const char *name,
      28                 :            :                 FILE **file) {
      29                 :            : 
      30                 :            :         const char *unit;
      31                 :            :         FILE *f;
      32                 :            :         int r;
      33                 :            : 
      34   [ #  #  #  #  :          0 :         unit = prefix_roota(dest, name);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      35                 :            : 
      36                 :          0 :         r = fopen_unlocked(unit, "wxe", &f);
      37         [ #  # ]:          0 :         if (r < 0) {
      38   [ #  #  #  # ]:          0 :                 if (source && r == -EEXIST)
      39         [ #  # ]:          0 :                         return log_error_errno(r,
      40                 :            :                                                "Failed to create unit file %s, as it already exists. Duplicate entry in %s?",
      41                 :            :                                                unit, source);
      42                 :            :                 else
      43         [ #  # ]:          0 :                         return log_error_errno(r,
      44                 :            :                                                "Failed to create unit file %s: %m",
      45                 :            :                                                unit);
      46                 :            :         }
      47                 :            : 
      48                 :          0 :         fprintf(f,
      49                 :            :                 "# Automatically generated by %s\n\n",
      50                 :            :                 program_invocation_short_name);
      51                 :            : 
      52                 :          0 :         *file = f;
      53                 :          0 :         return 0;
      54                 :            : }
      55                 :            : 
      56                 :        208 : int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src) {
      57                 :            :         /* Adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute)
      58                 :            :          * or ../<src> (otherwise). */
      59                 :            : 
      60                 :            :         const char *from, *to;
      61                 :            : 
      62   [ +  -  +  +  :       1040 :         from = path_is_absolute(src) ? src : strjoina("../", src);
          +  -  -  +  -  
             +  +  +  +  
                      - ]
      63   [ +  +  +  -  :       3120 :         to = strjoina(dir, "/", dst, ".", dep_type, "/", basename(src));
          -  +  -  +  +  
                +  +  - ]
      64                 :            : 
      65                 :        208 :         mkdir_parents_label(to, 0755);
      66         [ +  + ]:        208 :         if (symlink(from, to) < 0)
      67         [ -  + ]:        100 :                 if (errno != EEXIST)
      68         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to create symlink \"%s\": %m", to);
      69                 :            : 
      70                 :        208 :         return 0;
      71                 :            : }
      72                 :            : 
      73                 :          0 : static int write_fsck_sysroot_service(const char *dir, const char *what) {
      74                 :          0 :         _cleanup_free_ char *device = NULL, *escaped = NULL, *escaped2 = NULL;
      75                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
      76                 :            :         const char *unit;
      77                 :            :         int r;
      78                 :            : 
      79                 :          0 :         escaped = specifier_escape(what);
      80         [ #  # ]:          0 :         if (!escaped)
      81                 :          0 :                 return log_oom();
      82                 :            : 
      83                 :          0 :         escaped2 = cescape(escaped);
      84         [ #  # ]:          0 :         if (!escaped2)
      85                 :          0 :                 return log_oom();
      86                 :            : 
      87   [ #  #  #  #  :          0 :         unit = strjoina(dir, "/"SPECIAL_FSCK_ROOT_SERVICE);
          #  #  #  #  #  
                #  #  # ]
      88         [ #  # ]:          0 :         log_debug("Creating %s", unit);
      89                 :            : 
      90                 :          0 :         r = unit_name_from_path(what, ".device", &device);
      91         [ #  # ]:          0 :         if (r < 0)
      92         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to convert device \"%s\" to unit name: %m", what);
      93                 :            : 
      94                 :          0 :         f = fopen(unit, "wxe");
      95         [ #  # ]:          0 :         if (!f)
      96         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
      97                 :            : 
      98                 :          0 :         fprintf(f,
      99                 :            :                 "# Automatically generated by %1$s\n\n"
     100                 :            :                 "[Unit]\n"
     101                 :            :                 "Description=File System Check on %2$s\n"
     102                 :            :                 "Documentation=man:systemd-fsck-root.service(8)\n"
     103                 :            :                 "DefaultDependencies=no\n"
     104                 :            :                 "BindsTo=%3$s\n"
     105                 :            :                 "Conflicts=shutdown.target\n"
     106                 :            :                 "After=initrd-root-device.target local-fs-pre.target %3$s\n"
     107                 :            :                 "Before=shutdown.target\n"
     108                 :            :                 "\n"
     109                 :            :                 "[Service]\n"
     110                 :            :                 "Type=oneshot\n"
     111                 :            :                 "RemainAfterExit=yes\n"
     112                 :            :                 "ExecStart=" SYSTEMD_FSCK_PATH " %4$s\n"
     113                 :            :                 "TimeoutSec=0\n",
     114                 :            :                 program_invocation_short_name,
     115                 :            :                 escaped,
     116                 :            :                 device,
     117                 :            :                 escaped2);
     118                 :            : 
     119                 :          0 :         r = fflush_and_check(f);
     120         [ #  # ]:          0 :         if (r < 0)
     121         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write unit file %s: %m", unit);
     122                 :            : 
     123                 :          0 :         return 0;
     124                 :            : }
     125                 :            : 
     126                 :          0 : int generator_write_fsck_deps(
     127                 :            :                 FILE *f,
     128                 :            :                 const char *dir,
     129                 :            :                 const char *what,
     130                 :            :                 const char *where,
     131                 :            :                 const char *fstype) {
     132                 :            : 
     133                 :            :         int r;
     134                 :            : 
     135         [ #  # ]:          0 :         assert(f);
     136         [ #  # ]:          0 :         assert(dir);
     137         [ #  # ]:          0 :         assert(what);
     138         [ #  # ]:          0 :         assert(where);
     139                 :            : 
     140         [ #  # ]:          0 :         if (!is_device_path(what)) {
     141         [ #  # ]:          0 :                 log_warning("Checking was requested for \"%s\", but it is not a device.", what);
     142                 :          0 :                 return 0;
     143                 :            :         }
     144                 :            : 
     145   [ #  #  #  # ]:          0 :         if (!isempty(fstype) && !streq(fstype, "auto")) {
     146                 :          0 :                 r = fsck_exists(fstype);
     147         [ #  # ]:          0 :                 if (r < 0)
     148         [ #  # ]:          0 :                         log_warning_errno(r, "Checking was requested for %s, but couldn't detect if fsck.%s may be used, proceeding: %m", what, fstype);
     149         [ #  # ]:          0 :                 else if (r == 0) {
     150                 :            :                         /* treat missing check as essentially OK */
     151         [ #  # ]:          0 :                         log_debug("Checking was requested for %s, but fsck.%s does not exist.", what, fstype);
     152                 :          0 :                         return 0;
     153                 :            :                 }
     154                 :            :         }
     155                 :            : 
     156         [ #  # ]:          0 :         if (path_equal(where, "/")) {
     157                 :            :                 const char *lnk;
     158                 :            : 
     159   [ #  #  #  #  :          0 :                 lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/" SPECIAL_FSCK_ROOT_SERVICE);
          #  #  #  #  #  
                #  #  # ]
     160                 :            : 
     161                 :          0 :                 (void) mkdir_parents(lnk, 0755);
     162         [ #  # ]:          0 :                 if (symlink(SYSTEM_DATA_UNIT_PATH "/" SPECIAL_FSCK_ROOT_SERVICE, lnk) < 0)
     163         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
     164                 :            : 
     165                 :            :         } else {
     166         [ #  # ]:          0 :                 _cleanup_free_ char *_fsck = NULL;
     167                 :            :                 const char *fsck, *dep;
     168                 :            : 
     169   [ #  #  #  # ]:          0 :                 if (in_initrd() && path_equal(where, "/sysroot")) {
     170                 :          0 :                         r = write_fsck_sysroot_service(dir, what);
     171         [ #  # ]:          0 :                         if (r < 0)
     172                 :          0 :                                 return r;
     173                 :            : 
     174                 :          0 :                         fsck = SPECIAL_FSCK_ROOT_SERVICE;
     175                 :          0 :                         dep = "Requires";
     176                 :            :                 } else {
     177                 :            :                         /* When this is /usr, then let's add a Wants= dependency, otherwise a Requires=
     178                 :            :                          * dependency. Why? We can't possibly unmount /usr during shutdown, but if we have a
     179                 :            :                          * Requires= from /usr onto a fsck@.service unit and that unit is shut down, then
     180                 :            :                          * we'd have to unmount /usr too.  */
     181                 :            : 
     182   [ #  #  #  # ]:          0 :                         dep = !in_initrd() && path_equal(where, "/usr") ? "Wants" : "Requires";
     183                 :            : 
     184                 :          0 :                         r = unit_name_from_path_instance("systemd-fsck", what, ".service", &_fsck);
     185         [ #  # ]:          0 :                         if (r < 0)
     186         [ #  # ]:          0 :                                 return log_error_errno(r, "Failed to create fsck service name: %m");
     187                 :            : 
     188                 :          0 :                         fsck = _fsck;
     189                 :            :                 }
     190                 :            : 
     191                 :          0 :                 fprintf(f,
     192                 :            :                         "%1$s=%2$s\n"
     193                 :            :                         "After=%2$s\n",
     194                 :            :                         dep, fsck);
     195                 :            :         }
     196                 :            : 
     197                 :          0 :         return 0;
     198                 :            : }
     199                 :            : 
     200                 :          0 : int generator_write_timeouts(
     201                 :            :                 const char *dir,
     202                 :            :                 const char *what,
     203                 :            :                 const char *where,
     204                 :            :                 const char *opts,
     205                 :            :                 char **filtered) {
     206                 :            : 
     207                 :            :         /* Configure how long we wait for a device that backs a mount point or a
     208                 :            :          * swap partition to show up. This is useful to support endless device timeouts
     209                 :            :          * for devices that show up only after user input, like crypto devices. */
     210                 :            : 
     211                 :          0 :         _cleanup_free_ char *node = NULL, *unit = NULL, *timeout = NULL;
     212                 :            :         usec_t u;
     213                 :            :         int r;
     214                 :            : 
     215                 :          0 :         r = fstab_filter_options(opts, "comment=systemd.device-timeout\0"
     216                 :            :                                        "x-systemd.device-timeout\0",
     217                 :            :                                  NULL, &timeout, filtered);
     218         [ #  # ]:          0 :         if (r <= 0)
     219                 :          0 :                 return r;
     220                 :            : 
     221                 :          0 :         r = parse_sec_fix_0(timeout, &u);
     222         [ #  # ]:          0 :         if (r < 0) {
     223         [ #  # ]:          0 :                 log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
     224                 :          0 :                 return 0;
     225                 :            :         }
     226                 :            : 
     227                 :          0 :         node = fstab_node_to_udev_node(what);
     228         [ #  # ]:          0 :         if (!node)
     229                 :          0 :                 return log_oom();
     230         [ #  # ]:          0 :         if (!is_device_path(node)) {
     231         [ #  # ]:          0 :                 log_warning("x-systemd.device-timeout ignored for %s", what);
     232                 :          0 :                 return 0;
     233                 :            :         }
     234                 :            : 
     235                 :          0 :         r = unit_name_from_path(node, ".device", &unit);
     236         [ #  # ]:          0 :         if (r < 0)
     237         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit name from path: %m");
     238                 :            : 
     239                 :          0 :         return write_drop_in_format(dir, unit, 50, "device-timeout",
     240                 :            :                                     "# Automatically generated by %s\n\n"
     241                 :            :                                     "[Unit]\n"
     242                 :            :                                     "JobRunningTimeoutSec=%s",
     243                 :            :                                     program_invocation_short_name,
     244                 :            :                                     timeout);
     245                 :            : }
     246                 :            : 
     247                 :          0 : int generator_write_device_deps(
     248                 :            :                 const char *dir,
     249                 :            :                 const char *what,
     250                 :            :                 const char *where,
     251                 :            :                 const char *opts) {
     252                 :            : 
     253                 :            :         /* fstab records that specify _netdev option should apply the network
     254                 :            :          * ordering on the actual device depending on network connection. If we
     255                 :            :          * are not mounting real device (NFS, CIFS), we rely on _netdev effect
     256                 :            :          * on the mount unit itself. */
     257                 :            : 
     258                 :          0 :         _cleanup_free_ char *node = NULL, *unit = NULL;
     259                 :            :         int r;
     260                 :            : 
     261         [ #  # ]:          0 :         if (!fstab_test_option(opts, "_netdev\0"))
     262                 :          0 :                 return 0;
     263                 :            : 
     264                 :          0 :         node = fstab_node_to_udev_node(what);
     265         [ #  # ]:          0 :         if (!node)
     266                 :          0 :                 return log_oom();
     267                 :            : 
     268                 :            :         /* Nothing to apply dependencies to. */
     269         [ #  # ]:          0 :         if (!is_device_path(node))
     270                 :          0 :                 return 0;
     271                 :            : 
     272                 :          0 :         r = unit_name_from_path(node, ".device", &unit);
     273         [ #  # ]:          0 :         if (r < 0)
     274         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
     275                 :            :                                        node);
     276                 :            : 
     277                 :            :         /* See mount_add_default_dependencies for explanation why we create such
     278                 :            :          * dependencies. */
     279                 :          0 :         return write_drop_in_format(dir, unit, 50, "netdev-dependencies",
     280                 :            :                                     "# Automatically generated by %s\n\n"
     281                 :            :                                     "[Unit]\n"
     282                 :            :                                     "After=" SPECIAL_NETWORK_ONLINE_TARGET " " SPECIAL_NETWORK_TARGET "\n"
     283                 :            :                                     "Wants=" SPECIAL_NETWORK_ONLINE_TARGET "\n",
     284                 :            :                                     program_invocation_short_name);
     285                 :            : }
     286                 :            : 
     287                 :          0 : int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
     288                 :          0 :         _cleanup_free_ char *unit = NULL;
     289                 :            :         int r;
     290                 :            : 
     291                 :          0 :         r = unit_name_from_path(what, ".device", &unit);
     292         [ #  # ]:          0 :         if (r < 0)
     293         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
     294                 :            :                                        what);
     295                 :            : 
     296                 :          0 :         return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
     297                 :            :                                     "# Automatically generated by %s\n\n"
     298                 :            :                                     "[Unit]\n"
     299                 :            :                                     "Requires=%s\n"
     300                 :            :                                     "After=%s",
     301                 :            :                                     program_invocation_short_name,
     302                 :            :                                     unit,
     303                 :            :                                     unit);
     304                 :            : }
     305                 :            : 
     306                 :          0 : int generator_hook_up_mkswap(
     307                 :            :                 const char *dir,
     308                 :            :                 const char *what) {
     309                 :            : 
     310                 :          0 :         _cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
     311                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
     312                 :            :         const char *unit_file;
     313                 :            :         int r;
     314                 :            : 
     315                 :          0 :         node = fstab_node_to_udev_node(what);
     316         [ #  # ]:          0 :         if (!node)
     317                 :          0 :                 return log_oom();
     318                 :            : 
     319                 :            :         /* Nothing to work on. */
     320         [ #  # ]:          0 :         if (!is_device_path(node))
     321         [ #  # ]:          0 :                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     322                 :            :                                        "Cannot format something that is not a device node: %s",
     323                 :            :                                        node);
     324                 :            : 
     325                 :          0 :         r = unit_name_from_path_instance("systemd-mkswap", node, ".service", &unit);
     326         [ #  # ]:          0 :         if (r < 0)
     327         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
     328                 :            :                                        node);
     329                 :            : 
     330   [ #  #  #  #  :          0 :         unit_file = prefix_roota(dir, unit);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     331         [ #  # ]:          0 :         log_debug("Creating %s", unit_file);
     332                 :            : 
     333                 :          0 :         escaped = cescape(node);
     334         [ #  # ]:          0 :         if (!escaped)
     335                 :          0 :                 return log_oom();
     336                 :            : 
     337                 :          0 :         r = unit_name_from_path(what, ".swap", &where_unit);
     338         [ #  # ]:          0 :         if (r < 0)
     339         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
     340                 :            :                                        what);
     341                 :            : 
     342                 :          0 :         f = fopen(unit_file, "wxe");
     343         [ #  # ]:          0 :         if (!f)
     344         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to create unit file %s: %m",
     345                 :            :                                        unit_file);
     346                 :            : 
     347                 :          0 :         fprintf(f,
     348                 :            :                 "# Automatically generated by %s\n\n"
     349                 :            :                 "[Unit]\n"
     350                 :            :                 "Description=Make Swap on %%f\n"
     351                 :            :                 "Documentation=man:systemd-mkswap@.service(8)\n"
     352                 :            :                 "DefaultDependencies=no\n"
     353                 :            :                 "BindsTo=%%i.device\n"
     354                 :            :                 "Conflicts=shutdown.target\n"
     355                 :            :                 "After=%%i.device\n"
     356                 :            :                 "Before=shutdown.target %s\n"
     357                 :            :                 "\n"
     358                 :            :                 "[Service]\n"
     359                 :            :                 "Type=oneshot\n"
     360                 :            :                 "RemainAfterExit=yes\n"
     361                 :            :                 "ExecStart="SYSTEMD_MAKEFS_PATH " swap %s\n"
     362                 :            :                 "TimeoutSec=0\n",
     363                 :            :                 program_invocation_short_name,
     364                 :            :                 where_unit,
     365                 :            :                 escaped);
     366                 :            : 
     367                 :          0 :         r = fflush_and_check(f);
     368         [ #  # ]:          0 :         if (r < 0)
     369         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write unit file %s: %m", unit_file);
     370                 :            : 
     371                 :          0 :         return generator_add_symlink(dir, where_unit, "requires", unit);
     372                 :            : }
     373                 :            : 
     374                 :          0 : int generator_hook_up_mkfs(
     375                 :            :                 const char *dir,
     376                 :            :                 const char *what,
     377                 :            :                 const char *where,
     378                 :            :                 const char *type) {
     379                 :            : 
     380                 :          0 :         _cleanup_free_ char *node = NULL, *unit = NULL, *escaped = NULL, *where_unit = NULL;
     381                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
     382                 :            :         const char *unit_file;
     383                 :            :         int r;
     384                 :            : 
     385                 :          0 :         node = fstab_node_to_udev_node(what);
     386         [ #  # ]:          0 :         if (!node)
     387                 :          0 :                 return log_oom();
     388                 :            : 
     389                 :            :         /* Nothing to work on. */
     390         [ #  # ]:          0 :         if (!is_device_path(node))
     391         [ #  # ]:          0 :                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     392                 :            :                                        "Cannot format something that is not a device node: %s",
     393                 :            :                                        node);
     394                 :            : 
     395   [ #  #  #  # ]:          0 :         if (!type || streq(type, "auto"))
     396         [ #  # ]:          0 :                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
     397                 :            :                                        "Cannot format partition %s, filesystem type is not specified",
     398                 :            :                                        node);
     399                 :            : 
     400                 :          0 :         r = unit_name_from_path_instance("systemd-makefs", node, ".service", &unit);
     401         [ #  # ]:          0 :         if (r < 0)
     402         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
     403                 :            :                                        node);
     404                 :            : 
     405   [ #  #  #  #  :          0 :         unit_file = prefix_roota(dir, unit);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     406         [ #  # ]:          0 :         log_debug("Creating %s", unit_file);
     407                 :            : 
     408                 :          0 :         escaped = cescape(node);
     409         [ #  # ]:          0 :         if (!escaped)
     410                 :          0 :                 return log_oom();
     411                 :            : 
     412                 :          0 :         r = unit_name_from_path(where, ".mount", &where_unit);
     413         [ #  # ]:          0 :         if (r < 0)
     414         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
     415                 :            :                                        where);
     416                 :            : 
     417                 :          0 :         f = fopen(unit_file, "wxe");
     418         [ #  # ]:          0 :         if (!f)
     419         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to create unit file %s: %m",
     420                 :            :                                        unit_file);
     421                 :            : 
     422                 :          0 :         fprintf(f,
     423                 :            :                 "# Automatically generated by %s\n\n"
     424                 :            :                 "[Unit]\n"
     425                 :            :                 "Description=Make File System on %%f\n"
     426                 :            :                 "Documentation=man:systemd-makefs@.service(8)\n"
     427                 :            :                 "DefaultDependencies=no\n"
     428                 :            :                 "BindsTo=%%i.device\n"
     429                 :            :                 "Conflicts=shutdown.target\n"
     430                 :            :                 "After=%%i.device\n"
     431                 :            :                 /* fsck might or might not be used, so let's be safe and order
     432                 :            :                  * ourselves before both systemd-fsck@.service and the mount unit. */
     433                 :            :                 "Before=shutdown.target systemd-fsck@%%i.service %s\n"
     434                 :            :                 "\n"
     435                 :            :                 "[Service]\n"
     436                 :            :                 "Type=oneshot\n"
     437                 :            :                 "RemainAfterExit=yes\n"
     438                 :            :                 "ExecStart="SYSTEMD_MAKEFS_PATH " %s %s\n"
     439                 :            :                 "TimeoutSec=0\n",
     440                 :            :                 program_invocation_short_name,
     441                 :            :                 where_unit,
     442                 :            :                 type,
     443                 :            :                 escaped);
     444                 :            :         // XXX: what about local-fs-pre.target?
     445                 :            : 
     446                 :          0 :         r = fflush_and_check(f);
     447         [ #  # ]:          0 :         if (r < 0)
     448         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write unit file %s: %m", unit_file);
     449                 :            : 
     450                 :          0 :         return generator_add_symlink(dir, where_unit, "requires", unit);
     451                 :            : }
     452                 :            : 
     453                 :          0 : int generator_hook_up_growfs(
     454                 :            :                 const char *dir,
     455                 :            :                 const char *where,
     456                 :            :                 const char *target) {
     457                 :            : 
     458                 :          0 :         _cleanup_free_ char *unit = NULL, *escaped = NULL, *where_unit = NULL;
     459                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
     460                 :            :         const char *unit_file;
     461                 :            :         int r;
     462                 :            : 
     463                 :          0 :         escaped = cescape(where);
     464         [ #  # ]:          0 :         if (!escaped)
     465                 :          0 :                 return log_oom();
     466                 :            : 
     467                 :          0 :         r = unit_name_from_path_instance("systemd-growfs", where, ".service", &unit);
     468         [ #  # ]:          0 :         if (r < 0)
     469         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit instance name from path \"%s\": %m",
     470                 :            :                                        where);
     471                 :            : 
     472                 :          0 :         r = unit_name_from_path(where, ".mount", &where_unit);
     473         [ #  # ]:          0 :         if (r < 0)
     474         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
     475                 :            :                                        where);
     476                 :            : 
     477   [ #  #  #  #  :          0 :         unit_file = prefix_roota(dir, unit);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     478         [ #  # ]:          0 :         log_debug("Creating %s", unit_file);
     479                 :            : 
     480                 :          0 :         f = fopen(unit_file, "wxe");
     481         [ #  # ]:          0 :         if (!f)
     482         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to create unit file %s: %m",
     483                 :            :                                        unit_file);
     484                 :            : 
     485                 :          0 :         fprintf(f,
     486                 :            :                 "# Automatically generated by %s\n\n"
     487                 :            :                 "[Unit]\n"
     488                 :            :                 "Description=Grow File System on %%f\n"
     489                 :            :                 "Documentation=man:systemd-growfs@.service(8)\n"
     490                 :            :                 "DefaultDependencies=no\n"
     491                 :            :                 "BindsTo=%%i.mount\n"
     492                 :            :                 "Conflicts=shutdown.target\n"
     493                 :            :                 "After=%%i.mount\n"
     494                 :            :                 "Before=shutdown.target %s\n"
     495                 :            :                 "\n"
     496                 :            :                 "[Service]\n"
     497                 :            :                 "Type=oneshot\n"
     498                 :            :                 "RemainAfterExit=yes\n"
     499                 :            :                 "ExecStart="SYSTEMD_GROWFS_PATH " %s\n"
     500                 :            :                 "TimeoutSec=0\n",
     501                 :            :                 program_invocation_short_name,
     502                 :            :                 target,
     503                 :            :                 escaped);
     504                 :            : 
     505                 :          0 :         return generator_add_symlink(dir, where_unit, "wants", unit);
     506                 :            : }
     507                 :            : 
     508                 :          0 : int generator_enable_remount_fs_service(const char *dir) {
     509                 :            :         /* Pull in systemd-remount-fs.service */
     510                 :          0 :         return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants",
     511                 :            :                                      SYSTEM_DATA_UNIT_PATH "/" SPECIAL_REMOUNT_FS_SERVICE);
     512                 :            : }
     513                 :            : 
     514                 :         76 : void log_setup_generator(void) {
     515                 :         76 :         log_set_prohibit_ipc(true);
     516                 :         76 :         log_setup_service();
     517                 :         76 : }

Generated by: LCOV version 1.14