]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/gpt-auto-generator/gpt-auto-generator.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / gpt-auto-generator / gpt-auto-generator.c
index a088df811fd49dda7362165a2eca6199cf196f67..09c0bcba2da207313dd8ebfd028e00727724dfc8 100644 (file)
@@ -12,6 +12,7 @@
 #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"
 #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,6 +446,43 @@ 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;
+        }
+
+        (void) generator_enable_remount_fs_service(arg_dest);
+
+        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"
+                              "[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_(sd_device_unrefp) sd_device *d = NULL;
         const char *name, *devtype, *node;
@@ -461,43 +499,43 @@ static int open_parent(dev_t devnum, int *ret) {
         if (sd_device_get_devname(d, &name) < 0) {
                 r = sd_device_get_syspath(d, &name);
                 if (r < 0) {
-                        log_debug_errno(r, "Device %u:%u does not have a name, ignoring: %m", major(devnum), minor(devnum));
-                        goto not_found;
+                        log_device_debug_errno(d, r, "Device %u:%u does not have a name, ignoring: %m", major(devnum), minor(devnum));
+                        return 0;
                 }
         }
 
         r = sd_device_get_parent(d, &parent);
         if (r < 0) {
-                log_debug_errno(r, "%s: not a partitioned device, ignoring: %m", name);
-                goto not_found;
+                log_device_debug_errno(d, r, "Not a partitioned device, ignoring: %m");
+                return 0;
         }
 
         /* Does it have a devtype? */
         r = sd_device_get_devtype(parent, &devtype);
         if (r < 0) {
-                log_debug_errno(r, "%s: parent doesn't have a device type, ignoring: %m", name);
-                goto not_found;
+                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? */
         r = sd_device_get_devname(parent, &node);
         if (r < 0) {
-                log_debug_errno(r, "%s: parent device does not have device node, ignoring: %m", name);
-                goto not_found;
+                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);
 
         r = sd_device_get_devnum(parent, &pn);
         if (r < 0) {
-                log_debug_errno(r, "%s: parent device is not a proper block device, ignoring: %m", name);
-                goto not_found;
+                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);
@@ -506,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;
@@ -522,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;
@@ -554,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;
 }
 
@@ -562,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;
@@ -580,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;
@@ -589,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;
@@ -638,12 +678,15 @@ static int add_root_mount(void) {
                         return r;
         }
 
+        /* Note that we do not need to enable systemd-remount-fs.service here. If
+         * /etc/fstab exists, systemd-fstab-generator will pull it in for us. */
+
         return add_mount(
                         "root",
                         "/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);
@@ -672,27 +715,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);
@@ -701,19 +731,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);