Skip to content

Commit

Permalink
repart: add 'fsverity' flag for CopyFiles= lines
Browse files Browse the repository at this point in the history
We currently pass the CopyFlags that we use to populate the temporary
directory in the form of a constant at each of the copy_tree_at() call
sites.  De-duplicate that and move it into the `CopyFilesLine` struct,
initializing it from the parser.

Add our first non-constant flag: `fsverity=`.  This can be set to `off`
(the default) or `copy`, in which case we copy the fs-verity state from
the source files.

This arrangement is amenable to the introduction of more flags to
`CopyFiles=` lines, if we want to add them in the future.

Update the `repart.d(5)` manpage.

Closes systemd#35352

Signed-off-by: Allison Karlitskaya <allison.karlitskaya@redhat.com>
  • Loading branch information
allisonkarlitskaya committed Dec 2, 2024
1 parent 2c76598 commit 0ace782
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 17 deletions.
46 changes: 34 additions & 12 deletions man/repart.d.xml
Original file line number Diff line number Diff line change
Expand Up @@ -426,18 +426,40 @@
<varlistentry>
<term><varname>CopyFiles=</varname></term>

<listitem><para>Takes a pair of colon separated absolute file system paths. The first path refers to
a source file or directory on the host, the second path refers to a target in the file system of the
newly created partition and formatted file system. This setting may be used to copy files or
directories from the host into the file system that is created due to the <varname>Format=</varname>
option. If <varname>CopyFiles=</varname> is used without <varname>Format=</varname> specified
explicitly, <literal>Format=</literal> with a suitable default is implied (currently
<literal>vfat</literal> for <literal>ESP</literal> and <literal>XBOOTLDR</literal> partitions, and
<literal>ext4</literal> otherwise, but this may change in the future). This option may be used
multiple times to copy multiple files or directories from host into the newly formatted file system.
The colon and second path may be omitted in which case the source path is also used as the target
path (relative to the root of the newly created file system). If the source path refers to a
directory it is copied recursively.</para>
<listitem><para>Takes a colon-separated triplet in the form
<literal><varname>source</varname>[:<varname>target</varname>[:<varname>options</varname>]]</literal>.
<varname>source</varname> is an absolute path which refers to a source file or directory on the host.
<varname>target</varname> is an absolute path in the file system of the newly created partition and
formatted file system. <varname>options</varname> is a comma-separated list of options where each
option is in the form <literal><varname>key</varname>[=<varname>value</varname>]</literal>.</para>

<para>This setting may be used to copy files or directories from the host into the file system that
is created due to the <varname>Format=</varname> option. If <varname>CopyFiles=</varname> is used
without <varname>Format=</varname> specified explicitly, <literal>Format=</literal> with a suitable
default is implied (currently <literal>vfat</literal> for <literal>ESP</literal> and
<literal>XBOOTLDR</literal> partitions, and <literal>ext4</literal> otherwise, but this may change in
the future). This option may be used multiple times to copy multiple files or directories from host
into the newly formatted file system.</para>

<para>The <varname>target</varname> path may be omitted in which case the <varname>source</varname>
path is also used as the target path (relative to the root of the newly created file system). If
the source path refers to a directory it is copied recursively.</para>

<para>The <varname>options</varname> may contain the following values:</para>

<variablelist>
<varlistentry>
<term><varname>fsverity=</varname></term>
<listitem><para>May be set to the value <literal>off</literal> (the default if the option is not
present) or <literal>copy</literal>. If set to <literal>off</literal> then no files copied into
the filesystem from this source will have fs-verity enabled. If set to <literal>copy</literal>
then the fs-verity information for each file will be copied from the corresponding source
file.</para>

<xi:include href="version-info.xml" xpointer="v258"/></listitem>

</varlistentry>
</variablelist>

<para>This option has no effect if the partition already exists: it cannot be used to copy additional
files into an existing partition, it may only be used to populate a file system created anew.</para>
Expand Down
40 changes: 35 additions & 5 deletions src/repart/repart.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ static PartitionEncryptedVolume* partition_encrypted_volume_free(PartitionEncryp
typedef struct CopyFilesLine {
char *source;
char *target;
CopyFlags flags;
} CopyFilesLine;

static void copy_files_line_free_many(CopyFilesLine *f, size_t n) {
Expand Down Expand Up @@ -398,6 +399,7 @@ typedef struct Partition {

CopyFilesLine *copy_files;
size_t n_copy_files;
bool need_fsverity;

uint64_t gpt_flags;
int no_auto;
Expand Down Expand Up @@ -1769,9 +1771,36 @@ static int config_parse_copy_files(
else
target = buffer;

r = extract_first_word(&p, &options, ":", EXTRACT_CUNESCAPE|EXTRACT_DONT_COALESCE_SEPARATORS);
if (!isempty(p))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue);

CopyFlags flags = COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE|COPY_RESTORE_DIRECTORY_TIMESTAMPS;
for (const char *opts = options;;) {
_cleanup_free_ char *word = NULL;
char *val;

r = extract_first_word(&opts, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CopyFile options: %s", options);
if (r == 0)
break;

if (isempty(word))
continue;

if ((val = startswith(word, "fsverity="))) {
if (!STR_IN_SET(val, "off", "copy"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "fsverity= expects either 'off' or 'copy'");

if (strcmp(val, "off") != 0) {
partition->need_fsverity = true;
flags |= COPY_FS_VERITY;
}
} else
log_syntax(unit, LOG_WARNING, filename, line, r, "Encountered unknown option '%s', ignoring.", word);
}

r = specifier_printf(source, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_source);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
Expand Down Expand Up @@ -1800,6 +1829,7 @@ static int config_parse_copy_files(
partition->copy_files[partition->n_copy_files++] = (CopyFilesLine) {
.source = TAKE_PTR(resolved_source),
.target = TAKE_PTR(resolved_target),
.flags = flags,
};

return 0;
Expand Down Expand Up @@ -5677,14 +5707,14 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
sfd, ".",
pfd, fn,
UID_INVALID, GID_INVALID,
COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE|COPY_RESTORE_DIRECTORY_TIMESTAMPS,
line->flags,
denylist, subvolumes_by_source_inode);
} else
r = copy_tree_at(
sfd, ".",
tfd, ".",
UID_INVALID, GID_INVALID,
COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE|COPY_RESTORE_DIRECTORY_TIMESTAMPS,
line->flags,
denylist, subvolumes_by_source_inode);
if (r < 0)
return log_error_errno(r, "Failed to copy '%s%s' to '%s%s': %m",
Expand Down Expand Up @@ -6027,7 +6057,7 @@ static int context_mkfs(Context *context) {
return r;

r = make_filesystem(partition_target_path(t), p->format, strempty(p->new_label), root,
p->fs_uuid, arg_discard, /* fsverity = */ false, /* quiet = */ false,
p->fs_uuid, arg_discard, p->need_fsverity, /* quiet = */ false,
context->fs_sector_size, p->compression, p->compression_level,
extra_mkfs_options);
if (r < 0)
Expand Down Expand Up @@ -7592,7 +7622,7 @@ static int context_minimize(Context *context) {
root,
fs_uuid,
arg_discard,
/* fsverity = */ false,
p->need_fsverity,
/* quiet = */ false,
context->fs_sector_size,
p->compression,
Expand Down Expand Up @@ -7676,7 +7706,7 @@ static int context_minimize(Context *context) {
root,
p->fs_uuid,
arg_discard,
/* fsverity = */ false,
p->need_fsverity,
/* quiet = */ false,
context->fs_sector_size,
p->compression,
Expand Down

0 comments on commit 0ace782

Please sign in to comment.