summaryrefslogtreecommitdiff
path: root/src/gpt-auto-generator/gpt-auto-generator.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpt-auto-generator/gpt-auto-generator.c')
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c172
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);