Merge pull request #28621 from DaanDeMeyer/repart-fix

Revert https://github.com/systemd/systemd/pull/28556
This commit is contained in:
Daan De Meyer
2023-08-01 16:32:35 +02:00
committed by GitHub
5 changed files with 31 additions and 118 deletions

View File

@@ -373,7 +373,10 @@
data is never overwritten. Note that the data is copied in before the partition table is updated,
i.e. before the partition actually is persistently created. This provides robustness: it is
guaranteed that the partition either doesn't exist or exists fully populated; it is not possible that
the partition exists but is not or only partially populated.</para></listitem>
the partition exists but is not or only partially populated.</para>
<para>This option cannot be combined with <varname>Format=</varname> or
<varname>CopyFiles=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -392,7 +395,9 @@
<para>Similarly to the behaviour of <varname>CopyBlocks=</varname>, the file system is formatted
before the partition is created, ensuring that the partition only ever exists with a fully
initialized file system.</para></listitem>
initialized file system.</para>
<para>This option cannot be combined with <varname>CopyBlocks=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -434,10 +439,7 @@
<citerefentry project='man-pages'><refentrytitle>mkfs.xfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
due to limitations of its protofile format.</para>
<para>When this option is used in combination with <varname>CopyBlocks=</varname>,
<command>systemd-repart</command> will first try the <varname>CopyBlocks=</varname> logic and will
only fall back to the <varname>CopyFiles=</varname> logic if the <varname>CopyBlocks=</varname> logic
cannot be used.</para>
<para>This option cannot be combined with <varname>CopyBlocks=</varname>.</para>
<para>When
<citerefentry><refentrytitle>systemd-repart</refentrytitle><manvolnum>8</manvolnum></citerefentry>
@@ -567,15 +569,6 @@
into their original state by removing partitions and creating them anew. Defaults to off.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>OEM=</varname></term>
<listitem><para>Takes a boolean argument. If specified the partition is marked as an OEM partition.
When the <option>--oem</option> is used, only OEM partitions are written to the partition table.
Unless configured explicitly with <varname>OEM=</varname>, a partition is an OEM partition if
<varname>FactoryReset=no</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>Flags=</varname></term>

View File

@@ -440,14 +440,6 @@
due to missing permissions.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--oem=</option><arg>BOOL</arg></term>
<listitem><para>Instructs <command>systemd-repart</command> to only include OEM partitions into the
image. Takes a boolean and is off by default. OEM partitions can be configured using the
<varname>OEM=</varname> setting.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
<xi:include href="standard-options.xml" xpointer="no-pager" />

View File

@@ -24,7 +24,6 @@
#include "conf-files.h"
#include "conf-parser.h"
#include "constants.h"
#include "creds-util.h"
#include "cryptsetup-util.h"
#include "device-util.h"
#include "devnum-util.h"
@@ -154,7 +153,6 @@ 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 bool arg_oem = false;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
@@ -207,7 +205,6 @@ typedef struct Partition {
bool dropped;
bool factory_reset;
int oem;
int32_t priority;
uint32_t weight, padding_weight;
@@ -353,7 +350,6 @@ static Partition *partition_new(void) {
.no_auto = -1,
.read_only = -1,
.growfs = -1,
.oem = -1,
};
return p;
@@ -427,16 +423,9 @@ static void partition_foreignize(Partition *p) {
p->verity = VERITY_OFF;
}
static bool partition_is_oem(const Partition *p) {
return p->oem > 0 || (p->oem < 0 && !p->factory_reset);
}
static bool partition_exclude(const Partition *p) {
assert(p);
if (arg_oem && !partition_is_oem(p))
return true;
if (arg_filter_partitions_type == FILTER_PARTITIONS_NONE)
return false;
@@ -1642,7 +1631,6 @@ static int partition_read_definition(Partition *p, const char *path, const char
{ "Partition", "GrowFileSystem", config_parse_tristate, 0, &p->growfs },
{ "Partition", "SplitName", config_parse_string, 0, &p->split_name_format },
{ "Partition", "Minimize", config_parse_minimize, 0, &p->minimize },
{ "Partition", "OEM", config_parse_tristate, 0, &p->oem },
{}
};
int r;
@@ -1684,6 +1672,11 @@ static int partition_read_definition(Partition *p, const char *path, const char
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
"Type= not defined, refusing.");
if ((p->copy_blocks_path || p->copy_blocks_auto) &&
(p->format || !strv_isempty(p->copy_files) || !strv_isempty(p->make_directories)))
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
"Format=/CopyFiles=/MakeDirectories= and CopyBlocks= cannot be combined, refusing.");
if ((!strv_isempty(p->copy_files) || !strv_isempty(p->make_directories)) && streq_ptr(p->format, "swap"))
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
"Format=swap and CopyFiles= cannot be combined, refusing.");
@@ -5394,6 +5387,19 @@ static int resolve_copy_blocks_auto(
dev_t devno, found = 0;
int r;
/* Enforce some security restrictions: CopyBlocks=auto should not be an avenue to get outside of the
* --root=/--image= confinement. Specifically, refuse CopyBlocks= in combination with --root= at all,
* and restrict block device references in the --image= case to loopback block device we set up.
*
* restrict_devno contain the dev_t of the loop back device we operate on in case of --image=, and
* thus declares which device (and its partition subdevices) we shall limit access to. If
* restrict_devno is zero no device probing access shall be allowed at all (used for --root=) and if
* it is (dev_t) -1 then free access shall be allowed (if neither switch is used). */
if (restrict_devno == 0)
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
"Automatic discovery of backing block devices not permitted in --root= mode, refusing.");
/* Handles CopyBlocks=auto, and finds the right source partition to copy from. We look for matching
* partitions in the host, using the appropriate directory as key and ensuring that the partition
* type matches. */
@@ -5486,13 +5492,17 @@ static int resolve_copy_blocks_auto(
found = devno;
}
if (found == 0)
return log_error_errno(SYNTHETIC_ERRNO(ENXIO),
"Unable to automatically discover suitable partition to copy blocks from.");
if (ret_devno)
*ret_devno = found;
if (ret_uuid)
*ret_uuid = found_uuid;
return found != 0;
return 0;
}
static int context_open_copy_block_paths(
@@ -5534,35 +5544,9 @@ static int context_open_copy_block_paths(
} else if (p->copy_blocks_auto) {
dev_t devno = 0; /* Fake initialization to appease gcc. */
/* Enforce some security restrictions: CopyBlocks=auto should not be an avenue to get
* outside of the --root=/--image= confinement. Specifically, refuse CopyBlocks= in
* combination with --root= at all, and restrict block device references in the
* --image= case to loopback block device we set up.
*
* restrict_devno contain the dev_t of the loop back device we operate on in case of
* --image=, and thus declares which device (and its partition subdevices) we shall
* limit access to. If restrict_devno is zero no device probing access shall be
* allowed at all (used for --root=) and if it is (dev_t) -1 then free access shall
* be allowed (if neither switch is used). */
if (restrict_devno == 0) {
if (!p->format && strv_isempty(p->copy_files) && strv_isempty(p->make_directories))
return log_error_errno(SYNTHETIC_ERRNO(EPERM),
"Automatic discovery of backing block devices not permitted in --root= mode, refusing.");
continue;
}
r = resolve_copy_blocks_auto(p->type, p->copy_blocks_root, restrict_devno, &devno, &uuid);
if (r < 0)
return r;
if (r == 0) {
if (!p->format && strv_isempty(p->copy_files) && strv_isempty(p->make_directories))
return log_error_errno(SYNTHETIC_ERRNO(ENXIO),
"Unable to automatically discover suitable partition to copy blocks from.");
continue;
}
assert(devno != 0);
source_fd = r = device_open_from_devnum(S_IFBLK, devno, O_RDONLY|O_CLOEXEC|O_NONBLOCK, &opened);
@@ -6016,7 +6000,6 @@ 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"
" --oem=BOOL Whether to only include OEM partitions\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
@@ -6026,17 +6009,6 @@ static int help(void) {
return 0;
}
static int parse_credentials(void) {
int r;
r = read_credential_bool("repart.oem");
if (r < 0)
return log_error_errno(r, "Failed to read repart.oem credential: %m");
arg_oem = r;
return 0;
}
static int parse_argv(int argc, char *argv[]) {
enum {
@@ -6071,7 +6043,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SKIP_PARTITIONS,
ARG_ARCHITECTURE,
ARG_OFFLINE,
ARG_OEM,
};
static const struct option options[] = {
@@ -6106,7 +6077,6 @@ static int parse_argv(int argc, char *argv[]) {
{ "sector-size", required_argument, NULL, ARG_SECTOR_SIZE },
{ "architecture", required_argument, NULL, ARG_ARCHITECTURE },
{ "offline", required_argument, NULL, ARG_OFFLINE },
{ "oem", required_argument, NULL, ARG_OEM },
{}
};
@@ -6428,13 +6398,6 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_OEM:
r = parse_boolean_argument("--oem=", optarg, &arg_oem);
if (r < 0)
return r;
break;
case '?':
return -EINVAL;
@@ -6931,10 +6894,6 @@ static int run(int argc, char *argv[]) {
log_parse_environment();
log_open();
r = parse_credentials();
if (r < 0)
return r;
r = parse_argv(argc, argv);
if (r <= 0)
return r;

View File

@@ -132,9 +132,6 @@ EOF
Type=home
Label=home-first
Label=home-always-too-long-xxxxxxxxxxxxxx-%v
# Test that OEM=yes makes sure that a partition is OEM even if FactoryReset=yes is set.
FactoryReset=yes
OEM=yes
EOF
tee "$defs/swap.conf" <<EOF
@@ -142,8 +139,6 @@ EOF
Type=swap
SizeMaxBytes=64M
PaddingMinBytes=92M
# No OEM=yes here so this should not be considered an OEM partition since FactoryReset=yes.
FactoryReset=yes
EOF
systemd-repart --offline="$OFFLINE" \
@@ -165,26 +160,6 @@ 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" \
--dry-run=no \
--seed="$seed" \
--empty=force \
--include-partitions=home,swap \
--oem=yes \
--offline="$OFFLINE" \
"$imgs/zzz"
output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$')
assert_eq "$output" "label: gpt
label-id: 1D2CE291-7CCE-4F7D-BC83-FDB49AD74EBD
device: $imgs/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
$imgs/zzz1 : start= 2048, size= 2095064, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\""
systemd-repart --offline="$OFFLINE" \
--definitions="$defs" \
--dry-run=no \
@@ -293,9 +268,6 @@ Type=linux-generic
Label=block-copy
UUID=2a1d97e1d0a346cca26eadc643926617
CopyBlocks=$imgs/block-copy
# Test that these are ignored
CopyFiles=abc
Format=ext4
EOF
systemd-repart --offline="$OFFLINE" \
@@ -931,8 +903,6 @@ CopyFiles=/
CopyFiles=/zzz:/
CopyFiles=/:/oiu
ExcludeFilesTarget=/oiu/usr
# Test that this is just ignored
CopyBlocks=auto
EOF
tee "$defs/10-usr.conf" <<EOF

View File

@@ -30,7 +30,6 @@ Before=shutdown.target initrd-switch-root.target
Type=oneshot
RemainAfterExit=yes
ExecStart={{BINDIR}}/systemd-repart --dry-run=no
ImportCredential=repart.*
# The tool returns 77 if there's no existing GPT partition table
SuccessExitStatus=77