X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fgpt-auto-generator%2Fgpt-auto-generator.c;h=05934da82f8a18a8495bbade7ebe4357112811f9;hp=55fd6d6a7d9118e9055fdcdde19b6cb62962a121;hb=b94801803417c23d099cb7e508754181ecd27f9c;hpb=b47d419c25ecc735615a1088060c1ec8bef1e41f diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 55fd6d6a7..05934da82 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #ifdef HAVE_LINUX_BTRFS_H #include @@ -36,6 +36,7 @@ #include "missing.h" #include "sd-id128.h" #include "libudev.h" +#include "udev-util.h" #include "special.h" #include "unit-name.h" #include "virt.h" @@ -53,10 +54,7 @@ static const char *arg_dest = "/tmp"; -static inline void blkid_free_probep(blkid_probe *b) { - if (*b) - blkid_free_probe(*b); -} +DEFINE_TRIVIAL_CLEANUP_FUNC(blkid_probe, blkid_free_probe); #define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep) static int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr, char **fstype) { @@ -76,10 +74,8 @@ static int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr errno = 0; r = blkid_do_safeprobe(b); - if (r == -2) - return -ENODEV; - else if (r == 1) - return -ENODEV; + if (r == -2 || r == 1) /* no result or uncertain */ + return -EBADSLT; else if (r != 0) return errno ? -errno : -EIO; @@ -184,7 +180,7 @@ static int add_swap(const char *path, const char *fstype) { } static int add_home(const char *path, const char *fstype) { - _cleanup_free_ char *unit = NULL, *lnk = NULL; + _cleanup_free_ char *unit = NULL, *lnk = NULL, *fsck = NULL; _cleanup_fclose_ FILE *f = NULL; if (dir_is_empty("/home") <= 0) @@ -202,19 +198,23 @@ static int add_home(const char *path, const char *fstype) { return -errno; } + fsck = unit_name_from_path_instance("systemd-fsck", path, ".service"); + if (!fsck) + return log_oom(); + fprintf(f, "# Automatically generated by systemd-gpt-auto-generator\n\n" "[Unit]\n" "DefaultDependencies=no\n" - "After=" SPECIAL_LOCAL_FS_PRE_TARGET "\n" + "Requires=%s\n" + "After=" SPECIAL_LOCAL_FS_PRE_TARGET " %s\n" "Conflicts=" SPECIAL_UMOUNT_TARGET "\n" "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_LOCAL_FS_TARGET "\n\n" "[Mount]\n" "What=%s\n" "Where=/home\n" - "Type=%s\n" - "FsckPassNo=2\n", - path, fstype); + "Type=%s\n", + fsck, fsck, path, fstype); fflush(f); if (ferror(f)) { @@ -226,7 +226,6 @@ static int add_home(const char *path, const char *fstype) { if (!lnk) return log_oom(); - mkdir_parents_label(lnk, 0755); if (symlink(unit, lnk) < 0) { log_error("Failed to create symlink %s: %m", lnk); @@ -237,8 +236,9 @@ static int add_home(const char *path, const char *fstype) { } static int enumerate_partitions(struct udev *udev, dev_t dev) { - struct udev_enumerate *e = NULL; - struct udev_device *parent = NULL, *d = NULL; + struct udev_device *parent = NULL; + _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; + _cleanup_udev_device_unref_ struct udev_device *d = NULL; struct udev_list_entry *first, *item; unsigned home_nr = (unsigned) -1; _cleanup_free_ char *home = NULL, *home_fstype = NULL; @@ -249,71 +249,61 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { return log_oom(); d = udev_device_new_from_devnum(udev, 'b', dev); - if (!d) { - r = log_oom(); - goto finish; - } + if (!d) + return log_oom(); parent = udev_device_get_parent(d); - if (!parent) { - r = log_oom(); - goto finish; - } + if (!parent) + return log_oom(); r = udev_enumerate_add_match_parent(e, parent); - if (r < 0) { - r = log_oom(); - goto finish; - } + if (r < 0) + return log_oom(); r = udev_enumerate_add_match_subsystem(e, "block"); - if (r < 0) { - r = log_oom(); - goto finish; - } + if (r < 0) + return log_oom(); r = udev_enumerate_scan_devices(e); if (r < 0) { log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s", major(dev), minor(dev), strerror(-r)); - goto finish; + return r; } first = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(item, first) { _cleanup_free_ char *fstype = NULL; const char *node = NULL; - struct udev_device *q; + _cleanup_udev_device_unref_ struct udev_device *q; sd_id128_t type_id; unsigned nr; q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); - if (!q) { - r = log_oom(); - goto finish; - } + if (!q) + return log_oom(); if (udev_device_get_devnum(q) == udev_device_get_devnum(d)) - goto skip; + continue; if (udev_device_get_devnum(q) == udev_device_get_devnum(parent)) - goto skip; + continue; node = udev_device_get_devnode(q); - if (!node) { - r = log_oom(); - goto finish; - } + if (!node) + return log_oom(); r = verify_gpt_partition(node, &type_id, &nr, &fstype); if (r < 0) { + /* skip child devices which are not detected properly */ + if (r == -EBADSLT) + continue; log_error("Failed to verify GPT partition %s: %s", node, strerror(-r)); - udev_device_unref(q); - goto finish; + return r; } if (r == 0) - goto skip; + continue; if (sd_id128_equal(type_id, GPT_SWAP)) add_swap(node, fstype); @@ -321,10 +311,8 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { if (!home || nr < home_nr) { free(home); home = strdup(node); - if (!home) { - r = log_oom(); - goto finish; - } + if (!home) + return log_oom(); home_nr = nr; @@ -333,22 +321,11 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) { fstype = NULL; } } - - skip: - udev_device_unref(q); } if (home && home_fstype) add_home(home, home_fstype); -finish: - if (d) - udev_device_unref(d); - - if (e) - udev_enumerate_unref(e); - - return r; } @@ -425,41 +402,31 @@ static int get_block_device(const char *path, dev_t *dev) { } static int devno_to_devnode(struct udev *udev, dev_t devno, char **ret) { - struct udev_device *d = NULL; + _cleanup_udev_device_unref_ struct udev_device *d; const char *t; char *n; - int r; d = udev_device_new_from_devnum(udev, 'b', devno); if (!d) return log_oom(); t = udev_device_get_devnode(d); - if (!t) { - r = -ENODEV; - goto finish; - } + if (!t) + return -ENODEV; n = strdup(t); - if (!n) { - r = -ENOMEM; - goto finish; - } + if (!n) + return -ENOMEM; *ret = n; - r = 0; - -finish: - udev_device_unref(d); - - return r; + return 0; } int main(int argc, char *argv[]) { _cleanup_free_ char *node = NULL; - struct udev *udev = NULL; + _cleanup_udev_unref_ struct udev *udev = NULL; dev_t devno; - int r; + int r = 0; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); @@ -478,13 +445,11 @@ int main(int argc, char *argv[]) { if (in_initrd()) { log_debug("In initrd, exiting."); - r = 0; goto finish; } if (detect_container(NULL) > 0) { log_debug("In a container, exiting."); - r = 0; goto finish; } @@ -523,8 +488,5 @@ int main(int argc, char *argv[]) { r = enumerate_partitions(udev, devno); finish: - if (udev) - udev_unref(udev); - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }