chiark / gitweb /
Remove src/getty-generator
[elogind.git] / src / gpt-auto-generator / gpt-auto-generator.c
index 25d868aa877c80a951f3c158ce767faf07a53c40..99dc50fe3c3aa3cfe6159a9f25d8755cd594f0b2 100644 (file)
 
 #include <unistd.h>
 #include <stdlib.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
 #include <sys/statfs.h>
 #include <blkid/blkid.h>
 
-#ifdef HAVE_LINUX_BTRFS_H
-#include <linux/btrfs.h>
-#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.");