]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/fstab-generator/fstab-generator.c
fstab-generator: convert separate booleans to a flag field
[thirdparty/systemd.git] / src / fstab-generator / fstab-generator.c
index 243c1160b38d9b2503c575e0e62da5f45f5132cb..913992e365865dd021cf101e0483220c9f21384e 100644 (file)
@@ -26,8 +26,8 @@
 
 #include "alloc-util.h"
 #include "fd-util.h"
-#include "fs-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "fstab-util.h"
 #include "generator.h"
 #include "log.h"
@@ -38,6 +38,7 @@
 #include "path-util.h"
 #include "proc-cmdline.h"
 #include "special.h"
+#include "specifier.h"
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "virt.h"
 #include "volatile-util.h"
 
+typedef enum MountpointFlags {
+        NOAUTO    = 1 << 0,
+        NOFAIL    = 1 << 1,
+        AUTOMOUNT = 1 << 2,
+} MountpointFlags;
+
 static const char *arg_dest = "/tmp";
 static const char *arg_dest_late = "/tmp";
 static bool arg_fstab_enabled = true;
@@ -68,7 +75,7 @@ static int write_options(FILE *f, const char *options) {
         if (streq(options, "defaults"))
                 return 0;
 
-        o = strreplace(options, "%", "%%");
+        o = specifier_escape(options);
         if (!o)
                 return log_oom();
 
@@ -79,7 +86,7 @@ static int write_options(FILE *f, const char *options) {
 static int write_what(FILE *f, const char *what) {
         _cleanup_free_ char *w = NULL;
 
-        w = strreplace(what, "%", "%%");
+        w = specifier_escape(what);
         if (!w)
                 return log_oom();
 
@@ -90,8 +97,7 @@ static int write_what(FILE *f, const char *what) {
 static int add_swap(
                 const char *what,
                 struct mntent *me,
-                bool noauto,
-                bool nofail) {
+                MountpointFlags flags) {
 
         _cleanup_free_ char *name = NULL, *unit = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -149,9 +155,9 @@ static int add_swap(
         if (r < 0)
                 return r;
 
-        if (!noauto) {
+        if (!(flags & NOAUTO)) {
                 r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
-                                          nofail ? "wants" : "requires", name);
+                                          (flags & NOFAIL) ? "wants" : "requires", name);
                 if (r < 0)
                         return r;
         }
@@ -262,7 +268,7 @@ static int write_before(FILE *f, const char *opts) {
 }
 
 static int write_requires_mounts_for(FILE *f, const char *opts) {
-        _cleanup_strv_free_ char **paths = NULL;
+        _cleanup_strv_free_ char **paths = NULL, **paths_escaped = NULL;
         _cleanup_free_ char *res = NULL;
         int r;
 
@@ -275,7 +281,11 @@ static int write_requires_mounts_for(FILE *f, const char *opts) {
         if (r == 0)
                 return 0;
 
-        res = strv_join(paths, " ");
+        r = specifier_escape_strv(paths, &paths_escaped);
+        if (r < 0)
+                return log_error_errno(r, "Failed to escape paths: %m");
+
+        res = strv_join(paths_escaped, " ");
         if (!res)
                 return log_oom();
 
@@ -292,16 +302,15 @@ static int add_mount(
                 const char *fstype,
                 const char *opts,
                 int passno,
-                bool noauto,
-                bool nofail,
-                bool automount,
+                MountpointFlags flags,
                 const char *post,
                 const char *source) {
 
         _cleanup_free_ char
                 *name = NULL, *unit = NULL,
                 *automount_name = NULL, *automount_unit = NULL,
-                *filtered = NULL;
+                *filtered = NULL,
+                *where_escaped = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
@@ -324,14 +333,14 @@ static int add_mount(
                 return 0;
 
         if (path_equal(where, "/")) {
-                if (noauto)
+                if (flags & NOAUTO)
                         log_warning("Ignoring \"noauto\" for root device");
-                if (nofail)
+                if (flags & NOFAIL)
                         log_warning("Ignoring \"nofail\" for root device");
-                if (automount)
+                if (flags & AUTOMOUNT)
                         log_warning("Ignoring automount option for root device");
 
-                noauto = nofail = automount = false;
+                SET_FLAG(flags, NOAUTO | NOFAIL | AUTOMOUNT, false);
         }
 
         r = unit_name_from_path(where, ".mount", &name);
@@ -357,7 +366,7 @@ static int add_mount(
                 "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
                 source);
 
-        if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !automount &&
+        if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !(flags & AUTOMOUNT) &&
             fstab_test_yes_no_option(opts, "bg\0" "fg\0")) {
                 /* The default retry timeout that mount.nfs uses for 'bg' mounts
                  * is 10000 minutes, where as it uses 2 minutes for 'fg' mounts.
@@ -368,13 +377,13 @@ static int add_mount(
                  * By placing these options first, they can be over-ridden by
                  * settings in /etc/fstab. */
                 opts = strjoina("x-systemd.mount-timeout=infinity,retry=10000,", opts, ",fg");
-                nofail = true;
+                SET_FLAG(flags, NOFAIL, true);
         }
 
-        if (!nofail && !automount)
+        if (!(flags & NOFAIL) && !(flags & AUTOMOUNT))
                 fprintf(f, "Before=%s\n", post);
 
-        if (!automount && opts) {
+        if (!(flags & AUTOMOUNT) && opts) {
                  r = write_after(f, opts);
                  if (r < 0)
                          return r;
@@ -398,14 +407,25 @@ static int add_mount(
         fprintf(f, "\n[Mount]\n");
         if (original_where)
                 fprintf(f, "# Canonicalized from %s\n", original_where);
-        fprintf(f, "Where=%s\n", where);
+
+        where_escaped = specifier_escape(where);
+        if (!where_escaped)
+                return log_oom();
+        fprintf(f, "Where=%s\n", where_escaped);
 
         r = write_what(f, what);
         if (r < 0)
                 return r;
 
-        if (!isempty(fstype) && !streq(fstype, "auto"))
-                fprintf(f, "Type=%s\n", fstype);
+        if (!isempty(fstype) && !streq(fstype, "auto")) {
+                _cleanup_free_ char *t;
+
+                t = specifier_escape(fstype);
+                if (!t)
+                        return -ENOMEM;
+
+                fprintf(f, "Type=%s\n", t);
+        }
 
         r = generator_write_timeouts(dest, what, where, opts, &filtered);
         if (r < 0)
@@ -427,14 +447,14 @@ static int add_mount(
         if (r < 0)
                 return log_error_errno(r, "Failed to write unit file %s: %m", unit);
 
-        if (!noauto && !automount) {
+        if (!(flags & NOAUTO) && !(flags & AUTOMOUNT)) {
                 r = generator_add_symlink(dest, post,
-                                          nofail ? "wants" : "requires", name);
+                                          (flags & NOFAIL) ? "wants" : "requires", name);
                 if (r < 0)
                         return r;
         }
 
-        if (automount) {
+        if (flags & AUTOMOUNT) {
                 r = unit_name_from_path(where, ".automount", &automount_name);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate unit name: %m");
@@ -476,7 +496,7 @@ static int add_mount(
                         "\n"
                         "[Automount]\n"
                         "Where=%s\n",
-                        where);
+                        where_escaped);
 
                 r = write_idle_timeout(f, where, opts);
                 if (r < 0)
@@ -487,7 +507,7 @@ static int add_mount(
                         return log_error_errno(r, "Failed to write unit file %s: %m", automount_unit);
 
                 r = generator_add_symlink(dest, post,
-                                          nofail ? "wants" : "requires", automount_name);
+                                          (flags & NOFAIL) ? "wants" : "requires", automount_name);
                 if (r < 0)
                         return r;
         }
@@ -561,7 +581,8 @@ static int parse_fstab(bool initrd) {
                           yes_no(noauto), yes_no(nofail));
 
                 if (streq(me->mnt_type, "swap"))
-                        k = add_swap(what, me, noauto, nofail);
+                        k = add_swap(what, me,
+                                     noauto*NOAUTO | nofail*NOFAIL);
                 else {
                         bool automount;
                         const char *post;
@@ -583,9 +604,7 @@ static int parse_fstab(bool initrd) {
                                       me->mnt_type,
                                       me->mnt_opts,
                                       me->mnt_passno,
-                                      noauto,
-                                      nofail,
-                                      automount,
+                                      noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
                                       post,
                                       fstab_path);
                 }
@@ -646,9 +665,7 @@ static int add_sysroot_mount(void) {
                          arg_root_fstype,
                          opts,
                          is_device_path(what) ? 1 : 0, /* passno */
-                         false,                        /* noauto off */
-                         false,                        /* nofail off */
-                         false,                        /* automount off */
+                         0,                            /* noauto off, nofail off, automount off */
                          SPECIAL_INITRD_ROOT_FS_TARGET,
                          "/proc/cmdline");
 }
@@ -701,9 +718,7 @@ static int add_sysroot_usr_mount(void) {
                          arg_usr_fstype,
                          opts,
                          is_device_path(what) ? 1 : 0, /* passno */
-                         false,                        /* noauto off */
-                         false,                        /* nofail off */
-                         false,                        /* automount off */
+                         0,
                          SPECIAL_INITRD_FS_TARGET,
                          "/proc/cmdline");
 }
@@ -742,9 +757,7 @@ static int add_volatile_var(void) {
                          "tmpfs",
                          "mode=0755",
                          0,
-                         false,
-                         false,
-                         false,
+                         0,
                          SPECIAL_LOCAL_FS_TARGET,
                          "/proc/cmdline");
 }