X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fgpt-auto-generator%2Fgpt-auto-generator.c;h=32e9b78a1dc4e97ddb81aac01fb5929a28942408;hb=144232a8e0ea77eed8c5a456832758681b5b3511;hp=67d0f2a5b902603ed255a44dc050403a9c46739a;hpb=61331eab0a53cd9b8446eab6d1ebf1a046d8efc1;p=elogind.git diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 67d0f2a5b..32e9b78a1 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -44,15 +44,13 @@ #include "gpt.h" #include "fileio.h" #include "efivars.h" +#include "blkid-util.h" static const char *arg_dest = "/tmp"; static bool arg_enabled = true; static bool arg_root_enabled = true; static bool arg_root_rw = false; -DEFINE_TRIVIAL_CLEANUP_FUNC(blkid_probe, blkid_free_probe); -#define _cleanup_blkid_free_probe_ _cleanup_(blkid_free_probep) - static int add_swap(const char *path) { _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -70,10 +68,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" @@ -85,25 +81,21 @@ 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; } -static int add_cryptsetup(const char *id, const char *what, char **device) { +static int add_cryptsetup(const char *id, const char *what, bool rw, char **device) { _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL; _cleanup_fclose_ FILE *f = NULL; char *from, *ret; @@ -126,14 +118,12 @@ static int add_cryptsetup(const char *id, const char *what, char **device) { return log_oom(); p = strjoin(arg_dest, "/", n, NULL); - if (!n) + if (!p) 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" @@ -146,22 +136,19 @@ static int add_cryptsetup(const char *id, const char *what, char **device) { "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" "TimeoutSec=0\n" /* the binary handles timeouts anyway */ - "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s'\n" + "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n" "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n", d, d, - id, what, + id, what, rw ? "" : "read-only", 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); @@ -170,10 +157,8 @@ static int add_cryptsetup(const char *id, const char *what, char **device) { 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); @@ -181,10 +166,8 @@ static int add_cryptsetup(const char *id, const char *what, char **device) { 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); @@ -192,10 +175,8 @@ static int add_cryptsetup(const char *id, const char *what, char **device) { 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); @@ -207,10 +188,8 @@ static int add_cryptsetup(const char *id, const char *what, char **device) { "# 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) @@ -225,7 +204,7 @@ static int add_mount( const char *what, const char *where, const char *fstype, - const char *options, + bool rw, const char *description, const char *post) { @@ -242,7 +221,7 @@ static int add_mount( if (streq_ptr(fstype, "crypto_LUKS")) { - r = add_cryptsetup(id, what, &crypto_what); + r = add_cryptsetup(id, what, rw, &crypto_what); if (r < 0) return r; @@ -259,10 +238,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" @@ -288,14 +265,11 @@ static int add_mount( if (fstype) fprintf(f, "Type=%s\n", fstype); - if (options) - fprintf(f, "Options=%s\n", options); + 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); @@ -303,10 +277,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; @@ -316,6 +288,7 @@ static int probe_and_add_mount( const char *id, const char *what, const char *where, + bool rw, const char *description, const char *post) { @@ -342,7 +315,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; } @@ -356,7 +329,7 @@ static int probe_and_add_mount( else if (r != 0) { if (errno == 0) errno = EIO; - log_error("Failed to probe %s: %m", what); + log_error_errno(errno, "Failed to probe %s: %m", what); return -errno; } @@ -367,7 +340,7 @@ static int probe_and_add_mount( what, where, fstype, - NULL, + rw, description, post); } @@ -383,6 +356,7 @@ static int enumerate_partitions(dev_t devnum) { struct udev_device *parent = NULL; const char *node, *pttype, *devtype; int home_nr = -1, srv_nr = -1; + bool home_rw = true, srv_rw = true; blkid_partlist pl; int r, k; dev_t pn; @@ -396,22 +370,30 @@ static int enumerate_partitions(dev_t devnum) { return log_oom(); parent = udev_device_get_parent(d); - if (!parent) - return log_oom(); + if (!parent) { + log_debug("Not a partitioned device, ignoring."); + return 0; + } /* Does it have a devtype? */ devtype = udev_device_get_devtype(parent); - if (!devtype) + if (!devtype) { + log_debug("Parent doesn't have a device type, ignoring."); return 0; + } /* Is this a disk or a partition? We only care for disks... */ - if (!streq(devtype, "disk")) + if (!streq(devtype, "disk")) { + log_debug("Parent isn't a raw disk, ignoring."); return 0; + } /* Does it have a device node? */ node = udev_device_get_devnode(parent); - if (!node) + if (!node) { + log_debug("Parent device does not have device node, ignoring."); return 0; + } log_debug("Root device %s.", node); @@ -425,12 +407,10 @@ static int enumerate_partitions(dev_t devnum) { if (errno == 0) return log_oom(); - log_error("Failed allocate prober: %m"); + log_error_errno(errno, "Failed allocate prober: %m"); return -errno; } - blkid_probe_enable_superblocks(b, 1); - blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE); blkid_probe_enable_partitions(b, 1); blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS); @@ -441,7 +421,7 @@ static int enumerate_partitions(dev_t devnum) { else if (r != 0) { if (errno == 0) errno = EIO; - log_error("Failed to probe %s: %m", node); + log_error_errno(errno, "Failed to probe %s: %m", node); return -errno; } @@ -450,13 +430,15 @@ static int enumerate_partitions(dev_t devnum) { if (r != 0) { if (errno == 0) errno = EIO; - log_error("Failed to determine partition table type of %s: %m", node); + log_error_errno(errno, "Failed to determine partition table type of %s: %m", node); return -errno; } /* We only do this all for GPT... */ - if (!streq_ptr(pttype, "gpt")) + if (!streq_ptr(pttype, "gpt")) { + log_debug("Not a GPT partition table, ignoring."); return 0; + } errno = 0; pl = blkid_probe_get_partitions(b); @@ -464,7 +446,7 @@ static int enumerate_partitions(dev_t devnum) { if (errno == 0) return log_oom(); - log_error("Failed to list of partitions of %s: %m", node); + log_error_errno(errno, "Failed to list partitions of %s: %m", node); return -errno; } @@ -481,10 +463,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, "Failed to enumerate partitions on %s: %m", node); first = udev_enumerate_get_list_entry(e); udev_list_entry_foreach(item, first) { @@ -494,6 +474,7 @@ static int enumerate_partitions(dev_t devnum) { blkid_partition pp; dev_t qn; int nr; + unsigned long long flags; q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); if (!q) @@ -517,6 +498,13 @@ static int enumerate_partitions(dev_t devnum) { if (!pp) continue; + flags = blkid_partition_get_flags(pp); + + /* Ignore partitions that are not marked for automatic + * mounting on discovery */ + if (flags & GPT_FLAG_NO_AUTO) + continue; + nr = blkid_partition_get_partno(pp); if (nr < 0) continue; @@ -530,6 +518,11 @@ 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); + continue; + } + k = add_swap(subnode); if (k < 0) r = k; @@ -541,6 +534,7 @@ static int enumerate_partitions(dev_t devnum) { continue; home_nr = nr; + home_rw = !(flags & GPT_FLAG_READ_ONLY), free(home); home = strdup(subnode); @@ -554,6 +548,7 @@ static int enumerate_partitions(dev_t devnum) { continue; srv_nr = nr; + srv_rw = !(flags & GPT_FLAG_READ_ONLY), free(srv); srv = strdup(node); @@ -563,13 +558,13 @@ static int enumerate_partitions(dev_t devnum) { } if (home) { - k = probe_and_add_mount("home", home, "/home", "Home Partition", SPECIAL_LOCAL_FS_TARGET); + k = probe_and_add_mount("home", home, "/home", home_rw, "Home Partition", SPECIAL_LOCAL_FS_TARGET); if (k < 0) r = k; } if (srv) { - k = probe_and_add_mount("srv", srv, "/srv", "Server Data Partition", SPECIAL_LOCAL_FS_TARGET); + k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET); if (k < 0) r = k; } @@ -659,8 +654,8 @@ 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; + else + arg_enabled = r; } else if (streq(key, "root") && value) { @@ -673,8 +668,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value) { arg_root_rw = true; else if (streq(key, "ro") && !value) arg_root_rw = false; - else if (startswith(key, "systemd.gpt-auto.") || startswith(key, "rd.systemd.gpt-auto.")) - log_warning("Unknown kernel switch %s. Ignoring.", key); return 0; } @@ -693,10 +686,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 @@ -704,10 +695,10 @@ static int add_root_mount(void) { return add_mount( "root", - "/dev/disk/by-id/gpt-auto-root", + "/dev/gpt-auto-root", in_initrd() ? "/sysroot" : "/", NULL, - arg_root_rw ? "rw" : "ro", + arg_root_rw, "Root Partition", in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET); #else @@ -720,10 +711,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; } @@ -753,8 +743,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.");