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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <mntent.h>
       5                 :            : #include <stdio.h>
       6                 :            : #include <string.h>
       7                 :            : #include <unistd.h>
       8                 :            : 
       9                 :            : #include "alloc-util.h"
      10                 :            : #include "fd-util.h"
      11                 :            : #include "fileio.h"
      12                 :            : #include "fs-util.h"
      13                 :            : #include "fstab-util.h"
      14                 :            : #include "generator.h"
      15                 :            : #include "log.h"
      16                 :            : #include "main-func.h"
      17                 :            : #include "mkdir.h"
      18                 :            : #include "mount-setup.h"
      19                 :            : #include "mount-util.h"
      20                 :            : #include "mountpoint-util.h"
      21                 :            : #include "parse-util.h"
      22                 :            : #include "path-util.h"
      23                 :            : #include "proc-cmdline.h"
      24                 :            : #include "special.h"
      25                 :            : #include "specifier.h"
      26                 :            : #include "stat-util.h"
      27                 :            : #include "string-util.h"
      28                 :            : #include "strv.h"
      29                 :            : #include "unit-name.h"
      30                 :            : #include "util.h"
      31                 :            : #include "virt.h"
      32                 :            : #include "volatile-util.h"
      33                 :            : 
      34                 :            : typedef enum MountpointFlags {
      35                 :            :         NOAUTO    = 1 << 0,
      36                 :            :         NOFAIL    = 1 << 1,
      37                 :            :         AUTOMOUNT = 1 << 2,
      38                 :            :         MAKEFS    = 1 << 3,
      39                 :            :         GROWFS    = 1 << 4,
      40                 :            : } MountpointFlags;
      41                 :            : 
      42                 :            : static const char *arg_dest = NULL;
      43                 :            : static const char *arg_dest_late = NULL;
      44                 :            : static bool arg_fstab_enabled = true;
      45                 :            : static char *arg_root_what = NULL;
      46                 :            : static char *arg_root_fstype = NULL;
      47                 :            : static char *arg_root_options = NULL;
      48                 :            : static char *arg_root_hash = NULL;
      49                 :            : static int arg_root_rw = -1;
      50                 :            : static char *arg_usr_what = NULL;
      51                 :            : static char *arg_usr_fstype = NULL;
      52                 :            : static char *arg_usr_options = NULL;
      53                 :            : static VolatileMode arg_volatile_mode = _VOLATILE_MODE_INVALID;
      54                 :            : 
      55                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_root_what, freep);
      56                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_root_fstype, freep);
      57                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_root_options, freep);
      58                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_root_hash, freep);
      59                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_usr_what, freep);
      60                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_usr_fstype, freep);
      61                 :          0 : STATIC_DESTRUCTOR_REGISTER(arg_usr_options, freep);
      62                 :            : 
      63                 :          0 : static int write_options(FILE *f, const char *options) {
      64                 :          0 :         _cleanup_free_ char *o = NULL;
      65                 :            : 
      66         [ #  # ]:          0 :         if (isempty(options))
      67                 :          0 :                 return 0;
      68                 :            : 
      69         [ #  # ]:          0 :         if (streq(options, "defaults"))
      70                 :          0 :                 return 0;
      71                 :            : 
      72                 :          0 :         o = specifier_escape(options);
      73         [ #  # ]:          0 :         if (!o)
      74                 :          0 :                 return log_oom();
      75                 :            : 
      76                 :          0 :         fprintf(f, "Options=%s\n", o);
      77                 :          0 :         return 1;
      78                 :            : }
      79                 :            : 
      80                 :          0 : static int write_what(FILE *f, const char *what) {
      81                 :          0 :         _cleanup_free_ char *w = NULL;
      82                 :            : 
      83                 :          0 :         w = specifier_escape(what);
      84         [ #  # ]:          0 :         if (!w)
      85                 :          0 :                 return log_oom();
      86                 :            : 
      87                 :          0 :         fprintf(f, "What=%s\n", w);
      88                 :          0 :         return 1;
      89                 :            : }
      90                 :            : 
      91                 :          0 : static int add_swap(
      92                 :            :                 const char *what,
      93                 :            :                 struct mntent *me,
      94                 :            :                 MountpointFlags flags) {
      95                 :            : 
      96                 :          0 :         _cleanup_free_ char *name = NULL;
      97                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
      98                 :            :         int r;
      99                 :            : 
     100         [ #  # ]:          0 :         assert(what);
     101         [ #  # ]:          0 :         assert(me);
     102                 :            : 
     103         [ #  # ]:          0 :         if (access("/proc/swaps", F_OK) < 0) {
     104         [ #  # ]:          0 :                 log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
     105                 :          0 :                 return 0;
     106                 :            :         }
     107                 :            : 
     108         [ #  # ]:          0 :         if (detect_container() > 0) {
     109         [ #  # ]:          0 :                 log_info("Running in a container, ignoring fstab swap entry for %s.", what);
     110                 :          0 :                 return 0;
     111                 :            :         }
     112                 :            : 
     113                 :          0 :         r = unit_name_from_path(what, ".swap", &name);
     114         [ #  # ]:          0 :         if (r < 0)
     115         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to generate unit name: %m");
     116                 :            : 
     117                 :          0 :         r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f);
     118         [ #  # ]:          0 :         if (r < 0)
     119                 :          0 :                 return r;
     120                 :            : 
     121                 :          0 :         fputs("[Unit]\n"
     122                 :            :               "SourcePath=/etc/fstab\n"
     123                 :            :               "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
     124                 :            :               "[Swap]\n", f);
     125                 :            : 
     126                 :          0 :         r = write_what(f, what);
     127         [ #  # ]:          0 :         if (r < 0)
     128                 :          0 :                 return r;
     129                 :            : 
     130                 :          0 :         r = write_options(f, me->mnt_opts);
     131         [ #  # ]:          0 :         if (r < 0)
     132                 :          0 :                 return r;
     133                 :            : 
     134                 :          0 :         r = fflush_and_check(f);
     135         [ #  # ]:          0 :         if (r < 0)
     136         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write unit file %s: %m", name);
     137                 :            : 
     138                 :            :         /* use what as where, to have a nicer error message */
     139                 :          0 :         r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
     140         [ #  # ]:          0 :         if (r < 0)
     141                 :          0 :                 return r;
     142                 :            : 
     143         [ #  # ]:          0 :         if (flags & MAKEFS) {
     144                 :          0 :                 r = generator_hook_up_mkswap(arg_dest, what);
     145         [ #  # ]:          0 :                 if (r < 0)
     146                 :          0 :                         return r;
     147                 :            :         }
     148                 :            : 
     149         [ #  # ]:          0 :         if (flags & GROWFS)
     150                 :            :                 /* TODO: swap devices must be wiped and recreated */
     151         [ #  # ]:          0 :                 log_warning("%s: growing swap devices is currently unsupported.", what);
     152                 :            : 
     153         [ #  # ]:          0 :         if (!(flags & NOAUTO)) {
     154                 :          0 :                 r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
     155         [ #  # ]:          0 :                                           (flags & NOFAIL) ? "wants" : "requires", name);
     156         [ #  # ]:          0 :                 if (r < 0)
     157                 :          0 :                         return r;
     158                 :            :         }
     159                 :            : 
     160                 :          0 :         return 0;
     161                 :            : }
     162                 :            : 
     163                 :          0 : static bool mount_is_network(struct mntent *me) {
     164         [ #  # ]:          0 :         assert(me);
     165                 :            : 
     166   [ #  #  #  # ]:          0 :         return fstab_test_option(me->mnt_opts, "_netdev\0") ||
     167                 :          0 :                fstype_is_network(me->mnt_type);
     168                 :            : }
     169                 :            : 
     170                 :          0 : static bool mount_in_initrd(struct mntent *me) {
     171         [ #  # ]:          0 :         assert(me);
     172                 :            : 
     173         [ #  # ]:          0 :         return fstab_test_option(me->mnt_opts, "x-initrd.mount\0") ||
     174         [ #  # ]:          0 :                streq(me->mnt_dir, "/usr");
     175                 :            : }
     176                 :            : 
     177                 :          0 : static int write_timeout(FILE *f, const char *where, const char *opts,
     178                 :            :                          const char *filter, const char *variable) {
     179                 :          0 :         _cleanup_free_ char *timeout = NULL;
     180                 :            :         char timespan[FORMAT_TIMESPAN_MAX];
     181                 :            :         usec_t u;
     182                 :            :         int r;
     183                 :            : 
     184                 :          0 :         r = fstab_filter_options(opts, filter, NULL, &timeout, NULL);
     185         [ #  # ]:          0 :         if (r < 0)
     186         [ #  # ]:          0 :                 return log_warning_errno(r, "Failed to parse options: %m");
     187         [ #  # ]:          0 :         if (r == 0)
     188                 :          0 :                 return 0;
     189                 :            : 
     190                 :          0 :         r = parse_sec_fix_0(timeout, &u);
     191         [ #  # ]:          0 :         if (r < 0) {
     192         [ #  # ]:          0 :                 log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
     193                 :          0 :                 return 0;
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         fprintf(f, "%s=%s\n", variable, format_timespan(timespan, sizeof(timespan), u, 0));
     197                 :            : 
     198                 :          0 :         return 0;
     199                 :            : }
     200                 :            : 
     201                 :          0 : static int write_idle_timeout(FILE *f, const char *where, const char *opts) {
     202                 :          0 :         return write_timeout(f, where, opts,
     203                 :            :                              "x-systemd.idle-timeout\0", "TimeoutIdleSec");
     204                 :            : }
     205                 :            : 
     206                 :          0 : static int write_mount_timeout(FILE *f, const char *where, const char *opts) {
     207                 :          0 :         return write_timeout(f, where, opts,
     208                 :            :                              "x-systemd.mount-timeout\0", "TimeoutSec");
     209                 :            : }
     210                 :            : 
     211                 :          0 : static int write_dependency(FILE *f, const char *opts,
     212                 :            :                 const char *filter, const char *format) {
     213                 :          0 :         _cleanup_strv_free_ char **names = NULL, **units = NULL;
     214                 :          0 :         _cleanup_free_ char *res = NULL;
     215                 :            :         char **s;
     216                 :            :         int r;
     217                 :            : 
     218         [ #  # ]:          0 :         assert(f);
     219         [ #  # ]:          0 :         assert(opts);
     220                 :            : 
     221                 :          0 :         r = fstab_extract_values(opts, filter, &names);
     222         [ #  # ]:          0 :         if (r < 0)
     223         [ #  # ]:          0 :                 return log_warning_errno(r, "Failed to parse options: %m");
     224         [ #  # ]:          0 :         if (r == 0)
     225                 :          0 :                 return 0;
     226                 :            : 
     227   [ #  #  #  # ]:          0 :         STRV_FOREACH(s, names) {
     228                 :            :                 char *x;
     229                 :            : 
     230                 :          0 :                 r = unit_name_mangle_with_suffix(*s, 0, ".mount", &x);
     231         [ #  # ]:          0 :                 if (r < 0)
     232         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to generate unit name: %m");
     233                 :          0 :                 r = strv_consume(&units, x);
     234         [ #  # ]:          0 :                 if (r < 0)
     235                 :          0 :                         return log_oom();
     236                 :            :         }
     237                 :            : 
     238         [ #  # ]:          0 :         if (units) {
     239                 :          0 :                 res = strv_join(units, " ");
     240         [ #  # ]:          0 :                 if (!res)
     241                 :          0 :                         return log_oom();
     242                 :            : #pragma GCC diagnostic push
     243                 :            : #pragma GCC diagnostic ignored "-Wformat-nonliteral"
     244                 :          0 :                 fprintf(f, format, res);
     245                 :            : #pragma GCC diagnostic pop
     246                 :            :         }
     247                 :            : 
     248                 :          0 :         return 0;
     249                 :            : }
     250                 :            : 
     251                 :          0 : static int write_after(FILE *f, const char *opts) {
     252                 :          0 :         return write_dependency(f, opts, "x-systemd.after", "After=%1$s\n");
     253                 :            : }
     254                 :            : 
     255                 :          0 : static int write_requires_after(FILE *f, const char *opts) {
     256                 :          0 :         return write_dependency(f, opts,
     257                 :            :                                 "x-systemd.requires", "After=%1$s\nRequires=%1$s\n");
     258                 :            : }
     259                 :            : 
     260                 :          0 : static int write_before(FILE *f, const char *opts) {
     261                 :          0 :         return write_dependency(f, opts,
     262                 :            :                                 "x-systemd.before", "Before=%1$s\n");
     263                 :            : }
     264                 :            : 
     265                 :          0 : static int write_requires_mounts_for(FILE *f, const char *opts) {
     266                 :          0 :         _cleanup_strv_free_ char **paths = NULL, **paths_escaped = NULL;
     267                 :          0 :         _cleanup_free_ char *res = NULL;
     268                 :            :         int r;
     269                 :            : 
     270         [ #  # ]:          0 :         assert(f);
     271         [ #  # ]:          0 :         assert(opts);
     272                 :            : 
     273                 :          0 :         r = fstab_extract_values(opts, "x-systemd.requires-mounts-for", &paths);
     274         [ #  # ]:          0 :         if (r < 0)
     275         [ #  # ]:          0 :                 return log_warning_errno(r, "Failed to parse options: %m");
     276         [ #  # ]:          0 :         if (r == 0)
     277                 :          0 :                 return 0;
     278                 :            : 
     279                 :          0 :         r = specifier_escape_strv(paths, &paths_escaped);
     280         [ #  # ]:          0 :         if (r < 0)
     281         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to escape paths: %m");
     282                 :            : 
     283                 :          0 :         res = strv_join(paths_escaped, " ");
     284         [ #  # ]:          0 :         if (!res)
     285                 :          0 :                 return log_oom();
     286                 :            : 
     287                 :          0 :         fprintf(f, "RequiresMountsFor=%s\n", res);
     288                 :            : 
     289                 :          0 :         return 0;
     290                 :            : }
     291                 :            : 
     292                 :          0 : static int add_mount(
     293                 :            :                 const char *dest,
     294                 :            :                 const char *what,
     295                 :            :                 const char *where,
     296                 :            :                 const char *original_where,
     297                 :            :                 const char *fstype,
     298                 :            :                 const char *opts,
     299                 :            :                 int passno,
     300                 :            :                 MountpointFlags flags,
     301                 :            :                 const char *post,
     302                 :            :                 const char *source) {
     303                 :            : 
     304                 :            :         _cleanup_free_ char
     305                 :          0 :                 *name = NULL,
     306                 :          0 :                 *automount_name = NULL,
     307                 :          0 :                 *filtered = NULL,
     308                 :          0 :                 *where_escaped = NULL;
     309                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
     310                 :            :         int r;
     311                 :            : 
     312         [ #  # ]:          0 :         assert(what);
     313         [ #  # ]:          0 :         assert(where);
     314         [ #  # ]:          0 :         assert(opts);
     315         [ #  # ]:          0 :         assert(post);
     316         [ #  # ]:          0 :         assert(source);
     317                 :            : 
     318         [ #  # ]:          0 :         if (streq_ptr(fstype, "autofs"))
     319                 :          0 :                 return 0;
     320                 :            : 
     321         [ #  # ]:          0 :         if (!is_path(where)) {
     322         [ #  # ]:          0 :                 log_warning("Mount point %s is not a valid path, ignoring.", where);
     323                 :          0 :                 return 0;
     324                 :            :         }
     325                 :            : 
     326   [ #  #  #  # ]:          0 :         if (mount_point_is_api(where) ||
     327                 :          0 :             mount_point_ignore(where))
     328                 :          0 :                 return 0;
     329                 :            : 
     330         [ #  # ]:          0 :         if (path_equal(where, "/")) {
     331         [ #  # ]:          0 :                 if (flags & NOAUTO)
     332         [ #  # ]:          0 :                         log_warning("Ignoring \"noauto\" for root device");
     333         [ #  # ]:          0 :                 if (flags & NOFAIL)
     334         [ #  # ]:          0 :                         log_warning("Ignoring \"nofail\" for root device");
     335         [ #  # ]:          0 :                 if (flags & AUTOMOUNT)
     336         [ #  # ]:          0 :                         log_warning("Ignoring automount option for root device");
     337                 :            : 
     338                 :          0 :                 SET_FLAG(flags, NOAUTO | NOFAIL | AUTOMOUNT, false);
     339                 :            :         }
     340                 :            : 
     341                 :          0 :         r = unit_name_from_path(where, ".mount", &name);
     342         [ #  # ]:          0 :         if (r < 0)
     343         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to generate unit name: %m");
     344                 :            : 
     345                 :          0 :         r = generator_open_unit_file(dest, "/etc/fstab", name, &f);
     346         [ #  # ]:          0 :         if (r < 0)
     347                 :          0 :                 return r;
     348                 :            : 
     349                 :          0 :         fprintf(f,
     350                 :            :                 "[Unit]\n"
     351                 :            :                 "SourcePath=%s\n"
     352                 :            :                 "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
     353                 :            :                 source);
     354                 :            : 
     355                 :            :         /* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW, it's not
     356                 :            :          * technically part of the basic initrd filesystem itself, and so shouldn't inherit the default
     357                 :            :          * Before=local-fs.target dependency. */
     358   [ #  #  #  # ]:          0 :         if (in_initrd() && path_startswith(where, "/sysroot"))
     359                 :          0 :                 fprintf(f, "DefaultDependencies=no\n");
     360                 :            : 
     361   [ #  #  #  #  :          0 :         if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !(flags & AUTOMOUNT) &&
          #  #  #  #  #  
                      # ]
     362                 :          0 :             fstab_test_yes_no_option(opts, "bg\0" "fg\0")) {
     363                 :            :                 /* The default retry timeout that mount.nfs uses for 'bg' mounts
     364                 :            :                  * is 10000 minutes, where as it uses 2 minutes for 'fg' mounts.
     365                 :            :                  * As we are making  'bg' mounts look like an 'fg' mount to
     366                 :            :                  * mount.nfs (so systemd can manage the job-control aspects of 'bg'),
     367                 :            :                  * we need to explicitly preserve that default, and also ensure
     368                 :            :                  * the systemd mount-timeout doesn't interfere.
     369                 :            :                  * By placing these options first, they can be over-ridden by
     370                 :            :                  * settings in /etc/fstab. */
     371   [ #  #  #  #  :          0 :                 opts = strjoina("x-systemd.mount-timeout=infinity,retry=10000,", opts, ",fg");
          #  #  #  #  #  
                #  #  # ]
     372                 :          0 :                 SET_FLAG(flags, NOFAIL, true);
     373                 :            :         }
     374                 :            : 
     375   [ #  #  #  # ]:          0 :         if (!(flags & NOFAIL) && !(flags & AUTOMOUNT))
     376                 :          0 :                 fprintf(f, "Before=%s\n", post);
     377                 :            : 
     378   [ #  #  #  # ]:          0 :         if (!(flags & AUTOMOUNT) && opts) {
     379                 :          0 :                  r = write_after(f, opts);
     380         [ #  # ]:          0 :                  if (r < 0)
     381                 :          0 :                          return r;
     382                 :          0 :                  r = write_requires_after(f, opts);
     383         [ #  # ]:          0 :                  if (r < 0)
     384                 :          0 :                          return r;
     385                 :          0 :                  r = write_before(f, opts);
     386         [ #  # ]:          0 :                  if (r < 0)
     387                 :          0 :                          return r;
     388                 :          0 :                  r = write_requires_mounts_for(f, opts);
     389         [ #  # ]:          0 :                  if (r < 0)
     390                 :          0 :                          return r;
     391                 :            :         }
     392                 :            : 
     393         [ #  # ]:          0 :         if (passno != 0) {
     394                 :          0 :                 r = generator_write_fsck_deps(f, dest, what, where, fstype);
     395         [ #  # ]:          0 :                 if (r < 0)
     396                 :          0 :                         return r;
     397                 :            :         }
     398                 :            : 
     399                 :          0 :         fprintf(f, "\n[Mount]\n");
     400         [ #  # ]:          0 :         if (original_where)
     401                 :          0 :                 fprintf(f, "# Canonicalized from %s\n", original_where);
     402                 :            : 
     403                 :          0 :         where_escaped = specifier_escape(where);
     404         [ #  # ]:          0 :         if (!where_escaped)
     405                 :          0 :                 return log_oom();
     406                 :          0 :         fprintf(f, "Where=%s\n", where_escaped);
     407                 :            : 
     408                 :          0 :         r = write_what(f, what);
     409         [ #  # ]:          0 :         if (r < 0)
     410                 :          0 :                 return r;
     411                 :            : 
     412   [ #  #  #  # ]:          0 :         if (!isempty(fstype) && !streq(fstype, "auto")) {
     413         [ #  # ]:          0 :                 _cleanup_free_ char *t;
     414                 :            : 
     415                 :          0 :                 t = specifier_escape(fstype);
     416         [ #  # ]:          0 :                 if (!t)
     417                 :          0 :                         return -ENOMEM;
     418                 :            : 
     419                 :          0 :                 fprintf(f, "Type=%s\n", t);
     420                 :            :         }
     421                 :            : 
     422                 :          0 :         r = generator_write_timeouts(dest, what, where, opts, &filtered);
     423         [ #  # ]:          0 :         if (r < 0)
     424                 :          0 :                 return r;
     425                 :            : 
     426                 :          0 :         r = generator_write_device_deps(dest, what, where, opts);
     427         [ #  # ]:          0 :         if (r < 0)
     428                 :          0 :                 return r;
     429                 :            : 
     430                 :          0 :         r = write_mount_timeout(f, where, opts);
     431         [ #  # ]:          0 :         if (r < 0)
     432                 :          0 :                 return r;
     433                 :            : 
     434                 :          0 :         r = write_options(f, filtered);
     435         [ #  # ]:          0 :         if (r < 0)
     436                 :          0 :                 return r;
     437                 :            : 
     438                 :          0 :         r = fflush_and_check(f);
     439         [ #  # ]:          0 :         if (r < 0)
     440         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to write unit file %s: %m", name);
     441                 :            : 
     442         [ #  # ]:          0 :         if (flags & MAKEFS) {
     443                 :          0 :                 r = generator_hook_up_mkfs(dest, what, where, fstype);
     444         [ #  # ]:          0 :                 if (r < 0)
     445                 :          0 :                         return r;
     446                 :            :         }
     447                 :            : 
     448         [ #  # ]:          0 :         if (flags & GROWFS) {
     449                 :          0 :                 r = generator_hook_up_growfs(dest, where, post);
     450         [ #  # ]:          0 :                 if (r < 0)
     451                 :          0 :                         return r;
     452                 :            :         }
     453                 :            : 
     454   [ #  #  #  # ]:          0 :         if (!(flags & NOAUTO) && !(flags & AUTOMOUNT)) {
     455                 :          0 :                 r = generator_add_symlink(dest, post,
     456         [ #  # ]:          0 :                                           (flags & NOFAIL) ? "wants" : "requires", name);
     457         [ #  # ]:          0 :                 if (r < 0)
     458                 :          0 :                         return r;
     459                 :            :         }
     460                 :            : 
     461         [ #  # ]:          0 :         if (flags & AUTOMOUNT) {
     462                 :          0 :                 r = unit_name_from_path(where, ".automount", &automount_name);
     463         [ #  # ]:          0 :                 if (r < 0)
     464         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to generate unit name: %m");
     465                 :            : 
     466                 :          0 :                 f = safe_fclose(f);
     467                 :            : 
     468                 :          0 :                 r = generator_open_unit_file(dest, "/etc/fstab", automount_name, &f);
     469         [ #  # ]:          0 :                 if (r < 0)
     470                 :          0 :                         return r;
     471                 :            : 
     472                 :          0 :                 fprintf(f,
     473                 :            :                         "[Unit]\n"
     474                 :            :                         "SourcePath=%s\n"
     475                 :            :                         "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
     476                 :            :                         source);
     477                 :            : 
     478                 :          0 :                 fprintf(f, "Before=%s\n", post);
     479                 :            : 
     480         [ #  # ]:          0 :                 if (opts) {
     481                 :          0 :                         r = write_after(f, opts);
     482         [ #  # ]:          0 :                         if (r < 0)
     483                 :          0 :                                 return r;
     484                 :          0 :                         r = write_requires_after(f, opts);
     485         [ #  # ]:          0 :                         if (r < 0)
     486                 :          0 :                                 return r;
     487                 :          0 :                         r = write_before(f, opts);
     488         [ #  # ]:          0 :                         if (r < 0)
     489                 :          0 :                                 return r;
     490                 :          0 :                         r = write_requires_mounts_for(f, opts);
     491         [ #  # ]:          0 :                         if (r < 0)
     492                 :          0 :                                 return r;
     493                 :            :                 }
     494                 :            : 
     495                 :          0 :                 fprintf(f,
     496                 :            :                         "\n"
     497                 :            :                         "[Automount]\n"
     498                 :            :                         "Where=%s\n",
     499                 :            :                         where_escaped);
     500                 :            : 
     501                 :          0 :                 r = write_idle_timeout(f, where, opts);
     502         [ #  # ]:          0 :                 if (r < 0)
     503                 :          0 :                         return r;
     504                 :            : 
     505                 :          0 :                 r = fflush_and_check(f);
     506         [ #  # ]:          0 :                 if (r < 0)
     507         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to write unit file %s: %m", automount_name);
     508                 :            : 
     509                 :          0 :                 r = generator_add_symlink(dest, post,
     510         [ #  # ]:          0 :                                           (flags & NOFAIL) ? "wants" : "requires", automount_name);
     511         [ #  # ]:          0 :                 if (r < 0)
     512                 :          0 :                         return r;
     513                 :            :         }
     514                 :            : 
     515                 :          0 :         return 0;
     516                 :            : }
     517                 :            : 
     518                 :          0 : static int parse_fstab(bool initrd) {
     519                 :          0 :         _cleanup_endmntent_ FILE *f = NULL;
     520                 :            :         const char *fstab_path;
     521                 :            :         struct mntent *me;
     522                 :          0 :         int r = 0;
     523                 :            : 
     524         [ #  # ]:          0 :         fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab";
     525         [ #  # ]:          0 :         log_debug("Parsing %s...", fstab_path);
     526                 :            : 
     527                 :          0 :         f = setmntent(fstab_path, "re");
     528         [ #  # ]:          0 :         if (!f) {
     529         [ #  # ]:          0 :                 if (errno == ENOENT)
     530                 :          0 :                         return 0;
     531                 :            : 
     532         [ #  # ]:          0 :                 return log_error_errno(errno, "Failed to open %s: %m", fstab_path);
     533                 :            :         }
     534                 :            : 
     535         [ #  # ]:          0 :         while ((me = getmntent(f))) {
     536   [ #  #  #  #  :          0 :                 _cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
             #  #  #  #  
                      # ]
     537                 :            :                 bool makefs, growfs, noauto, nofail;
     538                 :            :                 int k;
     539                 :            : 
     540   [ #  #  #  # ]:          0 :                 if (initrd && !mount_in_initrd(me))
     541                 :          0 :                         continue;
     542                 :            : 
     543                 :          0 :                 what = fstab_node_to_udev_node(me->mnt_fsname);
     544         [ #  # ]:          0 :                 if (!what)
     545                 :          0 :                         return log_oom();
     546                 :            : 
     547   [ #  #  #  # ]:          0 :                 if (is_device_path(what) && path_is_read_only_fs("/sys") > 0) {
     548         [ #  # ]:          0 :                         log_info("Running in a container, ignoring fstab device entry for %s.", what);
     549                 :          0 :                         continue;
     550                 :            :                 }
     551                 :            : 
     552                 :          0 :                 where = strdup(me->mnt_dir);
     553         [ #  # ]:          0 :                 if (!where)
     554                 :          0 :                         return log_oom();
     555                 :            : 
     556         [ #  # ]:          0 :                 if (is_path(where)) {
     557                 :          0 :                         path_simplify(where, false);
     558                 :            : 
     559                 :            :                         /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
     560                 :            :                          * mount units, but causes problems since it historically worked to have symlinks in e.g.
     561                 :            :                          * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
     562                 :            :                          * where a symlink refers to another mount target; this works assuming the sub-mountpoint
     563                 :            :                          * target is the final directory. */
     564         [ #  # ]:          0 :                         r = chase_symlinks(where, initrd ? "/sysroot" : NULL,
     565                 :            :                                            CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
     566                 :            :                                            &canonical_where);
     567         [ #  # ]:          0 :                         if (r < 0) /* If we can't canonicalize we continue on as if it wasn't a symlink */
     568         [ #  # ]:          0 :                                 log_debug_errno(r, "Failed to read symlink target for %s, ignoring: %m", where);
     569         [ #  # ]:          0 :                         else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */
     570                 :          0 :                                 canonical_where = mfree(canonical_where);
     571                 :            :                         else
     572         [ #  # ]:          0 :                                 log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where);
     573                 :            :                 }
     574                 :            : 
     575                 :          0 :                 makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0");
     576                 :          0 :                 growfs = fstab_test_option(me->mnt_opts, "x-systemd.growfs\0");
     577                 :          0 :                 noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
     578                 :          0 :                 nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
     579                 :            : 
     580         [ #  # ]:          0 :                 log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s",
     581                 :            :                           what, where, me->mnt_type,
     582                 :            :                           yes_no(makefs), yes_no(growfs),
     583                 :            :                           yes_no(noauto), yes_no(nofail));
     584                 :            : 
     585         [ #  # ]:          0 :                 if (streq(me->mnt_type, "swap"))
     586                 :          0 :                         k = add_swap(what, me,
     587                 :          0 :                                      makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL);
     588                 :            :                 else {
     589                 :            :                         bool automount;
     590                 :            :                         const char *post;
     591                 :            : 
     592                 :          0 :                         automount = fstab_test_option(me->mnt_opts,
     593                 :            :                                                       "comment=systemd.automount\0"
     594                 :            :                                                       "x-systemd.automount\0");
     595         [ #  # ]:          0 :                         if (initrd)
     596                 :          0 :                                 post = SPECIAL_INITRD_FS_TARGET;
     597         [ #  # ]:          0 :                         else if (mount_is_network(me))
     598                 :          0 :                                 post = SPECIAL_REMOTE_FS_TARGET;
     599                 :            :                         else
     600                 :          0 :                                 post = SPECIAL_LOCAL_FS_TARGET;
     601                 :            : 
     602                 :          0 :                         k = add_mount(arg_dest,
     603                 :            :                                       what,
     604         [ #  # ]:          0 :                                       canonical_where ?: where,
     605                 :          0 :                                       canonical_where ? where: NULL,
     606                 :          0 :                                       me->mnt_type,
     607                 :          0 :                                       me->mnt_opts,
     608                 :            :                                       me->mnt_passno,
     609         [ #  # ]:          0 :                                       makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
     610                 :            :                                       post,
     611                 :            :                                       fstab_path);
     612                 :            :                 }
     613                 :            : 
     614   [ #  #  #  # ]:          0 :                 if (r >= 0 && k < 0)
     615                 :          0 :                         r = k;
     616                 :            :         }
     617                 :            : 
     618                 :          0 :         return r;
     619                 :            : }
     620                 :            : 
     621                 :          0 : static int add_sysroot_mount(void) {
     622                 :          0 :         _cleanup_free_ char *what = NULL;
     623                 :            :         const char *opts;
     624                 :            :         int r;
     625                 :            : 
     626         [ #  # ]:          0 :         if (isempty(arg_root_what)) {
     627         [ #  # ]:          0 :                 log_debug("Could not find a root= entry on the kernel command line.");
     628                 :          0 :                 return 0;
     629                 :            :         }
     630                 :            : 
     631         [ #  # ]:          0 :         if (streq(arg_root_what, "gpt-auto")) {
     632                 :            :                 /* This is handled by the gpt-auto generator */
     633         [ #  # ]:          0 :                 log_debug("Skipping root directory handling, as gpt-auto was requested.");
     634                 :          0 :                 return 0;
     635                 :            :         }
     636                 :            : 
     637         [ #  # ]:          0 :         if (path_equal(arg_root_what, "/dev/nfs")) {
     638                 :            :                 /* This is handled by the kernel or the initrd */
     639         [ #  # ]:          0 :                 log_debug("Skipping root directory handling, as /dev/nfs was requested.");
     640                 :          0 :                 return 0;
     641                 :            :         }
     642                 :            : 
     643                 :          0 :         what = fstab_node_to_udev_node(arg_root_what);
     644         [ #  # ]:          0 :         if (!what)
     645                 :          0 :                 return log_oom();
     646                 :            : 
     647         [ #  # ]:          0 :         if (!arg_root_options)
     648         [ #  # ]:          0 :                 opts = arg_root_rw > 0 ? "rw" : "ro";
     649         [ #  # ]:          0 :         else if (arg_root_rw >= 0 ||
     650         [ #  # ]:          0 :                  !fstab_test_option(arg_root_options, "ro\0" "rw\0"))
     651   [ #  #  #  #  :          0 :                 opts = strjoina(arg_root_options, ",", arg_root_rw > 0 ? "rw" : "ro");
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     652                 :            :         else
     653                 :          0 :                 opts = arg_root_options;
     654                 :            : 
     655         [ #  # ]:          0 :         log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
     656                 :            : 
     657         [ #  # ]:          0 :         if (is_device_path(what)) {
     658                 :          0 :                 r = generator_write_initrd_root_device_deps(arg_dest, what);
     659         [ #  # ]:          0 :                 if (r < 0)
     660                 :          0 :                         return r;
     661                 :            :         }
     662                 :            : 
     663                 :          0 :         return add_mount(arg_dest,
     664                 :            :                          what,
     665                 :            :                          "/sysroot",
     666                 :            :                          NULL,
     667                 :            :                          arg_root_fstype,
     668                 :            :                          opts,
     669                 :          0 :                          is_device_path(what) ? 1 : 0, /* passno */
     670                 :            :                          0,                            /* makefs off, growfs off, noauto off, nofail off, automount off */
     671                 :            :                          SPECIAL_INITRD_ROOT_FS_TARGET,
     672                 :            :                          "/proc/cmdline");
     673                 :            : }
     674                 :            : 
     675                 :          0 : static int add_sysroot_usr_mount(void) {
     676                 :          0 :         _cleanup_free_ char *what = NULL;
     677                 :            :         const char *opts;
     678                 :            : 
     679   [ #  #  #  #  :          0 :         if (!arg_usr_what && !arg_usr_fstype && !arg_usr_options)
                   #  # ]
     680                 :          0 :                 return 0;
     681                 :            : 
     682   [ #  #  #  # ]:          0 :         if (arg_root_what && !arg_usr_what) {
     683                 :            :                 /* Copy over the root device, in case the /usr mount just differs in a mount option (consider btrfs subvolumes) */
     684                 :          0 :                 arg_usr_what = strdup(arg_root_what);
     685         [ #  # ]:          0 :                 if (!arg_usr_what)
     686                 :          0 :                         return log_oom();
     687                 :            :         }
     688                 :            : 
     689   [ #  #  #  # ]:          0 :         if (arg_root_fstype && !arg_usr_fstype) {
     690                 :          0 :                 arg_usr_fstype = strdup(arg_root_fstype);
     691         [ #  # ]:          0 :                 if (!arg_usr_fstype)
     692                 :          0 :                         return log_oom();
     693                 :            :         }
     694                 :            : 
     695   [ #  #  #  # ]:          0 :         if (arg_root_options && !arg_usr_options) {
     696                 :          0 :                 arg_usr_options = strdup(arg_root_options);
     697         [ #  # ]:          0 :                 if (!arg_usr_options)
     698                 :          0 :                         return log_oom();
     699                 :            :         }
     700                 :            : 
     701         [ #  # ]:          0 :         if (!arg_usr_what)
     702                 :          0 :                 return 0;
     703                 :            : 
     704                 :          0 :         what = fstab_node_to_udev_node(arg_usr_what);
     705         [ #  # ]:          0 :         if (!what)
     706                 :          0 :                 return log_oom();
     707                 :            : 
     708         [ #  # ]:          0 :         if (!arg_usr_options)
     709         [ #  # ]:          0 :                 opts = arg_root_rw > 0 ? "rw" : "ro";
     710         [ #  # ]:          0 :         else if (!fstab_test_option(arg_usr_options, "ro\0" "rw\0"))
     711   [ #  #  #  #  :          0 :                 opts = strjoina(arg_usr_options, ",", arg_root_rw > 0 ? "rw" : "ro");
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     712                 :            :         else
     713                 :          0 :                 opts = arg_usr_options;
     714                 :            : 
     715         [ #  # ]:          0 :         log_debug("Found entry what=%s where=/sysroot/usr type=%s", what, strna(arg_usr_fstype));
     716                 :          0 :         return add_mount(arg_dest,
     717                 :            :                          what,
     718                 :            :                          "/sysroot/usr",
     719                 :            :                          NULL,
     720                 :            :                          arg_usr_fstype,
     721                 :            :                          opts,
     722                 :          0 :                          is_device_path(what) ? 1 : 0, /* passno */
     723                 :            :                          0,
     724                 :            :                          SPECIAL_INITRD_FS_TARGET,
     725                 :            :                          "/proc/cmdline");
     726                 :            : }
     727                 :            : 
     728                 :          0 : static int add_volatile_root(void) {
     729                 :            : 
     730                 :            :         /* Let's add in systemd-remount-volatile.service which will remount the root device to tmpfs if this is
     731                 :            :          * requested (or as an overlayfs), leaving only /usr from the root mount inside. */
     732                 :            : 
     733   [ #  #  #  # ]:          0 :         if (!IN_SET(arg_volatile_mode, VOLATILE_YES, VOLATILE_OVERLAY))
     734                 :          0 :                 return 0;
     735                 :            : 
     736                 :          0 :         return generator_add_symlink(arg_dest, SPECIAL_INITRD_ROOT_FS_TARGET, "requires",
     737                 :            :                                      SYSTEM_DATA_UNIT_PATH "/" SPECIAL_VOLATILE_ROOT_SERVICE);
     738                 :            : }
     739                 :            : 
     740                 :          0 : static int add_volatile_var(void) {
     741                 :            : 
     742         [ #  # ]:          0 :         if (arg_volatile_mode != VOLATILE_STATE)
     743                 :          0 :                 return 0;
     744                 :            : 
     745                 :            :         /* If requested, mount /var as tmpfs, but do so only if there's nothing else defined for this. */
     746                 :            : 
     747                 :          0 :         return add_mount(arg_dest_late,
     748                 :            :                          "tmpfs",
     749                 :            :                          "/var",
     750                 :            :                          NULL,
     751                 :            :                          "tmpfs",
     752                 :            :                          "mode=0755",
     753                 :            :                          0,
     754                 :            :                          0,
     755                 :            :                          SPECIAL_LOCAL_FS_TARGET,
     756                 :            :                          "/proc/cmdline");
     757                 :            : }
     758                 :            : 
     759                 :          0 : static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
     760                 :            :         int r;
     761                 :            : 
     762                 :            :         /* root=, usr=, usrfstype= and roofstype= may occur more than once, the last
     763                 :            :          * instance should take precedence.  In the case of multiple rootflags=
     764                 :            :          * or usrflags= the arguments should be concatenated */
     765                 :            : 
     766         [ #  # ]:          0 :         if (STR_IN_SET(key, "fstab", "rd.fstab")) {
     767                 :            : 
     768         [ #  # ]:          0 :                 r = value ? parse_boolean(value) : 1;
     769         [ #  # ]:          0 :                 if (r < 0)
     770         [ #  # ]:          0 :                         log_warning("Failed to parse fstab switch %s. Ignoring.", value);
     771                 :            :                 else
     772                 :          0 :                         arg_fstab_enabled = r;
     773                 :            : 
     774         [ #  # ]:          0 :         } else if (streq(key, "root")) {
     775                 :            : 
     776         [ #  # ]:          0 :                 if (proc_cmdline_value_missing(key, value))
     777                 :          0 :                         return 0;
     778                 :            : 
     779         [ #  # ]:          0 :                 if (free_and_strdup(&arg_root_what, value) < 0)
     780                 :          0 :                         return log_oom();
     781                 :            : 
     782         [ #  # ]:          0 :         } else if (streq(key, "rootfstype")) {
     783                 :            : 
     784         [ #  # ]:          0 :                 if (proc_cmdline_value_missing(key, value))
     785                 :          0 :                         return 0;
     786                 :            : 
     787         [ #  # ]:          0 :                 if (free_and_strdup(&arg_root_fstype, value) < 0)
     788                 :          0 :                         return log_oom();
     789                 :            : 
     790         [ #  # ]:          0 :         } else if (streq(key, "rootflags")) {
     791                 :            : 
     792         [ #  # ]:          0 :                 if (proc_cmdline_value_missing(key, value))
     793                 :          0 :                         return 0;
     794                 :            : 
     795         [ #  # ]:          0 :                 if (!strextend_with_separator(&arg_root_options, ",", value, NULL))
     796                 :          0 :                         return log_oom();
     797                 :            : 
     798         [ #  # ]:          0 :         } else if (streq(key, "roothash")) {
     799                 :            : 
     800         [ #  # ]:          0 :                 if (proc_cmdline_value_missing(key, value))
     801                 :          0 :                         return 0;
     802                 :            : 
     803         [ #  # ]:          0 :                 if (free_and_strdup(&arg_root_hash, value) < 0)
     804                 :          0 :                         return log_oom();
     805                 :            : 
     806         [ #  # ]:          0 :         } else if (streq(key, "mount.usr")) {
     807                 :            : 
     808         [ #  # ]:          0 :                 if (proc_cmdline_value_missing(key, value))
     809                 :          0 :                         return 0;
     810                 :            : 
     811         [ #  # ]:          0 :                 if (free_and_strdup(&arg_usr_what, value) < 0)
     812                 :          0 :                         return log_oom();
     813                 :            : 
     814         [ #  # ]:          0 :         } else if (streq(key, "mount.usrfstype")) {
     815                 :            : 
     816         [ #  # ]:          0 :                 if (proc_cmdline_value_missing(key, value))
     817                 :          0 :                         return 0;
     818                 :            : 
     819         [ #  # ]:          0 :                 if (free_and_strdup(&arg_usr_fstype, value) < 0)
     820                 :          0 :                         return log_oom();
     821                 :            : 
     822         [ #  # ]:          0 :         } else if (streq(key, "mount.usrflags")) {
     823                 :            : 
     824         [ #  # ]:          0 :                 if (proc_cmdline_value_missing(key, value))
     825                 :          0 :                         return 0;
     826                 :            : 
     827         [ #  # ]:          0 :                 if (!strextend_with_separator(&arg_usr_options, ",", value, NULL))
     828                 :          0 :                         return log_oom();
     829                 :            : 
     830   [ #  #  #  # ]:          0 :         } else if (streq(key, "rw") && !value)
     831                 :          0 :                 arg_root_rw = true;
     832   [ #  #  #  # ]:          0 :         else if (streq(key, "ro") && !value)
     833                 :          0 :                 arg_root_rw = false;
     834         [ #  # ]:          0 :         else if (streq(key, "systemd.volatile")) {
     835                 :            :                 VolatileMode m;
     836                 :            : 
     837         [ #  # ]:          0 :                 if (value) {
     838                 :          0 :                         m = volatile_mode_from_string(value);
     839         [ #  # ]:          0 :                         if (m < 0)
     840         [ #  # ]:          0 :                                 log_warning("Failed to parse systemd.volatile= argument: %s", value);
     841                 :            :                         else
     842                 :          0 :                                 arg_volatile_mode = m;
     843                 :            :                 } else
     844                 :          0 :                         arg_volatile_mode = VOLATILE_YES;
     845                 :            :         }
     846                 :            : 
     847                 :          0 :         return 0;
     848                 :            : }
     849                 :            : 
     850                 :          0 : static int determine_root(void) {
     851                 :            :         /* If we have a root hash but no root device then Verity is used, and we use the "root" DM device as root. */
     852                 :            : 
     853         [ #  # ]:          0 :         if (arg_root_what)
     854                 :          0 :                 return 0;
     855                 :            : 
     856         [ #  # ]:          0 :         if (!arg_root_hash)
     857                 :          0 :                 return 0;
     858                 :            : 
     859                 :          0 :         arg_root_what = strdup("/dev/mapper/root");
     860         [ #  # ]:          0 :         if (!arg_root_what)
     861                 :          0 :                 return log_oom();
     862                 :            : 
     863         [ #  # ]:          0 :         log_info("Using verity root device %s.", arg_root_what);
     864                 :            : 
     865                 :          0 :         return 1;
     866                 :            : }
     867                 :            : 
     868                 :          0 : static int run(const char *dest, const char *dest_early, const char *dest_late) {
     869                 :          0 :         int r, r2 = 0, r3 = 0;
     870                 :            : 
     871         [ #  # ]:          0 :         assert_se(arg_dest = dest);
     872         [ #  # ]:          0 :         assert_se(arg_dest_late = dest_late);
     873                 :            : 
     874                 :          0 :         r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
     875         [ #  # ]:          0 :         if (r < 0)
     876         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
     877                 :            : 
     878                 :          0 :         (void) determine_root();
     879                 :            : 
     880                 :            :         /* Always honour root= and usr= in the kernel command line if we are in an initrd */
     881         [ #  # ]:          0 :         if (in_initrd()) {
     882                 :          0 :                 r = add_sysroot_mount();
     883                 :            : 
     884                 :          0 :                 r2 = add_sysroot_usr_mount();
     885                 :            : 
     886                 :          0 :                 r3 = add_volatile_root();
     887                 :            :         } else
     888                 :          0 :                 r = add_volatile_var();
     889                 :            : 
     890                 :            :         /* Honour /etc/fstab only when that's enabled */
     891         [ #  # ]:          0 :         if (arg_fstab_enabled) {
     892                 :            :                 /* Parse the local /etc/fstab, possibly from the initrd */
     893                 :          0 :                 r2 = parse_fstab(false);
     894                 :            : 
     895                 :            :                 /* If running in the initrd also parse the /etc/fstab from the host */
     896         [ #  # ]:          0 :                 if (in_initrd())
     897                 :          0 :                         r3 = parse_fstab(true);
     898                 :            :                 else
     899                 :          0 :                         r3 = generator_enable_remount_fs_service(arg_dest);
     900                 :            :         }
     901                 :            : 
     902   [ #  #  #  # ]:          0 :         return r < 0 ? r : r2 < 0 ? r2 : r3;
     903                 :            : }
     904                 :            : 
     905   [ #  #  #  #  :          0 : DEFINE_MAIN_GENERATOR_FUNCTION(run);
          #  #  #  #  #  
                #  #  # ]

Generated by: LCOV version 1.14