mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
repart: add new --copy-source= switch
This specifies a directory to which CopyFiles= is considered relative. If unset defaults to the --root=/--image= setting, or host / otherwise. This is very similar to --root= but is much more focussed: it is really and exclusively about CopyFiles= (and related settings such as ExcludeFiles=) and does not affect any of the settings, i.e. it doesn't affect CopyBlocks=, the machine ID/seed handling, or where definitions are read from. In fact, --root= and --copy-source= may be combined for example to use the machine ID and similar from one tree, but the copy the files from another.
This commit is contained in:
parent
248f0186c1
commit
607343a1ac
|
@ -468,10 +468,11 @@
|
||||||
<para>This option cannot be combined with <varname>CopyBlocks=</varname>.</para>
|
<para>This option cannot be combined with <varname>CopyBlocks=</varname>.</para>
|
||||||
|
|
||||||
<para>When
|
<para>When
|
||||||
<citerefentry><refentrytitle>systemd-repart</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd-repart</refentrytitle><manvolnum>8</manvolnum></citerefentry> is
|
||||||
is invoked with the <option>--image=</option> or <option>--root=</option> command line switches the
|
invoked with the <option>--copy-source=</option> command line switch the file paths are taken
|
||||||
source paths specified are taken relative to the specified root directory or disk image root.
|
relative to the specified directory. If <option>--copy-source=</option> is not used, but the
|
||||||
</para>
|
<option>--image=</option> or <option>--root=</option> switches are used, the source paths are taken
|
||||||
|
relative to the specified root directory or disk image root.</para>
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v247"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v247"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -276,6 +276,9 @@
|
||||||
so that the tool operates on the configuration and machine ID stored in the root file system later
|
so that the tool operates on the configuration and machine ID stored in the root file system later
|
||||||
transitioned into itself.</para>
|
transitioned into itself.</para>
|
||||||
|
|
||||||
|
<para>See <option>--copy-source=</option> for a more restricted option that only affects
|
||||||
|
<varname>CopyFiles=</varname>.</para>
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v245"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v245"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -500,6 +503,19 @@
|
||||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--copy-source=</option><replaceable>PATH</replaceable></term>
|
||||||
|
<term><option>-s</option> <replaceable>PATH</replaceable></term>
|
||||||
|
|
||||||
|
<listitem><para>Specifies a source directory all <varname>CopyFiles=</varname> source paths shall be
|
||||||
|
considered relative to. This is similar to <option>--root=</option>, but exclusively applies to the
|
||||||
|
<varname>CopyFiles=</varname> setting. If <option>--root=</option> and
|
||||||
|
<option>--copy-source=</option> are used in combination the former applies as usual, except for
|
||||||
|
<varname>CopyFiles=</varname> where the latter takes precedence.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<xi:include href="standard-options.xml" xpointer="help" />
|
<xi:include href="standard-options.xml" xpointer="help" />
|
||||||
<xi:include href="standard-options.xml" xpointer="version" />
|
<xi:include href="standard-options.xml" xpointer="version" />
|
||||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||||
|
|
|
@ -162,6 +162,7 @@ static ImagePolicy *arg_image_policy = NULL;
|
||||||
static Architecture arg_architecture = _ARCHITECTURE_INVALID;
|
static Architecture arg_architecture = _ARCHITECTURE_INVALID;
|
||||||
static int arg_offline = -1;
|
static int arg_offline = -1;
|
||||||
static char **arg_copy_from = NULL;
|
static char **arg_copy_from = NULL;
|
||||||
|
static char *arg_copy_source = NULL;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||||
|
@ -175,6 +176,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_filter_partitions, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_filter_partitions, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_copy_from, strv_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_copy_from, strv_freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_copy_source, freep);
|
||||||
|
|
||||||
typedef struct FreeArea FreeArea;
|
typedef struct FreeArea FreeArea;
|
||||||
|
|
||||||
|
@ -4274,11 +4276,11 @@ static int add_exclude_path(const char *path, Hashmap **denylist, DenyType type)
|
||||||
if (!st)
|
if (!st)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = chase_and_stat(path, arg_root, CHASE_PREFIX_ROOT, NULL, st);
|
r = chase_and_stat(path, arg_copy_source, CHASE_PREFIX_ROOT, NULL, st);
|
||||||
if (r == -ENOENT)
|
if (r == -ENOENT)
|
||||||
return 0;
|
return 0;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to stat source file '%s/%s': %m", strempty(arg_root), path);
|
return log_error_errno(r, "Failed to stat source file '%s/%s': %m", strempty(arg_copy_source), path);
|
||||||
|
|
||||||
r = hashmap_ensure_put(denylist, &inode_hash_ops, st, INT_TO_PTR(type));
|
r = hashmap_ensure_put(denylist, &inode_hash_ops, st, INT_TO_PTR(type));
|
||||||
if (r == -EEXIST)
|
if (r == -EEXIST)
|
||||||
|
@ -4402,11 +4404,11 @@ static int add_subvolume_path(const char *path, Set **subvolumes) {
|
||||||
if (!st)
|
if (!st)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = chase_and_stat(path, arg_root, CHASE_PREFIX_ROOT, NULL, st);
|
r = chase_and_stat(path, arg_copy_source, CHASE_PREFIX_ROOT, NULL, st);
|
||||||
if (r == -ENOENT)
|
if (r == -ENOENT)
|
||||||
return 0;
|
return 0;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to stat source file '%s/%s': %m", strempty(arg_root), path);
|
return log_error_errno(r, "Failed to stat source file '%s/%s': %m", strempty(arg_copy_source), path);
|
||||||
|
|
||||||
r = set_ensure_consume(subvolumes, &inode_hash_ops, TAKE_PTR(st));
|
r = set_ensure_consume(subvolumes, &inode_hash_ops, TAKE_PTR(st));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -4469,9 +4471,9 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
|
||||||
if (rfd < 0)
|
if (rfd < 0)
|
||||||
return rfd;
|
return rfd;
|
||||||
|
|
||||||
sfd = chase_and_open(*source, arg_root, CHASE_PREFIX_ROOT, O_PATH|O_DIRECTORY|O_CLOEXEC|O_NOCTTY, NULL);
|
sfd = chase_and_open(*source, arg_copy_source, CHASE_PREFIX_ROOT, O_PATH|O_DIRECTORY|O_CLOEXEC|O_NOCTTY, NULL);
|
||||||
if (sfd < 0)
|
if (sfd < 0)
|
||||||
return log_error_errno(sfd, "Failed to open source file '%s%s': %m", strempty(arg_root), *source);
|
return log_error_errno(sfd, "Failed to open source file '%s%s': %m", strempty(arg_copy_source), *source);
|
||||||
|
|
||||||
(void) copy_xattr(sfd, NULL, rfd, NULL, COPY_ALL_XATTRS);
|
(void) copy_xattr(sfd, NULL, rfd, NULL, COPY_ALL_XATTRS);
|
||||||
(void) copy_access(sfd, rfd);
|
(void) copy_access(sfd, rfd);
|
||||||
|
@ -4493,9 +4495,9 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
sfd = chase_and_open(*source, arg_root, CHASE_PREFIX_ROOT, O_CLOEXEC|O_NOCTTY, NULL);
|
sfd = chase_and_open(*source, arg_copy_source, CHASE_PREFIX_ROOT, O_CLOEXEC|O_NOCTTY, NULL);
|
||||||
if (sfd < 0)
|
if (sfd < 0)
|
||||||
return log_error_errno(sfd, "Failed to open source file '%s%s': %m", strempty(arg_root), *source);
|
return log_error_errno(sfd, "Failed to open source file '%s%s': %m", strempty(arg_copy_source), *source);
|
||||||
|
|
||||||
r = fd_verify_regular(sfd);
|
r = fd_verify_regular(sfd);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -4541,7 +4543,7 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
|
||||||
denylist, subvolumes_by_source_inode);
|
denylist, subvolumes_by_source_inode);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to copy '%s%s' to '%s%s': %m",
|
return log_error_errno(r, "Failed to copy '%s%s' to '%s%s': %m",
|
||||||
strempty(arg_root), *source, strempty(root), *target);
|
strempty(arg_copy_source), *source, strempty(root), *target);
|
||||||
} else {
|
} else {
|
||||||
_cleanup_free_ char *dn = NULL, *fn = NULL;
|
_cleanup_free_ char *dn = NULL, *fn = NULL;
|
||||||
|
|
||||||
|
@ -4572,7 +4574,7 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
|
||||||
|
|
||||||
r = copy_bytes(sfd, tfd, UINT64_MAX, COPY_REFLINK|COPY_HOLES|COPY_SIGINT|COPY_TRUNCATE);
|
r = copy_bytes(sfd, tfd, UINT64_MAX, COPY_REFLINK|COPY_HOLES|COPY_SIGINT|COPY_TRUNCATE);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", *source, strempty(arg_root), *target);
|
return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", *source, strempty(arg_copy_source), *target);
|
||||||
|
|
||||||
(void) copy_xattr(sfd, NULL, tfd, NULL, COPY_ALL_XATTRS);
|
(void) copy_xattr(sfd, NULL, tfd, NULL, COPY_ALL_XATTRS);
|
||||||
(void) copy_access(sfd, tfd);
|
(void) copy_access(sfd, tfd);
|
||||||
|
@ -6372,6 +6374,7 @@ static int help(void) {
|
||||||
" --sector-size=SIZE Set the logical sector size for the image\n"
|
" --sector-size=SIZE Set the logical sector size for the image\n"
|
||||||
" --architecture=ARCH Set the generic architecture for the image\n"
|
" --architecture=ARCH Set the generic architecture for the image\n"
|
||||||
" --offline=BOOL Whether to build the image offline\n"
|
" --offline=BOOL Whether to build the image offline\n"
|
||||||
|
" -s --copy-source=PATH Specify the primary source tree to copy files from\n"
|
||||||
" --copy-from=IMAGE Copy partitions from the given image(s)\n"
|
" --copy-from=IMAGE Copy partitions from the given image(s)\n"
|
||||||
"\nSee the %s for details.\n",
|
"\nSee the %s for details.\n",
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
|
@ -6417,6 +6420,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
ARG_ARCHITECTURE,
|
ARG_ARCHITECTURE,
|
||||||
ARG_OFFLINE,
|
ARG_OFFLINE,
|
||||||
ARG_COPY_FROM,
|
ARG_COPY_FROM,
|
||||||
|
ARG_COPY_SOURCE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
|
@ -6452,6 +6456,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
{ "architecture", required_argument, NULL, ARG_ARCHITECTURE },
|
{ "architecture", required_argument, NULL, ARG_ARCHITECTURE },
|
||||||
{ "offline", required_argument, NULL, ARG_OFFLINE },
|
{ "offline", required_argument, NULL, ARG_OFFLINE },
|
||||||
{ "copy-from", required_argument, NULL, ARG_COPY_FROM },
|
{ "copy-from", required_argument, NULL, ARG_COPY_FROM },
|
||||||
|
{ "copy-source", required_argument, NULL, 's' },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6460,7 +6465,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
while ((c = getopt_long(argc, argv, "hs:", options, NULL)) >= 0)
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
|
@ -6785,6 +6790,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_copy_source);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -7345,6 +7356,13 @@ static int run(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!arg_copy_source && arg_root) {
|
||||||
|
/* If no explicit copy source is specified, then use --root=/--image= */
|
||||||
|
arg_copy_source = strdup(arg_root);
|
||||||
|
if (!arg_copy_source)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
context = context_new(arg_seed);
|
context = context_new(arg_seed);
|
||||||
if (!context)
|
if (!context)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
Loading…
Reference in a new issue