]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/gpt-auto-generator/gpt-auto-generator.c
service: add new RootImageOptions feature
[thirdparty/systemd.git] / src / gpt-auto-generator / gpt-auto-generator.c
index 99b5da17f5a2c52efaf6b3518e9a1730bd4c1690..02d8837ca9b09b8119a5d2054a8881122257d8e0 100644 (file)
@@ -40,14 +40,14 @@ static bool arg_enabled = true;
 static bool arg_root_enabled = true;
 static int arg_root_rw = -1;
 
-static int open_parent_devno(dev_t devnum, int *ret) {
+static int open_parent_block_device(dev_t devnum, int *ret_fd) {
         _cleanup_(sd_device_unrefp) sd_device *d = NULL;
         const char *name, *devtype, *node;
         sd_device *parent;
         dev_t pn;
         int fd, r;
 
-        assert(ret);
+        assert(ret_fd);
 
         r = sd_device_new_from_devnum(&d, 'b', devnum);
         if (r < 0)
@@ -56,7 +56,8 @@ static int open_parent_devno(dev_t devnum, int *ret) {
         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));
+                        log_device_debug_errno(d, r, "Device %u:%u does not have a name, ignoring: %m",
+                                               major(devnum), minor(devnum));
                         return 0;
                 }
         }
@@ -99,14 +100,13 @@ static int open_parent_devno(dev_t devnum, int *ret) {
         if (fd < 0)
                 return log_error_errno(errno, "Failed to open %s: %m", node);
 
-        *ret = fd;
+        *ret_fd = fd;
         return 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;
+        _cleanup_free_ char *e = NULL, *n = NULL, *d = NULL;
         _cleanup_fclose_ FILE *f = NULL;
-        const char *p;
         int r;
 
         assert(id);
@@ -124,44 +124,28 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
-        id_escaped = specifier_escape(id);
-        if (!id_escaped)
-                return log_oom();
-
-        what_escaped = specifier_escape(what);
-        if (!what_escaped)
-                return log_oom();
+        r = generator_open_unit_file(arg_dest, NULL, n, &f);
+        if (r < 0)
+                return r;
 
-        p = prefix_roota(arg_dest, n);
-        f = fopen(p, "wxe");
-        if (!f)
-                return log_error_errno(errno, "Failed to create unit file %s: %m", p);
+        r = generator_write_cryptsetup_unit_section(f, NULL);
+        if (r < 0)
+                return r;
 
         fprintf(f,
-                "# Automatically generated by systemd-gpt-auto-generator\n\n"
-                "[Unit]\n"
-                "Description=Cryptography Setup for %%I\n"
-                "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
-                "DefaultDependencies=no\n"
-                "Conflicts=umount.target\n"
-                "BindsTo=dev-mapper-%%i.device %s\n"
                 "Before=umount.target cryptsetup.target\n"
-                "After=%s\n"
-                "IgnoreOnIsolate=true\n"
-                "[Service]\n"
-                "Type=oneshot\n"
-                "RemainAfterExit=yes\n"
-                "TimeoutSec=0\n" /* the binary handles timeouts anyway */
-                "KeyringMode=shared\n" /* make sure we can share cached keys among instances */
-                "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n"
-                "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
-                d, d,
-                id_escaped, what_escaped, rw ? "" : "read-only",
-                id_escaped);
+                "Conflicts=umount.target\n"
+                "BindsTo=%s\n"
+                "After=%s\n",
+                d, d);
+
+        r = generator_write_cryptsetup_service_section(f, id, what, NULL, rw ? NULL : "read-only");
+        if (r < 0)
+                return r;
 
         r = fflush_and_check(f);
         if (r < 0)
-                return log_error_errno(r, "Failed to write file %s: %m", p);
+                return log_error_errno(r, "Failed to write file %s: %m", n);
 
         r = generator_add_symlink(arg_dest, d, "wants", n);
         if (r < 0)
@@ -226,7 +210,6 @@ static int add_mount(
         log_debug("Adding %s: %s fstype=%s", where, what, fstype ?: "(any)");
 
         if (streq_ptr(fstype, "crypto_LUKS")) {
-
                 r = add_cryptsetup(id, what, rw, true, &crypto_what);
                 if (r < 0)
                         return r;
@@ -261,6 +244,10 @@ static int add_mount(
         if (r < 0)
                 return r;
 
+        r = generator_write_blockdev_dependency(f, what);
+        if (r < 0)
+                return r;
+
         fprintf(f,
                 "\n"
                 "[Mount]\n"
@@ -369,7 +356,14 @@ static int add_swap(const char *path) {
                 "# Automatically generated by systemd-gpt-auto-generator\n\n"
                 "[Unit]\n"
                 "Description=Swap Partition\n"
-                "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
+                "Documentation=man:systemd-gpt-auto-generator(8)\n");
+
+        r = generator_write_blockdev_dependency(f, path);
+        if (r < 0)
+                return r;
+
+        fprintf(f,
+                "\n"
                 "[Swap]\n"
                 "What=%s\n",
                 path);
@@ -442,6 +436,19 @@ static int add_automount(
         return generator_add_symlink(arg_dest, SPECIAL_LOCAL_FS_TARGET, "wants", unit);
 }
 
+static const char *esp_or_xbootldr_options(const DissectedPartition *p) {
+        assert(p);
+
+        /* if we probed vfat or have no idea about the file system then assume these file systems are vfat
+         * and thus understand "umask=0077". If we detected something else then don't specify any options and
+         * use kernel defaults. */
+
+        if (!p->fstype || streq(p->fstype, "vfat"))
+                return "umask=0077";
+
+        return NULL;
+}
+
 static int add_xbootldr(DissectedPartition *p) {
         int r;
 
@@ -471,7 +478,7 @@ static int add_xbootldr(DissectedPartition *p) {
                              "/boot",
                              p->fstype,
                              true,
-                             "umask=0077",
+                             esp_or_xbootldr_options(p),
                              "Boot Loader Partition",
                              120 * USEC_PER_SEC);
 }
@@ -545,7 +552,7 @@ static int add_esp(DissectedPartition *p, bool has_xbootldr) {
                              esp_path,
                              p->fstype,
                              true,
-                             "umask=0077",
+                             esp_or_xbootldr_options(p),
                              "EFI System Partition Automount",
                              120 * USEC_PER_SEC);
 }
@@ -612,7 +619,8 @@ static int add_root_mount(void) {
 
         r = efi_loader_get_device_part_uuid(NULL);
         if (r == -ENOENT) {
-                log_debug("EFI loader partition unknown, exiting.");
+                log_notice("EFI loader partition unknown, exiting.\n"
+                           "(The boot loader did not set EFI variable LoaderDevicePartUUID.)");
                 return 0;
         } else if (r < 0)
                 return log_error_errno(r, "Failed to read ESP partition UUID: %m");
@@ -653,11 +661,11 @@ static int enumerate_partitions(dev_t devnum) {
         _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
         int r, k;
 
-        r = open_parent_devno(devnum, &fd);
+        r = open_parent_block_device(devnum, &fd);
         if (r <= 0)
                 return r;
 
-        r = dissect_image(fd, NULL, 0, DISSECT_IMAGE_GPT_ONLY|DISSECT_IMAGE_NO_UDEV, &m);
+        r = dissect_image(fd, NULL, 0, NULL, NULL, DISSECT_IMAGE_GPT_ONLY|DISSECT_IMAGE_NO_UDEV, &m);
         if (r == -ENOPKG) {
                 log_debug_errno(r, "No suitable partition table found, ignoring.");
                 return 0;
@@ -695,6 +703,18 @@ static int enumerate_partitions(dev_t devnum) {
                         r = k;
         }
 
+        if (m->partitions[PARTITION_VAR].found) {
+                k = add_partition_mount(m->partitions + PARTITION_VAR, "var", "/var", "Variable Data Partition");
+                if (k < 0)
+                        r = k;
+        }
+
+        if (m->partitions[PARTITION_TMP].found) {
+                k = add_partition_mount(m->partitions + PARTITION_TMP, "var-tmp", "/var/tmp", "Temporary Data Partition");
+                if (k < 0)
+                        r = k;
+        }
+
         if (m->partitions[PARTITION_ROOT].found) {
                 k = add_root_rw(m->partitions + PARTITION_ROOT);
                 if (k < 0)