]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: Allow specifying --copy-from more than once 28766/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 10 Aug 2023 12:41:31 +0000 (14:41 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 11 Aug 2023 09:05:31 +0000 (11:05 +0200)
Definitions will be synthesized from each of the given images.

man/systemd-repart.xml
src/partition/repart.c
test/units/testsuite-58.sh

index 346cc88441bd2d6086e3ddfc479f25dfbf4da3df..7ebac168b4d2dabfd75db1215d1fda8045088806 100644 (file)
         <term><option>--copy-from=</option><arg>IMAGE</arg></term>
 
         <listitem><para>Instructs <command>systemd-repart</command> to synthesize partition definitions from
-        the partition table in the given image. The generated definitions will copy the partitions into the
-        destination partition table. The copied partitions will have the same size, metadata and contents but
-        might have a different partition number and might be located at a different offset in the destination
-        partition table. These definitions can be combined with partition definitions read from regular
-        partition definition files. The synthesized definitions take precedence over the definitions read
-        from partition definition files.</para></listitem>
+        the partition table in the given image. This option can be specified multiple times to synthesize
+        definitions from each of the given images. The generated definitions will copy the partitions into
+        the destination partition table. The copied partitions will have the same size, metadata and contents
+        but might have a different partition number and might be located at a different offset in the
+        destination partition table. These definitions can be combined with partition definitions read from
+        regular partition definition files. The synthesized definitions take precedence over the definitions
+        read from partition definition files.</para></listitem>
       </varlistentry>
 
       <xi:include href="standard-options.xml" xpointer="help" />
index d5a64bfa12b847309e131f242b62709b3cbcc2a1..88669db5865c2d6e14cce3acfd3e1281c938e47f 100644 (file)
@@ -156,7 +156,7 @@ static uint64_t arg_sector_size = 0;
 static ImagePolicy *arg_image_policy = NULL;
 static Architecture arg_architecture = _ARCHITECTURE_INVALID;
 static int arg_offline = -1;
-static char *arg_copy_from = NULL;
+static char **arg_copy_from = NULL;
 
 STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
@@ -169,7 +169,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_tpm2_hash_pcr_values, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_filter_partitions, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
-STATIC_DESTRUCTOR_REGISTER(arg_copy_from, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_copy_from, strv_freep);
 
 typedef struct FreeArea FreeArea;
 
@@ -1905,7 +1905,7 @@ static int determine_current_padding(
         return 0;
 }
 
-static int context_copy_from(Context *context) {
+static int context_copy_from_one(Context *context, const char *src) {
         _cleanup_close_ int fd = -EBADF;
         _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
         _cleanup_(fdisk_unref_tablep) struct fdisk_table *t = NULL;
@@ -1914,16 +1914,15 @@ static int context_copy_from(Context *context) {
         size_t n_partitions;
         int r;
 
-        if (!arg_copy_from)
-                return 0;
+        assert(src);
 
-        r = context_open_and_lock_backing_fd(arg_copy_from, LOCK_SH, &fd);
+        r = context_open_and_lock_backing_fd(src, LOCK_SH, &fd);
         if (r < 0)
                 return r;
 
         r = fd_verify_regular(fd);
         if (r < 0)
-                return log_error_errno(r, "%s is not a file: %m", arg_copy_from);
+                return log_error_errno(r, "%s is not a file: %m", src);
 
         r = fdisk_new_context_fd(fd, /* read_only = */ true, /* sector_size = */ UINT32_MAX, &c);
         if (r < 0)
@@ -1937,7 +1936,7 @@ static int context_copy_from(Context *context) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Sector size %lu is not a power of two larger than 512? Refusing.", secsz);
 
         if (!fdisk_is_labeltype(c, FDISK_DISKLABEL_GPT))
-                return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON), "Cannot copy from disk %s with no GPT disk label.", arg_copy_from);
+                return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON), "Cannot copy from disk %s with no GPT disk label.", src);
 
         r = fdisk_get_partitions(c, &t);
         if (r < 0)
@@ -2003,7 +2002,7 @@ static int context_copy_from(Context *context) {
                 np->size_min = np->size_max = sz;
                 np->new_label = TAKE_PTR(label_copy);
 
-                np->definition_path = strdup(arg_copy_from);
+                np->definition_path = strdup(src);
                 if (!np->definition_path)
                         return log_oom();
 
@@ -2013,13 +2012,13 @@ static int context_copy_from(Context *context) {
 
                 np->padding_min = np->padding_max = padding;
 
-                np->copy_blocks_path = strdup(arg_copy_from);
+                np->copy_blocks_path = strdup(src);
                 if (!np->copy_blocks_path)
                         return log_oom();
 
                 np->copy_blocks_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
                 if (np->copy_blocks_fd < 0)
-                        return log_error_errno(r, "Failed to duplicate file descriptor of %s: %m", arg_copy_from);
+                        return log_error_errno(r, "Failed to duplicate file descriptor of %s: %m", src);
 
                 np->copy_blocks_offset = start;
                 np->copy_blocks_size = sz;
@@ -2036,6 +2035,20 @@ static int context_copy_from(Context *context) {
         return 0;
 }
 
+static int context_copy_from(Context *context) {
+        int r;
+
+        assert(context);
+
+        STRV_FOREACH(src, arg_copy_from) {
+                r = context_copy_from_one(context, *src);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
 static int context_read_definitions(Context *context) {
         _cleanup_strv_free_ char **files = NULL;
         Partition *last = LIST_FIND_TAIL(partitions, context->partitions);
@@ -6195,7 +6208,7 @@ static int help(void) {
                "     --sector-size=SIZE   Set the logical sector size for the image\n"
                "     --architecture=ARCH  Set the generic architecture for the image\n"
                "     --offline=BOOL       Whether to build the image offline\n"
-               "     --copy-from=IMAGE    Copy partitions from the given image\n"
+               "     --copy-from=IMAGE    Copy partitions from the given image(s)\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                ansi_highlight(),
@@ -6598,11 +6611,18 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
-                case ARG_COPY_FROM:
-                        r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_copy_from);
+                case ARG_COPY_FROM: {
+                        _cleanup_free_ char *p = NULL;
+
+                        r = parse_path_argument(optarg, /* suppress_root= */ false, &p);
                         if (r < 0)
                                 return r;
+
+                        if (strv_consume(&arg_copy_from, TAKE_PTR(p)) < 0)
+                                return log_oom();
+
                         break;
+                }
 
                 case '?':
                         return -EINVAL;
index 118d797f2ba8bf73a75b3c0aa2fe2eeb31c367fe..249c1b04bb4c501e57d312500415a37c201a1450 100755 (executable)
@@ -160,12 +160,24 @@ last-lba: 2097118
 $imgs/zzz1 : start=        2048, size=     1775576, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\"
 $imgs/zzz2 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\""
 
+    systemd-repart --offline="$OFFLINE" \
+                    --definitions="$defs" \
+                   --empty=create \
+                   --size=50M \
+                   --seed="$seed" \
+                   --include-partitions=root,home \
+                   "$imgs/qqq"
+
+    sfdisk -d "$imgs/qqq" | grep -v -e 'sector-size' -e '^$'
+
     systemd-repart --offline="$OFFLINE" \
                    --empty=create \
                    --size=1G \
                    --dry-run=no \
                    --seed="$seed" \
-                   --copy-from="$imgs/zzz" \
+                   --definitions "" \
+                   --copy-from="$imgs/qqq" \
+                   --copy-from="$imgs/qqq" \
                    "$imgs/copy"
 
     output=$(sfdisk -d "$imgs/copy" | grep -v -e 'sector-size' -e '^$')
@@ -176,10 +188,14 @@ device: $imgs/copy
 unit: sectors
 first-lba: 2048
 last-lba: 2097118
-$imgs/copy1 : start=        2048, size=     1775576, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\"
-$imgs/copy2 : start=     1777624, size=      131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\""
-
-    rm "$imgs/copy" # Save disk space
+$imgs/copy1 : start=        2048, size=       33432, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\"
+$imgs/copy2 : start=       35480, size=       33440, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=60F33797-1D71-4DCB-AA6F-20564F036CD0, name=\"root-x86-64\", attrs=\"GUID:59\"
+$imgs/copy3 : start=       68920, size=       33440, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=73A4CCD2-EAF5-44DA-A366-F99188210FDC, name=\"root-x86-64-2\", attrs=\"GUID:59\"
+$imgs/copy4 : start=      102360, size=       33432, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\"
+$imgs/copy5 : start=      135792, size=       33440, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=60F33797-1D71-4DCB-AA6F-20564F036CD0, name=\"root-x86-64\", attrs=\"GUID:59\"
+$imgs/copy6 : start=      169232, size=       33440, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=73A4CCD2-EAF5-44DA-A366-F99188210FDC, name=\"root-x86-64-2\", attrs=\"GUID:59\""
+
+    rm "$imgs/qqq" "$imgs/copy" # Save disk space
 
     systemd-repart --offline="$OFFLINE" \
                    --definitions="$defs" \