From: Daan De Meyer Date: Thu, 10 Aug 2023 12:41:31 +0000 (+0200) Subject: repart: Allow specifying --copy-from more than once X-Git-Tag: v255-rc1~749^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F28766%2Fhead;p=thirdparty%2Fsystemd.git repart: Allow specifying --copy-from more than once Definitions will be synthesized from each of the given images. --- diff --git a/man/systemd-repart.xml b/man/systemd-repart.xml index 346cc88441b..7ebac168b4d 100644 --- a/man/systemd-repart.xml +++ b/man/systemd-repart.xml @@ -444,12 +444,13 @@ IMAGE Instructs systemd-repart 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. + 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. diff --git a/src/partition/repart.c b/src/partition/repart.c index d5a64bfa12b..88669db5865 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -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; diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 118d797f2ba..249c1b04bb4 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -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" \