]> git.proxmox.com Git - systemd.git/blame - src/fstab-generator/fstab-generator.c
Imported Upstream version 227
[systemd.git] / src / fstab-generator / fstab-generator.c
CommitLineData
663996b3
MS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2012 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <mntent.h>
24#include <errno.h>
25#include <string.h>
26#include <unistd.h>
27
28#include "log.h"
29#include "util.h"
30#include "unit-name.h"
31#include "path-util.h"
e735f4d4 32#include "fstab-util.h"
663996b3
MS
33#include "mount-setup.h"
34#include "special.h"
35#include "mkdir.h"
60f067b4
JS
36#include "generator.h"
37#include "strv.h"
38#include "virt.h"
663996b3
MS
39
40static const char *arg_dest = "/tmp";
60f067b4
JS
41static bool arg_fstab_enabled = true;
42static char *arg_root_what = NULL;
43static char *arg_root_fstype = NULL;
44static char *arg_root_options = NULL;
45static int arg_root_rw = -1;
5eef597e
MP
46static char *arg_usr_what = NULL;
47static char *arg_usr_fstype = NULL;
48static char *arg_usr_options = NULL;
e842803a 49
f47781d8
MP
50static int add_swap(
51 const char *what,
52 struct mntent *me,
53 bool noauto,
54 bool nofail) {
55
86f210e9 56 _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
663996b3 57 _cleanup_fclose_ FILE *f = NULL;
86f210e9 58 int r;
663996b3
MS
59
60 assert(what);
61 assert(me);
62
e735f4d4
MP
63 if (access("/proc/swaps", F_OK) < 0) {
64 log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
65 return 0;
66 }
67
6300502b 68 if (detect_container() > 0) {
60f067b4
JS
69 log_info("Running in a container, ignoring fstab swap entry for %s.", what);
70 return 0;
71 }
72
e3bff60a
MP
73 r = unit_name_from_path(what, ".swap", &name);
74 if (r < 0)
75 return log_error_errno(r, "Failed to generate unit name: %m");
663996b3
MS
76
77 unit = strjoin(arg_dest, "/", name, NULL);
78 if (!unit)
79 return log_oom();
80
81 f = fopen(unit, "wxe");
82 if (!f) {
83 if (errno == EEXIST)
84 log_error("Failed to create swap unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit);
85 else
f47781d8 86 log_error_errno(errno, "Failed to create unit file %s: %m", unit);
663996b3
MS
87 return -errno;
88 }
89
663996b3 90 fprintf(f,
14228c0d
MB
91 "# Automatically generated by systemd-fstab-generator\n\n"
92 "[Unit]\n"
60f067b4
JS
93 "SourcePath=/etc/fstab\n"
94 "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
663996b3
MS
95 "[Swap]\n"
96 "What=%s\n",
97 what);
98
86f210e9
MP
99 if (!isempty(me->mnt_opts) && !streq(me->mnt_opts, "defaults"))
100 fprintf(f, "Options=%s\n", me->mnt_opts);
5eef597e
MP
101
102 r = fflush_and_check(f);
f47781d8
MP
103 if (r < 0)
104 return log_error_errno(r, "Failed to write unit file %s: %m", unit);
663996b3 105
e842803a 106 /* use what as where, to have a nicer error message */
86f210e9 107 r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
e842803a
MB
108 if (r < 0)
109 return r;
110
663996b3 111 if (!noauto) {
f47781d8
MP
112 lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET,
113 nofail ? ".wants/" : ".requires/", name, NULL);
663996b3
MS
114 if (!lnk)
115 return log_oom();
116
117 mkdir_parents_label(lnk, 0755);
f47781d8
MP
118 if (symlink(unit, lnk) < 0)
119 return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
663996b3
MS
120 }
121
122 return 0;
123}
124
663996b3
MS
125static bool mount_is_network(struct mntent *me) {
126 assert(me);
127
e735f4d4
MP
128 return fstab_test_option(me->mnt_opts, "_netdev\0") ||
129 fstype_is_network(me->mnt_type);
663996b3
MS
130}
131
132static bool mount_in_initrd(struct mntent *me) {
133 assert(me);
134
e735f4d4
MP
135 return fstab_test_option(me->mnt_opts, "x-initrd.mount\0") ||
136 streq(me->mnt_dir, "/usr");
663996b3
MS
137}
138
e3bff60a
MP
139static int write_idle_timeout(FILE *f, const char *where, const char *opts) {
140 _cleanup_free_ char *timeout = NULL;
141 char timespan[FORMAT_TIMESPAN_MAX];
142 usec_t u;
143 int r;
144
145 r = fstab_filter_options(opts, "x-systemd.idle-timeout\0", NULL, &timeout, NULL);
146 if (r < 0)
147 return log_warning_errno(r, "Failed to parse options: %m");
148 if (r == 0)
149 return 0;
150
151 r = parse_sec(timeout, &u);
152 if (r < 0) {
153 log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
154 return 0;
155 }
156
157 fprintf(f, "TimeoutIdleSec=%s\n", format_timespan(timespan, sizeof(timespan), u, 0));
158
159 return 0;
160}
161
162static int write_requires_after(FILE *f, const char *opts) {
163 _cleanup_strv_free_ char **names = NULL, **units = NULL;
164 _cleanup_free_ char *res = NULL;
165 char **s;
166 int r;
167
168 assert(f);
169 assert(opts);
170
171 r = fstab_extract_values(opts, "x-systemd.requires", &names);
172 if (r < 0)
173 return log_warning_errno(r, "Failed to parse options: %m");
174 if (r == 0)
175 return 0;
176
177 STRV_FOREACH(s, names) {
178 char *x;
179
180 r = unit_name_mangle_with_suffix(*s, UNIT_NAME_NOGLOB, ".mount", &x);
181 if (r < 0)
182 return log_error_errno(r, "Failed to generate unit name: %m");
183 r = strv_consume(&units, x);
184 if (r < 0)
185 return log_oom();
186 }
187
188 if (units) {
189 res = strv_join(units, " ");
190 if (!res)
191 return log_oom();
192 fprintf(f, "After=%1$s\nRequires=%1$s\n", res);
193 }
194
195 return 0;
196}
197
198static int write_requires_mounts_for(FILE *f, const char *opts) {
199 _cleanup_strv_free_ char **paths = NULL;
200 _cleanup_free_ char *res = NULL;
201 int r;
202
203 assert(f);
204 assert(opts);
205
206 r = fstab_extract_values(opts, "x-systemd.requires-mounts-for", &paths);
207 if (r < 0)
208 return log_warning_errno(r, "Failed to parse options: %m");
209 if (r == 0)
210 return 0;
211
212 res = strv_join(paths, " ");
213 if (!res)
214 return log_oom();
215
216 fprintf(f, "RequiresMountsFor=%s\n", res);
217
218 return 0;
219}
220
663996b3
MS
221static int add_mount(
222 const char *what,
223 const char *where,
60f067b4 224 const char *fstype,
663996b3
MS
225 const char *opts,
226 int passno,
227 bool noauto,
228 bool nofail,
229 bool automount,
663996b3
MS
230 const char *post,
231 const char *source) {
60f067b4 232
663996b3 233 _cleanup_free_ char
14228c0d 234 *name = NULL, *unit = NULL, *lnk = NULL,
e842803a
MB
235 *automount_name = NULL, *automount_unit = NULL,
236 *filtered = NULL;
663996b3 237 _cleanup_fclose_ FILE *f = NULL;
60f067b4 238 int r;
663996b3
MS
239
240 assert(what);
241 assert(where);
663996b3
MS
242 assert(opts);
243 assert(source);
244
60f067b4 245 if (streq_ptr(fstype, "autofs"))
663996b3
MS
246 return 0;
247
248 if (!is_path(where)) {
249 log_warning("Mount point %s is not a valid path, ignoring.", where);
250 return 0;
251 }
252
253 if (mount_point_is_api(where) ||
254 mount_point_ignore(where))
255 return 0;
256
60f067b4 257 if (path_equal(where, "/")) {
e3bff60a
MP
258 if (noauto)
259 log_warning("Ignoring \"noauto\" for root device");
260 if (nofail)
261 log_warning("Ignoring \"nofail\" for root device");
262 if (automount)
263 log_warning("Ignoring automount option for root device");
264
265 noauto = nofail = automount = false;
60f067b4
JS
266 }
267
e3bff60a
MP
268 r = unit_name_from_path(where, ".mount", &name);
269 if (r < 0)
270 return log_error_errno(r, "Failed to generate unit name: %m");
663996b3
MS
271
272 unit = strjoin(arg_dest, "/", name, NULL);
273 if (!unit)
274 return log_oom();
275
276 f = fopen(unit, "wxe");
277 if (!f) {
278 if (errno == EEXIST)
279 log_error("Failed to create mount unit file %s, as it already exists. Duplicate entry in /etc/fstab?", unit);
280 else
f47781d8 281 log_error_errno(errno, "Failed to create unit file %s: %m", unit);
663996b3
MS
282 return -errno;
283 }
284
285 fprintf(f,
60f067b4
JS
286 "# Automatically generated by systemd-fstab-generator\n\n"
287 "[Unit]\n"
288 "SourcePath=%s\n"
289 "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
290 source);
663996b3 291
663996b3 292 if (post && !noauto && !nofail && !automount)
60f067b4
JS
293 fprintf(f, "Before=%s\n", post);
294
e3bff60a
MP
295 if (!automount && opts) {
296 r = write_requires_after(f, opts);
297 if (r < 0)
298 return r;
299 r = write_requires_mounts_for(f, opts);
300 if (r < 0)
301 return r;
302 }
303
60f067b4
JS
304 if (passno != 0) {
305 r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
306 if (r < 0)
307 return r;
308 }
663996b3
MS
309
310 fprintf(f,
311 "\n"
312 "[Mount]\n"
313 "What=%s\n"
60f067b4 314 "Where=%s\n",
663996b3 315 what,
60f067b4 316 where);
663996b3 317
60f067b4
JS
318 if (!isempty(fstype) && !streq(fstype, "auto"))
319 fprintf(f, "Type=%s\n", fstype);
320
e842803a
MB
321 r = generator_write_timeouts(arg_dest, what, where, opts, &filtered);
322 if (r < 0)
323 return r;
324
325 if (!isempty(filtered) && !streq(filtered, "defaults"))
326 fprintf(f, "Options=%s\n", filtered);
663996b3 327
e3bff60a
MP
328 r = fflush_and_check(f);
329 if (r < 0)
330 return log_error_errno(r, "Failed to write unit file %s: %m", unit);
663996b3 331
60f067b4
JS
332 if (!noauto && post) {
333 lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
334 if (!lnk)
335 return log_oom();
336
337 mkdir_parents_label(lnk, 0755);
f47781d8
MP
338 if (symlink(unit, lnk) < 0)
339 return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
663996b3
MS
340 }
341
60f067b4 342 if (automount) {
e3bff60a
MP
343 r = unit_name_from_path(where, ".automount", &automount_name);
344 if (r < 0)
345 return log_error_errno(r, "Failed to generate unit name: %m");
663996b3
MS
346
347 automount_unit = strjoin(arg_dest, "/", automount_name, NULL);
348 if (!automount_unit)
349 return log_oom();
350
351 fclose(f);
352 f = fopen(automount_unit, "wxe");
f47781d8
MP
353 if (!f)
354 return log_error_errno(errno, "Failed to create unit file %s: %m", automount_unit);
663996b3
MS
355
356 fprintf(f,
357 "# Automatically generated by systemd-fstab-generator\n\n"
358 "[Unit]\n"
60f067b4
JS
359 "SourcePath=%s\n"
360 "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
663996b3
MS
361 source);
362
363 if (post)
364 fprintf(f,
60f067b4 365 "Before=%s\n",
663996b3
MS
366 post);
367
e3bff60a
MP
368 if (opts) {
369 r = write_requires_after(f, opts);
370 if (r < 0)
371 return r;
372 r = write_requires_mounts_for(f, opts);
373 if (r < 0)
374 return r;
375 }
376
663996b3
MS
377 fprintf(f,
378 "[Automount]\n"
379 "Where=%s\n",
380 where);
381
e3bff60a
MP
382 r = write_idle_timeout(f, where, opts);
383 if (r < 0)
384 return r;
385
386 r = fflush_and_check(f);
387 if (r < 0)
388 return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit);
663996b3
MS
389
390 free(lnk);
391 lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL);
392 if (!lnk)
393 return log_oom();
394
395 mkdir_parents_label(lnk, 0755);
f47781d8
MP
396 if (symlink(automount_unit, lnk) < 0)
397 return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
663996b3
MS
398 }
399
400 return 0;
401}
402
60f067b4
JS
403static int parse_fstab(bool initrd) {
404 _cleanup_endmntent_ FILE *f = NULL;
405 const char *fstab_path;
663996b3 406 struct mntent *me;
60f067b4 407 int r = 0;
663996b3 408
60f067b4
JS
409 fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab";
410 f = setmntent(fstab_path, "re");
663996b3
MS
411 if (!f) {
412 if (errno == ENOENT)
413 return 0;
414
f47781d8 415 log_error_errno(errno, "Failed to open %s: %m", fstab_path);
663996b3
MS
416 return -errno;
417 }
418
419 while ((me = getmntent(f))) {
420 _cleanup_free_ char *where = NULL, *what = NULL;
f47781d8 421 bool noauto, nofail;
663996b3
MS
422 int k;
423
424 if (initrd && !mount_in_initrd(me))
425 continue;
426
427 what = fstab_node_to_udev_node(me->mnt_fsname);
60f067b4
JS
428 if (!what)
429 return log_oom();
430
e735f4d4 431 if (is_device_path(what) && path_is_read_only_fs("sys") > 0) {
60f067b4
JS
432 log_info("Running in a container, ignoring fstab device entry for %s.", what);
433 continue;
663996b3
MS
434 }
435
60f067b4
JS
436 where = initrd ? strappend("/sysroot/", me->mnt_dir) : strdup(me->mnt_dir);
437 if (!where)
438 return log_oom();
439
663996b3
MS
440 if (is_path(where))
441 path_kill_slashes(where);
442
e735f4d4
MP
443 noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
444 nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
f47781d8
MP
445 log_debug("Found entry what=%s where=%s type=%s nofail=%s noauto=%s",
446 what, where, me->mnt_type,
447 yes_no(noauto), yes_no(nofail));
663996b3
MS
448
449 if (streq(me->mnt_type, "swap"))
f47781d8 450 k = add_swap(what, me, noauto, nofail);
663996b3 451 else {
f47781d8 452 bool automount;
14228c0d 453 const char *post;
663996b3 454
e735f4d4
MP
455 automount = fstab_test_option(me->mnt_opts,
456 "comment=systemd.automount\0"
457 "x-systemd.automount\0");
60f067b4 458 if (initrd)
663996b3 459 post = SPECIAL_INITRD_FS_TARGET;
60f067b4 460 else if (mount_in_initrd(me))
663996b3 461 post = SPECIAL_INITRD_ROOT_FS_TARGET;
60f067b4 462 else if (mount_is_network(me))
663996b3 463 post = SPECIAL_REMOTE_FS_TARGET;
60f067b4 464 else
663996b3 465 post = SPECIAL_LOCAL_FS_TARGET;
663996b3 466
60f067b4
JS
467 k = add_mount(what,
468 where,
469 me->mnt_type,
470 me->mnt_opts,
471 me->mnt_passno,
472 noauto,
473 nofail,
474 automount,
475 post,
476 fstab_path);
663996b3
MS
477 }
478
479 if (k < 0)
480 r = k;
481 }
482
663996b3
MS
483 return r;
484}
485
e3bff60a 486static int add_sysroot_mount(void) {
e842803a
MB
487 _cleanup_free_ char *what = NULL;
488 const char *opts;
663996b3 489
60f067b4 490 if (isempty(arg_root_what)) {
f47781d8 491 log_debug("Could not find a root= entry on the kernel command line.");
663996b3
MS
492 return 0;
493 }
494
60f067b4 495 what = fstab_node_to_udev_node(arg_root_what);
e3bff60a
MP
496 if (!what)
497 return log_oom();
663996b3 498
60f067b4 499 if (!arg_root_options)
e842803a
MB
500 opts = arg_root_rw > 0 ? "rw" : "ro";
501 else if (arg_root_rw >= 0 ||
e735f4d4
MP
502 !fstab_test_option(arg_root_options, "ro\0" "rw\0"))
503 opts = strjoina(arg_root_options, ",", arg_root_rw > 0 ? "rw" : "ro");
e842803a
MB
504 else
505 opts = arg_root_options;
663996b3 506
60f067b4
JS
507 log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
508 return add_mount(what,
509 "/sysroot",
510 arg_root_fstype,
e842803a 511 opts,
e3bff60a 512 is_device_path(what) ? 1 : 0,
60f067b4
JS
513 false,
514 false,
515 false,
516 SPECIAL_INITRD_ROOT_FS_TARGET,
517 "/proc/cmdline");
663996b3
MS
518}
519
e3bff60a 520static int add_sysroot_usr_mount(void) {
5eef597e
MP
521 _cleanup_free_ char *what = NULL;
522 const char *opts;
523
524 if (!arg_usr_what && !arg_usr_fstype && !arg_usr_options)
525 return 0;
526
527 if (arg_root_what && !arg_usr_what) {
528 arg_usr_what = strdup(arg_root_what);
529
530 if (!arg_usr_what)
531 return log_oom();
532 }
533
534 if (arg_root_fstype && !arg_usr_fstype) {
535 arg_usr_fstype = strdup(arg_root_fstype);
536
537 if (!arg_usr_fstype)
538 return log_oom();
539 }
540
541 if (arg_root_options && !arg_usr_options) {
542 arg_usr_options = strdup(arg_root_options);
543
544 if (!arg_usr_options)
545 return log_oom();
546 }
547
f47781d8 548 if (!arg_usr_what)
5eef597e
MP
549 return 0;
550
551 what = fstab_node_to_udev_node(arg_usr_what);
552 if (!path_is_absolute(what)) {
553 log_debug("Skipping entry what=%s where=/sysroot/usr type=%s", what, strna(arg_usr_fstype));
554 return -1;
555 }
556
f47781d8
MP
557 if (!arg_usr_options)
558 opts = arg_root_rw > 0 ? "rw" : "ro";
e735f4d4
MP
559 else if (!fstab_test_option(arg_usr_options, "ro\0" "rw\0"))
560 opts = strjoina(arg_usr_options, ",", arg_root_rw > 0 ? "rw" : "ro");
f47781d8
MP
561 else
562 opts = arg_usr_options;
5eef597e
MP
563
564 log_debug("Found entry what=%s where=/sysroot/usr type=%s", what, strna(arg_usr_fstype));
565 return add_mount(what,
566 "/sysroot/usr",
567 arg_usr_fstype,
568 opts,
569 1,
570 false,
571 false,
572 false,
573 SPECIAL_INITRD_ROOT_FS_TARGET,
574 "/proc/cmdline");
575}
576
60f067b4 577static int parse_proc_cmdline_item(const char *key, const char *value) {
663996b3 578 int r;
663996b3 579
5eef597e
MP
580 /* root=, usr=, usrfstype= and roofstype= may occur more than once, the last
581 * instance should take precedence. In the case of multiple rootflags=
582 * or usrflags= the arguments should be concatenated */
663996b3 583
60f067b4
JS
584 if (STR_IN_SET(key, "fstab", "rd.fstab") && value) {
585
586 r = parse_boolean(value);
587 if (r < 0)
588 log_warning("Failed to parse fstab switch %s. Ignoring.", value);
589 else
590 arg_fstab_enabled = r;
663996b3 591
60f067b4 592 } else if (streq(key, "root") && value) {
663996b3 593
5eef597e 594 if (free_and_strdup(&arg_root_what, value) < 0)
663996b3
MS
595 return log_oom();
596
60f067b4 597 } else if (streq(key, "rootfstype") && value) {
663996b3 598
5eef597e 599 if (free_and_strdup(&arg_root_fstype, value) < 0)
60f067b4 600 return log_oom();
663996b3 601
60f067b4
JS
602 } else if (streq(key, "rootflags") && value) {
603 char *o;
663996b3 604
60f067b4
JS
605 o = arg_root_options ?
606 strjoin(arg_root_options, ",", value, NULL) :
607 strdup(value);
608 if (!o)
609 return log_oom();
663996b3 610
60f067b4
JS
611 free(arg_root_options);
612 arg_root_options = o;
613
5eef597e
MP
614 } else if (streq(key, "mount.usr") && value) {
615
616 if (free_and_strdup(&arg_usr_what, value) < 0)
617 return log_oom();
618
619 } else if (streq(key, "mount.usrfstype") && value) {
620
621 if (free_and_strdup(&arg_usr_fstype, value) < 0)
622 return log_oom();
623
624 } else if (streq(key, "mount.usrflags") && value) {
625 char *o;
626
627 o = arg_usr_options ?
628 strjoin(arg_usr_options, ",", value, NULL) :
629 strdup(value);
630 if (!o)
631 return log_oom();
632
633 free(arg_usr_options);
634 arg_usr_options = o;
635
60f067b4
JS
636 } else if (streq(key, "rw") && !value)
637 arg_root_rw = true;
638 else if (streq(key, "ro") && !value)
639 arg_root_rw = false;
663996b3
MS
640
641 return 0;
642}
643
644int main(int argc, char *argv[]) {
60f067b4 645 int r = 0;
663996b3
MS
646
647 if (argc > 1 && argc != 4) {
648 log_error("This program takes three or no arguments.");
649 return EXIT_FAILURE;
650 }
651
652 if (argc > 1)
653 arg_dest = argv[1];
654
655 log_set_target(LOG_TARGET_SAFE);
656 log_parse_environment();
657 log_open();
658
659 umask(0022);
660
f47781d8
MP
661 r = parse_proc_cmdline(parse_proc_cmdline_item);
662 if (r < 0)
663 log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
663996b3 664
5eef597e
MP
665 /* Always honour root= and usr= in the kernel command line if we are in an initrd */
666 if (in_initrd()) {
e3bff60a 667 r = add_sysroot_mount();
5eef597e 668 if (r == 0)
e3bff60a 669 r = add_sysroot_usr_mount();
5eef597e 670 }
663996b3 671
60f067b4
JS
672 /* Honour /etc/fstab only when that's enabled */
673 if (arg_fstab_enabled) {
674 int k;
663996b3 675
e842803a
MB
676 log_debug("Parsing /etc/fstab");
677
60f067b4
JS
678 /* Parse the local /etc/fstab, possibly from the initrd */
679 k = parse_fstab(false);
680 if (k < 0)
681 r = k;
663996b3 682
60f067b4
JS
683 /* If running in the initrd also parse the /etc/fstab from the host */
684 if (in_initrd()) {
e842803a
MB
685 log_debug("Parsing /sysroot/etc/fstab");
686
60f067b4
JS
687 k = parse_fstab(true);
688 if (k < 0)
689 r = k;
690 }
691 }
663996b3 692
5eef597e 693 free(arg_root_what);
f47781d8
MP
694 free(arg_root_fstype);
695 free(arg_root_options);
696
697 free(arg_usr_what);
698 free(arg_usr_fstype);
699 free(arg_usr_options);
5eef597e 700
60f067b4 701 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
663996b3 702}