1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-23 21:35:11 +03:00

repart: allow reading from char device for CopyBlocks=

Sometimes it is useful to allow initializing a partition with randomized
data, hence allow reading from a char device as source for CopyBlocks=
This commit is contained in:
Lennart Poettering 2024-05-24 13:57:56 +02:00
parent ad25ede488
commit 468d09c319
2 changed files with 24 additions and 13 deletions

View File

@ -362,12 +362,14 @@
<varlistentry> <varlistentry>
<term><varname>CopyBlocks=</varname></term> <term><varname>CopyBlocks=</varname></term>
<listitem><para>Takes a path to a regular file, block device node or directory, or the special value <listitem><para>Takes a path to a regular file, block device node, char device node or directory, or
<literal>auto</literal>. If specified and the partition is newly created, the data from the specified the special value <literal>auto</literal>. If specified and the partition is newly created, the data
path is written to the newly created partition, on the block level. If a directory is specified, the from the specified path is written to the newly created partition, on the block level. If a directory
backing block device of the file system the directory is on is determined, and the data read directly is specified, the backing block device of the file system the directory is on is determined, and the
from that. This option is useful to efficiently replicate existing file systems onto new partitions data read directly from that. This option is useful to efficiently replicate existing file systems
on the block level — for example to build a simple OS installer or an OS image builder.</para> onto new partitions on the block level — for example to build a simple OS installer or an OS image
builder. Specify <filename>/dev/urandom</filename> as value to initialize a partition with random
data.</para>
<para>If the special value <literal>auto</literal> is specified, the source to copy from is <para>If the special value <literal>auto</literal> is specified, the source to copy from is
automatically picked up from the running system (or the image specified with automatically picked up from the running system (or the image specified with

View File

@ -4522,8 +4522,13 @@ static int context_copy_blocks(Context *context) {
continue; continue;
assert(p->new_size != UINT64_MAX); assert(p->new_size != UINT64_MAX);
assert(p->copy_blocks_size != UINT64_MAX);
assert(p->new_size >= p->copy_blocks_size + (p->encrypt != ENCRYPT_OFF ? LUKS2_METADATA_KEEP_FREE : 0)); size_t extra = p->encrypt != ENCRYPT_OFF ? LUKS2_METADATA_KEEP_FREE : 0;
if (p->copy_blocks_size == UINT64_MAX)
p->copy_blocks_size = LESS_BY(p->new_size, extra);
assert(p->new_size >= p->copy_blocks_size + extra);
usec_t start_timestamp = now(CLOCK_MONOTONIC); usec_t start_timestamp = now(CLOCK_MONOTONIC);
@ -6350,13 +6355,17 @@ static int context_open_copy_block_paths(
r = blockdev_get_device_size(source_fd, &size); r = blockdev_get_device_size(source_fd, &size);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to determine size of block device to copy from: %m"); return log_error_errno(r, "Failed to determine size of block device to copy from: %m");
} else } else if (S_ISCHR(st.st_mode))
size = UINT64_MAX;
else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Specified path to copy blocks from '%s' is not a regular file, block device or directory, refusing.", opened); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Specified path to copy blocks from '%s' is not a regular file, block device or directory, refusing.", opened);
if (size <= 0) if (size != UINT64_MAX) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File to copy bytes from '%s' has zero size, refusing.", opened); if (size <= 0)
if (size % 512 != 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File to copy bytes from '%s' has zero size, refusing.", opened);
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File to copy bytes from '%s' has size that is not multiple of 512, refusing.", opened); if (size % 512 != 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File to copy bytes from '%s' has size that is not multiple of 512, refusing.", opened);
}
p->copy_blocks_fd = TAKE_FD(source_fd); p->copy_blocks_fd = TAKE_FD(source_fd);
p->copy_blocks_size = size; p->copy_blocks_size = size;