mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
Merge pull request #28766 from DaanDeMeyer/repart-copy-from
repart: Allow specifying --copy-from more than once
This commit is contained in:
commit
9a441937e1
@ -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" />
|
||||
|
@ -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;
|
||||
|
||||
@ -1814,7 +1814,7 @@ static int find_verity_sibling(Context *context, Partition *p, VerityMode mode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int context_open_and_lock_backing_fd(const char *node, int *backing_fd) {
|
||||
static int context_open_and_lock_backing_fd(const char *node, int operation, int *backing_fd) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
assert(node);
|
||||
@ -1828,7 +1828,7 @@ static int context_open_and_lock_backing_fd(const char *node, int *backing_fd) {
|
||||
return log_error_errno(errno, "Failed to open device '%s': %m", node);
|
||||
|
||||
/* Tell udev not to interfere while we are processing the device */
|
||||
if (flock(fd, arg_dry_run ? LOCK_SH : LOCK_EX) < 0)
|
||||
if (flock(fd, operation) < 0)
|
||||
return log_error_errno(errno, "Failed to lock device '%s': %m", node);
|
||||
|
||||
log_debug("Device %s opened and locked.", node);
|
||||
@ -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, &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);
|
||||
@ -2223,7 +2236,8 @@ static int context_load_partition_table(Context *context) {
|
||||
else {
|
||||
uint32_t ssz;
|
||||
|
||||
r = context_open_and_lock_backing_fd(context->node, &context->backing_fd);
|
||||
r = context_open_and_lock_backing_fd(context->node, arg_dry_run ? LOCK_SH : LOCK_EX,
|
||||
&context->backing_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2270,7 +2284,9 @@ static int context_load_partition_table(Context *context) {
|
||||
|
||||
if (context->backing_fd < 0) {
|
||||
/* If we have no fd referencing the device yet, make a copy of the fd now, so that we have one */
|
||||
r = context_open_and_lock_backing_fd(FORMAT_PROC_FD_PATH(fdisk_get_devfd(c)), &context->backing_fd);
|
||||
r = context_open_and_lock_backing_fd(FORMAT_PROC_FD_PATH(fdisk_get_devfd(c)),
|
||||
arg_dry_run ? LOCK_SH : LOCK_EX,
|
||||
&context->backing_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -6192,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(),
|
||||
@ -6595,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;
|
||||
|
@ -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" \
|
||||
|
Loading…
x
Reference in New Issue
Block a user