repart: Allow specifying --copy-from more than once

Definitions will be synthesized from each of the given images.
This commit is contained in:
Daan De Meyer 2023-08-10 14:41:31 +02:00
parent 3cdcf4e204
commit e1536d1fb0
3 changed files with 61 additions and 24 deletions

View file

@ -444,12 +444,13 @@
<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" />

View 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;

View file

@ -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\""
$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/copy" # Save disk space
rm "$imgs/qqq" "$imgs/copy" # Save disk space
systemd-repart --offline="$OFFLINE" \
--definitions="$defs" \