X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fgpt-auto-generator%2Fgpt-auto-generator.c;h=99dc50fe3c3aa3cfe6159a9f25d8755cd594f0b2;hb=a7ed8946137bf16499ef3099013ae22bdac2dfc7;hp=25d868aa877c80a951f3c158ce767faf07a53c40;hpb=821b2e792159e237a1e5a1ea4bb6ae2e55d64be5;p=elogind.git diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 25d868aa8..99dc50fe3 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -21,15 +21,9 @@ #include #include -#include -#include #include #include -#ifdef HAVE_LINUX_BTRFS_H -#include -#endif - #include "sd-id128.h" #include "libudev.h" #include "path-util.h" @@ -45,6 +39,7 @@ #include "fileio.h" #include "efivars.h" #include "blkid-util.h" +#include "btrfs-util.h" static const char *arg_dest = "/tmp"; static bool arg_enabled = true; @@ -68,10 +63,8 @@ static int add_swap(const char *path) { return log_oom(); f = fopen(unit, "wxe"); - if (!f) { - log_error("Failed to create unit file %s: %m", unit); - return -errno; - } + if (!f) + return log_error_errno(errno, "Failed to create unit file %s: %m", unit); fprintf(f, "# Automatically generated by systemd-gpt-auto-generator\n\n" @@ -83,20 +76,16 @@ static int add_swap(const char *path) { path); fflush(f); - if (ferror(f)) { - log_error("Failed to write unit file %s: %m", unit); - return -errno; - } + if (ferror(f)) + return log_error_errno(errno, "Failed to write unit file %s: %m", unit); lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", 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 (symlink(unit, lnk) < 0) + return log_error_errno(errno, "Failed to create symlink %s: %m", lnk); return 0; } @@ -128,10 +117,8 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi return log_oom(); f = fopen(p, "wxe"); - if (!f) { - log_error("Failed to create unit file %s: %m", p); - return -errno; - } + if (!f) + return log_error_errno(errno, "Failed to create unit file %s: %m", p); fprintf(f, "# Automatically generated by systemd-gpt-auto-generator\n\n" @@ -144,7 +131,6 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi "Before=umount.target cryptsetup.target\n" "After=%s\n" "IgnoreOnIsolate=true\n" - "After=systemd-readahead-collect.service systemd-readahead-replay.service\n\n" "[Service]\n" "Type=oneshot\n" "RemainAfterExit=yes\n" @@ -156,22 +142,18 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi id); fflush(f); - if (ferror(f)) { - log_error("Failed to write file %s: %m", p); - return -errno; - } + if (ferror(f)) + return log_error_errno(errno, "Failed to write file %s: %m", p); - from = strappenda("../", n); + from = strjoina("../", n); to = strjoin(arg_dest, "/", d, ".wants/", n, NULL); if (!to) return log_oom(); mkdir_parents_label(to, 0755); - if (symlink(from, to) < 0) { - log_error("Failed to create symlink %s: %m", to); - return -errno; - } + if (symlink(from, to) < 0) + return log_error_errno(errno, "Failed to create symlink %s: %m", to); free(to); to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL); @@ -179,10 +161,8 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi return log_oom(); mkdir_parents_label(to, 0755); - if (symlink(from, to) < 0) { - log_error("Failed to create symlink %s: %m", to); - return -errno; - } + if (symlink(from, to) < 0) + return log_error_errno(errno, "Failed to create symlink %s: %m", to); free(to); to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL); @@ -190,10 +170,8 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi return log_oom(); mkdir_parents_label(to, 0755); - if (symlink(from, to) < 0) { - log_error("Failed to create symlink %s: %m", to); - return -errno; - } + if (symlink(from, to) < 0) + return log_error_errno(errno, "Failed to create symlink %s: %m", to); free(p); p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL); @@ -205,10 +183,8 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi "# Automatically generated by systemd-gpt-auto-generator\n\n" "[Unit]\n" "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */ - if (r < 0) { - log_error("Failed to write device drop-in: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to write device drop-in: %m"); ret = strappend("/dev/mapper/", id); if (!ret) @@ -257,10 +233,8 @@ static int add_mount( return log_oom(); f = fopen(p, "wxe"); - if (!f) { - log_error("Failed to create unit file %s: %m", unit); - return -errno; - } + if (!f) + return log_error_errno(errno, "Failed to create unit file %s: %m", unit); fprintf(f, "# Automatically generated by systemd-gpt-auto-generator\n\n" @@ -289,10 +263,8 @@ static int add_mount( fprintf(f, "Options=%s\n", rw ? "rw" : "ro"); fflush(f); - if (ferror(f)) { - log_error("Failed to write unit file %s: %m", p); - return -errno; - } + if (ferror(f)) + return log_error_errno(errno, "Failed to write unit file %s: %m", p); if (post) { lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL); @@ -300,10 +272,8 @@ static int add_mount( return log_oom(); mkdir_parents_label(lnk, 0755); - if (symlink(p, lnk) < 0) { - log_error("Failed to create symlink %s: %m", lnk); - return -errno; - } + if (symlink(p, lnk) < 0) + return log_error_errno(errno, "Failed to create symlink %s: %m", lnk); } return 0; @@ -318,7 +288,7 @@ static int probe_and_add_mount( const char *post) { _cleanup_blkid_free_probe_ blkid_probe b = NULL; - const char *fstype; + const char *fstype = NULL; int r; assert(id); @@ -340,7 +310,7 @@ static int probe_and_add_mount( if (!b) { if (errno == 0) return log_oom(); - log_error("Failed to allocate prober: %m"); + log_error_errno(errno, "Failed to allocate prober: %m"); return -errno; } @@ -351,14 +321,11 @@ static int probe_and_add_mount( r = blkid_do_safeprobe(b); if (r == -2 || r == 1) /* no result or uncertain */ return 0; - else if (r != 0) { - if (errno == 0) - errno = EIO; - log_error("Failed to probe %s: %m", what); - return -errno; - } + else if (r != 0) + return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what); - blkid_probe_lookup_value(b, "TYPE", &fstype, NULL); + /* add_mount is OK with fstype being NULL. */ + (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL); return add_mount( id, @@ -379,7 +346,7 @@ static int enumerate_partitions(dev_t devnum) { _cleanup_free_ char *home = NULL, *srv = NULL; struct udev_list_entry *first, *item; struct udev_device *parent = NULL; - const char *node, *pttype, *devtype; + const char *name, *node, *pttype, *devtype; int home_nr = -1, srv_nr = -1; bool home_rw = true, srv_rw = true; blkid_partlist pl; @@ -394,33 +361,42 @@ static int enumerate_partitions(dev_t devnum) { if (!d) return log_oom(); + name = udev_device_get_devnode(d); + if (!name) + name = udev_device_get_syspath(d); + if (!name) { + log_debug("Device %u:%u does not have a name, ignoring.", + major(devnum), minor(devnum)); + return 0; + } + parent = udev_device_get_parent(d); if (!parent) { - log_debug("Not a partitioned device, ignoring."); + log_debug("%s: not a partitioned device, ignoring.", name); return 0; } /* Does it have a devtype? */ devtype = udev_device_get_devtype(parent); if (!devtype) { - log_debug("Parent doesn't have a device type, ignoring."); + log_debug("%s: parent doesn't have a device type, ignoring.", name); return 0; } /* Is this a disk or a partition? We only care for disks... */ if (!streq(devtype, "disk")) { - log_debug("Parent isn't a raw disk, ignoring."); + log_debug("%s: parent isn't a raw disk, ignoring.", name); return 0; } /* Does it have a device node? */ node = udev_device_get_devnode(parent); if (!node) { - log_debug("Parent device does not have device node, ignoring."); + log_debug("%s: parent device does not have device node, ignoring.", name); return 0; } - log_debug("Root device %s.", node); + log_debug("%s: root device %s.", name, node); pn = udev_device_get_devnum(parent); if (major(pn) == 0) @@ -432,8 +408,7 @@ static int enumerate_partitions(dev_t devnum) { if (errno == 0) return log_oom(); - log_error("Failed allocate prober: %m"); - return -errno; + return log_error_errno(errno, "%s: failed to allocate prober: %m", node); } blkid_probe_enable_partitions(b, 1); @@ -443,25 +418,18 @@ static int enumerate_partitions(dev_t devnum) { r = blkid_do_safeprobe(b); if (r == -2 || r == 1) /* no result or uncertain */ return 0; - else if (r != 0) { - if (errno == 0) - errno = EIO; - log_error("Failed to probe %s: %m", node); - return -errno; - } + else if (r != 0) + return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node); errno = 0; r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL); - if (r != 0) { - if (errno == 0) - errno = EIO; - log_error("Failed to determine partition table type of %s: %m", node); - return -errno; - } + if (r != 0) + return log_error_errno(errno ?: EIO, + "%s: failed to determine partition table type: %m", node); /* We only do this all for GPT... */ if (!streq_ptr(pttype, "gpt")) { - log_debug("Not a GPT partition table, ignoring."); + log_debug("%s: not a GPT partition table, ignoring.", node); return 0; } @@ -471,8 +439,7 @@ static int enumerate_partitions(dev_t devnum) { if (errno == 0) return log_oom(); - log_error("Failed to list partitions of %s: %m", node); - return -errno; + return log_error_errno(errno, "%s: failed to list partitions: %m", node); } e = udev_enumerate_new(udev); @@ -488,10 +455,8 @@ static int enumerate_partitions(dev_t devnum) { return log_oom(); r = udev_enumerate_scan_devices(e); - if (r < 0) { - log_error("Failed to enumerate partitions on %s: %s", node, strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "%s: failed to enumerate partitions: %m", node); first = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(item, first) { @@ -546,7 +511,7 @@ static int enumerate_partitions(dev_t devnum) { if (sd_id128_equal(type_id, GPT_SWAP)) { if (flags & GPT_FLAG_READ_ONLY) { - log_debug("%s marked as read-only swap partition, which is bogus, ignoring.", subnode); + log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode); continue; } @@ -578,7 +543,7 @@ static int enumerate_partitions(dev_t devnum) { srv_rw = !(flags & GPT_FLAG_READ_ONLY), free(srv); - srv = strdup(node); + srv = strdup(subnode); if (!srv) return log_oom(); } @@ -599,54 +564,6 @@ static int enumerate_partitions(dev_t devnum) { return r; } -static int get_btrfs_block_device(const char *path, dev_t *dev) { - struct btrfs_ioctl_fs_info_args fsi = {}; - _cleanup_close_ int fd = -1; - uint64_t id; - - assert(path); - assert(dev); - - fd = open(path, O_DIRECTORY|O_CLOEXEC); - if (fd < 0) - return -errno; - - if (ioctl(fd, BTRFS_IOC_FS_INFO, &fsi) < 0) - return -errno; - - /* We won't do this for btrfs RAID */ - if (fsi.num_devices != 1) - return 0; - - for (id = 1; id <= fsi.max_id; id++) { - struct btrfs_ioctl_dev_info_args di = { - .devid = id, - }; - struct stat st; - - if (ioctl(fd, BTRFS_IOC_DEV_INFO, &di) < 0) { - if (errno == ENODEV) - continue; - - return -errno; - } - - if (stat((char*) di.path, &st) < 0) - return -errno; - - if (!S_ISBLK(st.st_mode)) - return -ENODEV; - - if (major(st.st_rdev) == 0) - return -ENODEV; - - *dev = st.st_rdev; - return 1; - } - - return -ENODEV; -} - static int get_block_device(const char *path, dev_t *dev) { struct stat st; struct statfs sfs; @@ -666,7 +583,7 @@ static int get_block_device(const char *path, dev_t *dev) { return -errno; if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) - return get_btrfs_block_device(path, dev); + return btrfs_get_block_device(path, dev); return 0; } @@ -680,9 +597,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value) { r = parse_boolean(value); if (r < 0) - log_warning("Failed to parse gpt-auto switch %s. Ignoring.", value); - - arg_enabled = r; + log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value); + else + arg_enabled = r; } else if (streq(key, "root") && value) { @@ -713,10 +630,8 @@ static int add_root_mount(void) { if (r == -ENOENT) { log_debug("EFI loader partition unknown, exiting."); return 0; - } else if (r < 0) { - log_error("Failed to read ESP partition UUID: %s", strerror(-r)); - return r; - } + } else if (r < 0) + return log_error_errno(r, "Failed to read ESP partition UUID: %m"); /* OK, we have an ESP partition, this is fantastic, so let's * wait for a root device to show up. A udev rule will create @@ -740,10 +655,9 @@ static int add_mounts(void) { int r; r = get_block_device("/", &devno); - if (r < 0) { - log_error("Failed to determine block device of root file system: %s", strerror(-r)); - return r; - } else if (r == 0) { + if (r < 0) + return log_error_errno(r, "Failed to determine block device of root file system: %m"); + else if (r == 0) { log_debug("Root file system not on a (single) block device."); return 0; } @@ -773,8 +687,9 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } - if (parse_proc_cmdline(parse_proc_cmdline_item) < 0) - return EXIT_FAILURE; + r = parse_proc_cmdline(parse_proc_cmdline_item); + if (r < 0) + log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); if (!arg_enabled) { log_debug("Disabled, exiting.");