[systemd-commits] 5 commits - src/core src/efi-boot-generator src/fstab-generator src/shared src/udev

Lennart Poettering lennart at kemper.freedesktop.org
Thu Mar 6 17:41:19 PST 2014


 src/core/mount.c                            |   14 -
 src/efi-boot-generator/efi-boot-generator.c |    2 
 src/fstab-generator/fstab-generator.c       |  201 +++++++++++++---------------
 src/shared/generator.c                      |    9 -
 src/shared/gpt.h                            |   22 ++-
 src/shared/util.c                           |   27 ++-
 src/shared/util.h                           |    2 
 src/udev/udev-builtin-blkid.c               |  102 +++++++++++++-
 8 files changed, 242 insertions(+), 137 deletions(-)

New commits:
commit 5ecdcf41cbce38c44b399993cb1c356280e0bafd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 7 02:39:59 2014 +0100

    fstab-generator: the root partition is not optional

diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 57d0a53..34cd720 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -189,6 +189,7 @@ static int add_mount(
                 return 0;
 
         if (path_equal(where, "/")) {
+                /* The root disk is not an option */
                 automount = false;
                 noauto = false;
                 nofail = false;
@@ -219,9 +220,7 @@ static int add_mount(
                 source);
 
         if (post && !noauto && !nofail && !automount)
-                fprintf(f,
-                        "Before=%s\n",
-                        post);
+                fprintf(f, "Before=%s\n", post);
 
         if (passno != 0) {
                 r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
@@ -249,17 +248,15 @@ static int add_mount(
                 return -errno;
         }
 
-        if (!noauto) {
-                if (post) {
-                        lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
-                        if (!lnk)
-                                return log_oom();
-
-                        mkdir_parents_label(lnk, 0755);
-                        if (symlink(unit, lnk) < 0) {
-                                log_error("Failed to create symlink %s: %m", lnk);
-                                return -errno;
-                        }
+        if (!noauto && post) {
+                lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
+                if (!lnk)
+                        return log_oom();
+
+                mkdir_parents_label(lnk, 0755);
+                if (symlink(unit, lnk) < 0) {
+                        log_error("Failed to create symlink %s: %m", lnk);
+                        return -errno;
                 }
         }
 
@@ -395,7 +392,6 @@ static int parse_fstab(bool initrd) {
 
 static int add_root_mount(void) {
         _cleanup_free_ char *o = NULL, *what = NULL;
-        bool noauto, nofail;
 
         if (isempty(arg_root_what)) {
                 log_debug("Could not find a root= entry on the kernel commandline.");
@@ -421,16 +417,14 @@ static int add_root_mount(void) {
         if (!o)
                 return log_oom();
 
-        noauto = mount_test_option(arg_root_options, "noauto");
-        nofail = mount_test_option(arg_root_options, "nofail");
-
         log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
         return add_mount(what,
                          "/sysroot",
                          arg_root_fstype,
                          o,
                          1,
-                         noauto, nofail,
+                         false,
+                         false,
                          false,
                          SPECIAL_INITRD_ROOT_FS_TARGET,
                          "/proc/cmdline");

commit a873c5bdf253057b8cd39a7e2affdd4ff8752827
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 7 02:39:01 2014 +0100

    efi-boot-generator: typo fix

diff --git a/src/efi-boot-generator/efi-boot-generator.c b/src/efi-boot-generator/efi-boot-generator.c
index 66d85bd..d4d7780 100644
--- a/src/efi-boot-generator/efi-boot-generator.c
+++ b/src/efi-boot-generator/efi-boot-generator.c
@@ -77,7 +77,7 @@ int main(int argc, char *argv[]) {
 
         r = efi_loader_get_device_part_uuid(&id);
         if (r == -ENOENT) {
-                log_debug("EFI loader partition unknown exiting.");
+                log_debug("EFI loader partition unknown, exiting.");
                 return EXIT_SUCCESS;
         } else if (r < 0) {
                 log_error("Failed to read ESP partition UUID: %s", strerror(-r));

commit cbd353ce7787ab11a9aa193f35abb97548b3fcf2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 7 02:35:19 2014 +0100

    udev-builtin-blkid: when we find a GPT partition marked as root disk on the same disk as the ESP, expose a property on the udev device
    
    This is preparation for a logic to automatically discover the root
    partition to boot from if no partition has been configured explicitly.
    
    This makes use of our newly defined GPT type GUIDs for our root disks:
    
     #define GPT_ROOT_X86    SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
     #define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
    
    We define differen GUIDs for different architectures to allow images
    which finde the right root partition for the appropriate arch.

diff --git a/src/shared/gpt.h b/src/shared/gpt.h
index 2956377..e23073e 100644
--- a/src/shared/gpt.h
+++ b/src/shared/gpt.h
@@ -21,8 +21,20 @@
 
 #include "sd-id128.h"
 
-#define GPT_ESP  SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
-#define GPT_ROOT SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
-#define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
-#define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
-#define GPT_SRV  SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8)
+/* We only support root disk discovery for x86 and x86-64 for now,
+ * since EFI for anything else doesn't really exist, and we only care
+ * for root partitions on the same disk as the EFI ESP. */
+
+#define GPT_ROOT_X86    SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
+#define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
+
+#define GPT_ESP         SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
+#define GPT_SWAP        SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
+#define GPT_HOME        SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
+#define GPT_SRV         SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8)
+
+#if defined(__x86_64__)
+#  define GPT_ROOT_NATIVE GPT_ROOT_X86_64
+#elif defined(__i386__)
+#  define GPT_ROOT_NATIVE GPT_ROOT_X86
+#endif
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index 23a24da..a49dd31 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -29,6 +29,9 @@
 #include <sys/stat.h>
 #include <blkid/blkid.h>
 
+#include "sd-id128.h"
+#include "gpt.h"
+#include "efivars.h"
 #include "udev.h"
 
 static void print_property(struct udev_device *dev, bool test, const char *name, const char *value)
@@ -100,6 +103,85 @@ static void print_property(struct udev_device *dev, bool test, const char *name,
         }
 }
 
+static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {
+
+#if defined(GPT_ROOT_NATIVE) && defined(ENABLE_EFI)
+
+        _cleanup_free_ char *root_id = NULL;
+        bool found_esp = false;
+        blkid_partlist pl;
+        int i, nvals, r;
+
+        assert(pr);
+
+        /* Iterate through the partitions on this disk, and see if the
+         * EFI ESP we booted from is on it. If so, find the first root
+         * disk, and add a property indicating its partition UUID. */
+
+        errno = 0;
+        pl = blkid_probe_get_partitions(pr);
+        if (!pl)
+                return errno ? -errno : -ENOMEM;
+
+        nvals = blkid_partlist_numof_partitions(pl);
+        for (i = 0; i < nvals; i++) {
+                blkid_partition pp;
+                const char *stype, *sid;
+                sd_id128_t type;
+
+                pp = blkid_partlist_get_partition(pl, i);
+                if (!pp)
+                        continue;
+
+                sid = blkid_partition_get_uuid(pp);
+                if (!sid)
+                        continue;
+
+                stype = blkid_partition_get_type_string(pp);
+                if (!stype)
+                        continue;
+
+                if (sd_id128_from_string(stype, &type) < 0)
+                        continue;
+
+                if (sd_id128_equal(type, GPT_ESP)) {
+                        sd_id128_t id, esp;
+
+                        /* We found an ESP, let's see if it matches
+                         * the ESP we booted from. */
+
+                        if (sd_id128_from_string(sid, &id) < 0)
+                                continue;
+
+                        r = efi_loader_get_device_part_uuid(&esp);
+                        if (r < 0)
+                                return r;
+
+                        if (sd_id128_equal(id, esp))
+                                found_esp = true;
+
+                } else if (sd_id128_equal(type, GPT_ROOT_NATIVE)) {
+
+                        /* We found a suitable root partition, let's
+                         * remember the first one. */
+
+                        if (!root_id) {
+                                root_id = strdup(sid);
+                                if (!root_id)
+                                        return -ENOMEM;
+                        }
+                }
+        }
+
+        /* We found the ESP on this disk, and also found a root
+         * partition, nice! Let's export its UUID*/
+        if (found_esp && root_id)
+                udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", root_id);
+#endif
+
+        return 0;
+}
+
 static int probe_superblocks(blkid_probe pr)
 {
         struct stat st;
@@ -145,6 +227,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
         int i;
         size_t len;
         int err = 0;
+        bool is_gpt = false;
 
         static const struct option options[] = {
                 { "offset", optional_argument, NULL, 'o' },
@@ -203,10 +286,17 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
         for (i = 0; i < nvals; i++) {
                 if (blkid_probe_get_value(pr, i, &name, &data, &len))
                         continue;
+
                 len = strnlen((char *) data, len);
                 print_property(dev, test, name, (char *) data);
+
+                if (streq(name, "PTTYPE") && streq(data, "gpt"))
+                        is_gpt = true;
         }
 
+        if (is_gpt)
+                find_gpt_root(dev, pr, test);
+
         blkid_free_probe(pr);
 out:
         if (err < 0)

commit d13394a88334441bf3092cf93804ba0f9c56d8e0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 7 02:34:18 2014 +0100

    udev-builtin-blkid: modernizations and minor fixes

diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index c806bd6..23a24da 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -33,7 +33,7 @@
 
 static void print_property(struct udev_device *dev, bool test, const char *name, const char *value)
 {
-        char s[265];
+        char s[256];
 
         s[0] = '\0';
 
@@ -110,7 +110,8 @@ static int probe_superblocks(blkid_probe pr)
 
         blkid_probe_enable_partitions(pr, 1);
 
-        if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 &&
+        if (!S_ISCHR(st.st_mode) &&
+            blkid_probe_get_size(pr) <= 1024 * 1440 &&
             blkid_probe_is_wholedisk(pr)) {
                 /*
                  * check if the small disk is partitioned, if yes then
@@ -120,7 +121,7 @@ static int probe_superblocks(blkid_probe pr)
 
                 rc = blkid_do_fullprobe(pr);
                 if (rc < 0)
-                        return rc;        /* -1 = error, 1 = nothing, 0 = succes */
+                        return rc;        /* -1 = error, 1 = nothing, 0 = success */
 
                 if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
                         return 0;        /* partition table detected */
@@ -136,7 +137,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
 {
         int64_t offset = 0;
         bool noraid = false;
-        int fd = -1;
+        _cleanup_close_ int fd = -1;
         blkid_probe pr;
         const char *data;
         const char *name;
@@ -208,10 +209,9 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
 
         blkid_free_probe(pr);
 out:
-        if (fd > 0)
-                close(fd);
         if (err < 0)
                 return EXIT_FAILURE;
+
         return EXIT_SUCCESS;
 }
 

commit 6db615c17ee7a434f9e0c40d67a1f833d8f3cc9d
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Mar 6 21:14:26 2014 +0100

    fstab-generator: merge /proc/cmdline parsing loops into one

diff --git a/src/core/mount.c b/src/core/mount.c
index 60067d4..b4b6080 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -62,20 +62,6 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 
-static char* mount_test_option(const char *haystack, const char *needle) {
-        struct mntent me = { .mnt_opts = (char*) haystack };
-
-        assert(needle);
-
-        /* Like glibc's hasmntopt(), but works on a string, not a
-         * struct mntent */
-
-        if (!haystack)
-                return NULL;
-
-        return hasmntopt(&me, needle);
-}
-
 static bool mount_is_network(MountParameters *p) {
         assert(p);
 
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 248a4ce..57d0a53 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -38,6 +38,10 @@
 
 static const char *arg_dest = "/tmp";
 static bool arg_fstab_enabled = true;
+static char *arg_root_what = NULL;
+static char *arg_root_fstype = NULL;
+static char *arg_root_options = NULL;
+static int arg_root_rw = -1;
 
 static int mount_find_pri(struct mntent *me, int *ret) {
         char *end, *pri;
@@ -152,7 +156,7 @@ static bool mount_in_initrd(struct mntent *me) {
 static int add_mount(
                 const char *what,
                 const char *where,
-                const char *type,
+                const char *fstype,
                 const char *opts,
                 int passno,
                 bool noauto,
@@ -169,11 +173,10 @@ static int add_mount(
 
         assert(what);
         assert(where);
-        assert(type);
         assert(opts);
         assert(source);
 
-        if (streq(type, "autofs"))
+        if (streq_ptr(fstype, "autofs"))
                 return 0;
 
         if (!is_path(where)) {
@@ -221,7 +224,7 @@ static int add_mount(
                         post);
 
         if (passno != 0) {
-                r = generator_write_fsck_deps(f, arg_dest, what, where, type);
+                r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
                 if (r < 0)
                         return r;
         }
@@ -230,16 +233,15 @@ static int add_mount(
                 "\n"
                 "[Mount]\n"
                 "What=%s\n"
-                "Where=%s\n"
-                "Type=%s\n",
+                "Where=%s\n",
                 what,
-                where,
-                type);
+                where);
+
+        if (!isempty(fstype) && !streq(fstype, "auto"))
+                fprintf(f, "Type=%s\n", fstype);
 
         if (!isempty(opts) && !streq(opts, "defaults"))
-                fprintf(f,
-                        "Options=%s\n",
-                        opts);
+                fprintf(f, "Options=%s\n", opts);
 
         fflush(f);
         if (ferror(f)) {
@@ -316,7 +318,7 @@ static int add_mount(
 }
 
 static int parse_fstab(bool initrd) {
-        _cleanup_endmntent_ FILE *f;
+        _cleanup_endmntent_ FILE *f = NULL;
         const char *fstab_path;
         struct mntent *me;
         int r = 0;
@@ -372,9 +374,16 @@ static int parse_fstab(bool initrd) {
                         else
                                 post = SPECIAL_LOCAL_FS_TARGET;
 
-                        k = add_mount(what, where, me->mnt_type, me->mnt_opts,
-                                      me->mnt_passno, noauto, nofail, automount,
-                                      post, fstab_path);
+                        k = add_mount(what,
+                                      where,
+                                      me->mnt_type,
+                                      me->mnt_opts,
+                                      me->mnt_passno,
+                                      noauto,
+                                      nofail,
+                                      automount,
+                                      post,
+                                      fstab_path);
                 }
 
                 if (k < 0)
@@ -384,90 +393,56 @@ static int parse_fstab(bool initrd) {
         return r;
 }
 
-static int parse_new_root_from_proc_cmdline(void) {
-        _cleanup_free_ char *what = NULL, *type = NULL, *opts = NULL, *line = NULL;
+static int add_root_mount(void) {
+        _cleanup_free_ char *o = NULL, *what = NULL;
         bool noauto, nofail;
-        char *w, *state;
-        size_t l;
-        int r;
-
-        r = proc_cmdline(&line);
-        if (r < 0)
-                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
-        if (r <= 0)
-                return 0;
-
-        opts = strdup("ro");
-        type = strdup("auto");
-        if (!opts || !type)
-                return log_oom();
-
-        /* root= and roofstype= may occur more than once, the last instance should take precedence.
-         * In the case of multiple rootflags= the arguments should be concatenated */
-        FOREACH_WORD_QUOTED(w, l, line, state) {
-                _cleanup_free_ char *word;
-
-                word = strndup(w, l);
-                if (!word)
-                        return log_oom();
 
-                else if (startswith(word, "root=")) {
-                        free(what);
-                        what = fstab_node_to_udev_node(word+5);
-                        if (!what)
-                                return log_oom();
-
-                } else if (startswith(word, "rootfstype=")) {
-                        free(type);
-                        type = strdup(word + 11);
-                        if (!type)
-                                return log_oom();
-
-                } else if (startswith(word, "rootflags=")) {
-                        char *o;
-
-                        o = strjoin(opts, ",", word + 10, NULL);
-                        if (!o)
-                                return log_oom();
-
-                        free(opts);
-                        opts = o;
-
-                } else if (streq(word, "ro") || streq(word, "rw")) {
-                        char *o;
-
-                        o = strjoin(opts, ",", word, NULL);
-                        if (!o)
-                                return log_oom();
-
-                        free(opts);
-                        opts = o;
-                }
-        }
-
-        noauto = !!strstr(opts, "noauto");
-        nofail = !!strstr(opts, "nofail");
-
-        if (!what) {
+        if (isempty(arg_root_what)) {
                 log_debug("Could not find a root= entry on the kernel commandline.");
                 return 0;
         }
 
-        if (what[0] != '/') {
-                log_debug("Skipping entry what=%s where=/sysroot type=%s", what, type);
+        what = fstab_node_to_udev_node(arg_root_what);
+        if (!path_is_absolute(what)) {
+                log_debug("Skipping entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
                 return 0;
         }
 
-        log_debug("Found entry what=%s where=/sysroot type=%s", what, type);
-        r = add_mount(what, "/sysroot", type, opts, 1, noauto, nofail, false,
-                      SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline");
+        if (!arg_root_options)
+                o = strdup(arg_root_rw > 0 ? "rw" : "ro");
+        else {
+                if (arg_root_rw >= 0 ||
+                    (!mount_test_option(arg_root_options, "ro") &&
+                     !mount_test_option(arg_root_options, "rw")))
+                        o = strjoin(arg_root_options, ",", arg_root_rw > 0 ? "rw" : "ro", NULL);
+                else
+                        o = strdup(arg_root_options);
+        }
+        if (!o)
+                return log_oom();
 
-        return (r < 0) ? r : 0;
+        noauto = mount_test_option(arg_root_options, "noauto");
+        nofail = mount_test_option(arg_root_options, "nofail");
+
+        log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
+        return add_mount(what,
+                         "/sysroot",
+                         arg_root_fstype,
+                         o,
+                         1,
+                         noauto, nofail,
+                         false,
+                         SPECIAL_INITRD_ROOT_FS_TARGET,
+                         "/proc/cmdline");
 }
 
 static int parse_proc_cmdline_item(const char *key, const char *value) {
         int r;
 
+        /* root= and roofstype= may occur more than once, the last
+         * instance should take precedence.  In the case of multiple
+         * rootflags= the arguments should be concatenated */
+
         if (STR_IN_SET(key, "fstab", "rd.fstab") && value) {
 
                 r = parse_boolean(value);
@@ -476,7 +451,37 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
                 else
                         arg_fstab_enabled = r;
 
-        } else if (startswith(key, "fstab.") || startswith(key, "rd.fstab."))
+        } else if (streq(key, "root") && value) {
+
+                free(arg_root_what);
+                arg_root_what = strdup(value);
+                if (!arg_root_what)
+                        return log_oom();
+
+        } else if (streq(key, "rootfstype") && value) {
+
+                free(arg_root_fstype);
+                arg_root_fstype = strdup(value);
+                if (!arg_root_fstype)
+                        return log_oom();
+
+        } else if (streq(key, "rootflags") && value) {
+                char *o;
+
+                o = arg_root_options ?
+                        strjoin(arg_root_options, ",", value, NULL) :
+                        strdup(value);
+                if (!o)
+                        return log_oom();
+
+                free(arg_root_options);
+                arg_root_options = o;
+
+        } else if (streq(key, "rw") && !value)
+                arg_root_rw = true;
+        else if (streq(key, "ro") && !value)
+                arg_root_rw = false;
+        else if (startswith(key, "fstab.") || startswith(key, "rd.fstab."))
                 log_warning("Unknown kernel switch %s. Ignoring.", key);
 
         return 0;
@@ -504,7 +509,7 @@ int main(int argc, char *argv[]) {
 
         /* Always honour root= in the kernel command line if we are in an initrd */
         if (in_initrd())
-                r = parse_new_root_from_proc_cmdline();
+                r = add_root_mount();
 
         /* Honour /etc/fstab only when that's enabled */
         if (arg_fstab_enabled) {
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 49647c1..6110303 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -32,20 +32,23 @@ int generator_write_fsck_deps(
                 const char *dest,
                 const char *what,
                 const char *where,
-                const char *type) {
+                const char *fstype) {
 
         assert(f);
+        assert(dest);
+        assert(what);
+        assert(where);
 
         if (!is_device_path(what)) {
                 log_warning("Checking was requested for \"%s\", but it is not a device.", what);
                 return 0;
         }
 
-        if (type && !streq(type, "auto")) {
+        if (!isempty(fstype) && !streq(fstype, "auto")) {
                 const char *checker;
                 int r;
 
-                checker = strappenda("/sbin/fsck.", type);
+                checker = strappenda("/sbin/fsck.", fstype);
                 r = access(checker, X_OK);
                 if (r < 0) {
                         log_warning("Checking was requested for %s, but %s cannot be used: %m", what, checker);
diff --git a/src/shared/util.c b/src/shared/util.c
index cffa1ab..d28caae 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3519,25 +3519,21 @@ int signal_from_string_try_harder(const char *s) {
 
 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
         _cleanup_free_ char *t = NULL, *u = NULL;
-        char *dn;
         size_t enc_len;
 
         u = unquote(tagvalue, "\"\'");
-        if (u == NULL)
+        if (!u)
                 return NULL;
 
         enc_len = strlen(u) * 4 + 1;
         t = new(char, enc_len);
-        if (t == NULL)
+        if (!t)
                 return NULL;
 
         if (encode_devnode_name(u, t, enc_len) < 0)
                 return NULL;
 
-        if (asprintf(&dn, "/dev/disk/by-%s/%s", by, t) < 0)
-                return NULL;
-
-        return dn;
+        return strjoin("/dev/disk/by-", by, "/", t, NULL);
 }
 
 char *fstab_node_to_udev_node(const char *p) {
@@ -6339,3 +6335,20 @@ uint64_t physical_memory(void) {
 
         return (uint64_t) mem * (uint64_t) page_size();
 }
+
+char* mount_test_option(const char *haystack, const char *needle) {
+
+        struct mntent me = {
+                .mnt_opts = (char*) haystack
+        };
+
+        assert(needle);
+
+        /* Like glibc's hasmntopt(), but works on a string, not a
+         * struct mntent */
+
+        if (!haystack)
+                return NULL;
+
+        return hasmntopt(&me, needle);
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index cd166f6..c2bc977 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -893,3 +893,5 @@ unsigned long personality_from_string(const char *p);
 const char *personality_to_string(unsigned long);
 
 uint64_t physical_memory(void);
+
+char* mount_test_option(const char *haystack, const char *needle);



More information about the systemd-commits mailing list