diff options
Diffstat (limited to 'src/gpt-auto-generator/gpt-auto-generator.c')
-rw-r--r-- | src/gpt-auto-generator/gpt-auto-generator.c | 172 |
1 files changed, 97 insertions, 75 deletions
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index f72a55c20a..d9e29c47f3 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -5,13 +5,14 @@ #include <sys/statfs.h> #include <unistd.h> -#include "libudev.h" +#include "sd-device.h" #include "sd-id128.h" #include "alloc-util.h" #include "blkid-util.h" #include "blockdev-util.h" #include "btrfs-util.h" +#include "device-util.h" #include "dirent-util.h" #include "dissect-image.h" #include "efivars.h" @@ -22,7 +23,7 @@ #include "gpt.h" #include "missing.h" #include "mkdir.h" -#include "mount-util.h" +#include "mountpoint-util.h" #include "parse-util.h" #include "path-util.h" #include "proc-cmdline.h" @@ -30,15 +31,15 @@ #include "specifier.h" #include "stat-util.h" #include "string-util.h" -#include "udev-util.h" +#include "strv.h" #include "unit-name.h" #include "util.h" #include "virt.h" -static const char *arg_dest = "/tmp"; +static const char *arg_dest = NULL; static bool arg_enabled = true; static bool arg_root_enabled = true; -static bool arg_root_rw = false; +static int arg_root_rw = -1; static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) { _cleanup_free_ char *e = NULL, *n = NULL, *d = NULL, *id_escaped = NULL, *what_escaped = NULL; @@ -445,64 +446,96 @@ static int add_esp(DissectedPartition *p) { } #endif +static int add_root_rw(DissectedPartition *p) { + const char *path; + int r; + + assert(p); + + if (in_initrd()) { + log_debug("In initrd, not generating drop-in for systemd-remount-fs.service."); + return 0; + } + + if (arg_root_rw >= 0) { + log_debug("Parameter ro/rw specified on kernel command line, not generating drop-in for systemd-remount-fs.service."); + return 0; + } + + if (!p->rw) { + log_debug("Root partition marked read-only in GPT partition table, not generating drop-in for systemd-remount-fs.service."); + return 0; + } + + path = strjoina(arg_dest, "/systemd-remount-fs.service.d/50-remount-rw.conf"); + (void) mkdir_parents(path, 0755); + + r = write_string_file(path, + "# Automatically generated by systemd-gpt-generator\n\n" + "[Unit]\n" + "ConditionPathExists=\n\n" /* We need to turn off the ConditionPathExist= in the main unit file */ + "[Service]\n" + "Environment=SYSTEMD_REMOUNT_ROOT_RW=1\n", + WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_NOFOLLOW); + if (r < 0) + return log_error_errno(r, "Failed to write drop-in file %s: %m", path); + + return 0; +} + static int open_parent(dev_t devnum, int *ret) { - _cleanup_(udev_device_unrefp) struct udev_device *d = NULL; - _cleanup_(udev_unrefp) struct udev *udev = NULL; + _cleanup_(sd_device_unrefp) sd_device *d = NULL; const char *name, *devtype, *node; - struct udev_device *parent; + sd_device *parent; dev_t pn; - int fd; + int fd, r; assert(ret); - udev = udev_new(); - if (!udev) - return log_oom(); - - d = udev_device_new_from_devnum(udev, 'b', devnum); - if (!d) - return log_oom(); + r = sd_device_new_from_devnum(&d, 'b', devnum); + if (r < 0) + return log_debug_errno(r, "Failed to open device: %m"); - 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)); - goto not_found; + if (sd_device_get_devname(d, &name) < 0) { + r = sd_device_get_syspath(d, &name); + if (r < 0) { + log_device_debug_errno(d, r, "Device %u:%u does not have a name, ignoring: %m", major(devnum), minor(devnum)); + return 0; + } } - parent = udev_device_get_parent(d); - if (!parent) { - log_debug("%s: not a partitioned device, ignoring.", name); - goto not_found; + r = sd_device_get_parent(d, &parent); + if (r < 0) { + log_device_debug_errno(d, r, "Not a partitioned device, ignoring: %m"); + return 0; } /* Does it have a devtype? */ - devtype = udev_device_get_devtype(parent); - if (!devtype) { - log_debug("%s: parent doesn't have a device type, ignoring.", name); - goto not_found; + r = sd_device_get_devtype(parent, &devtype); + if (r < 0) { + log_device_debug_errno(parent, r, "Parent doesn't have a device type, ignoring: %m"); + return 0; } /* Is this a disk or a partition? We only care for disks... */ if (!streq(devtype, "disk")) { - log_debug("%s: parent isn't a raw disk, ignoring.", name); - goto not_found; + log_device_debug(parent, "Parent isn't a raw disk, ignoring."); + return 0; } /* Does it have a device node? */ - node = udev_device_get_devnode(parent); - if (!node) { - log_debug("%s: parent device does not have device node, ignoring.", name); - goto not_found; + r = sd_device_get_devname(parent, &node); + if (r < 0) { + log_device_debug_errno(parent, r, "Parent device does not have device node, ignoring: %m"); + return 0; } - log_debug("%s: root device %s.", name, node); + log_device_debug(d, "Root device %s.", node); - pn = udev_device_get_devnum(parent); - if (major(pn) == 0) { - log_debug("%s: parent device is not a proper block device, ignoring.", name); - goto not_found; + r = sd_device_get_devnum(parent, &pn); + if (r < 0) { + log_device_debug_errno(parent, r, "Parent device is not a proper block device, ignoring: %m"); + return 0; } fd = open(node, O_RDONLY|O_CLOEXEC|O_NOCTTY); @@ -511,14 +544,9 @@ static int open_parent(dev_t devnum, int *ret) { *ret = fd; return 1; - -not_found: - *ret = -1; - return 0; } static int enumerate_partitions(dev_t devnum) { - _cleanup_close_ int fd = -1; _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; int r, k; @@ -527,7 +555,7 @@ static int enumerate_partitions(dev_t devnum) { if (r <= 0) return r; - r = dissect_image(fd, NULL, 0, DISSECT_IMAGE_GPT_ONLY, &m); + r = dissect_image(fd, NULL, 0, DISSECT_IMAGE_GPT_ONLY|DISSECT_IMAGE_NO_UDEV, &m); if (r == -ENOPKG) { log_debug_errno(r, "No suitable partition table found, ignoring."); return 0; @@ -559,6 +587,12 @@ static int enumerate_partitions(dev_t devnum) { r = k; } + if (m->partitions[PARTITION_ROOT].found) { + k = add_root_rw(m->partitions + PARTITION_ROOT); + if (k < 0) + r = k; + } + return r; } @@ -567,15 +601,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat assert(key); - if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto")) { + if (proc_cmdline_key_streq(key, "systemd.gpt_auto") || + proc_cmdline_key_streq(key, "rd.systemd.gpt_auto")) { r = value ? parse_boolean(value) : 1; if (r < 0) - log_warning("Failed to parse gpt-auto switch \"%s\". Ignoring.", value); + log_warning_errno(r, "Failed to parse gpt-auto switch \"%s\", ignoring: %m", value); else arg_enabled = r; - } else if (streq(key, "root")) { + } else if (proc_cmdline_key_streq(key, "root")) { if (proc_cmdline_value_missing(key, value)) return 0; @@ -585,7 +620,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat arg_root_enabled = streq(value, "gpt-auto"); - } else if (streq(key, "roothash")) { + } else if (proc_cmdline_key_streq(key, "roothash")) { if (proc_cmdline_value_missing(key, value)) return 0; @@ -594,9 +629,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat arg_root_enabled = false; - } else if (streq(key, "rw") && !value) + } else if (proc_cmdline_key_streq(key, "rw") && !value) arg_root_rw = true; - else if (streq(key, "ro") && !value) + else if (proc_cmdline_key_streq(key, "ro") && !value) arg_root_rw = false; return 0; @@ -648,7 +683,7 @@ static int add_root_mount(void) { "/dev/gpt-auto-root", in_initrd() ? "/sysroot" : "/", NULL, - arg_root_rw, + arg_root_rw > 0, NULL, "Root Partition", in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET); @@ -677,27 +712,14 @@ static int add_mounts(void) { return enumerate_partitions(devno); } -int main(int argc, char *argv[]) { +static int run(const char *dest, const char *dest_early, const char *dest_late) { int r, k; - if (argc > 1 && argc != 4) { - log_error("This program takes three or no arguments."); - return EXIT_FAILURE; - } - - if (argc > 1) - arg_dest = argv[3]; - - log_set_prohibit_ipc(true); - log_set_target(LOG_TARGET_AUTO); - log_parse_environment(); - log_open(); - - umask(0022); + assert_se(arg_dest = dest_late); if (detect_container() > 0) { log_debug("In a container, exiting."); - return EXIT_SUCCESS; + return 0; } r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0); @@ -706,19 +728,19 @@ int main(int argc, char *argv[]) { if (!arg_enabled) { log_debug("Disabled, exiting."); - return EXIT_SUCCESS; + return 0; } if (arg_root_enabled) r = add_root_mount(); - else - r = 0; if (!in_initrd()) { k = add_mounts(); - if (k < 0) + if (r >= 0) r = k; } - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + return r; } + +DEFINE_MAIN_GENERATOR_FUNCTION(run); |