diff --git a/man/repart.d.xml b/man/repart.d.xml
index 752fc3b852..7e4fe93cfc 100644
--- a/man/repart.d.xml
+++ b/man/repart.d.xml
@@ -567,6 +567,15 @@
into their original state by removing partitions and creating them anew. Defaults to off.
+
+ OEM=
+
+ Takes a boolean argument. If specified the partition is marked as an OEM partition.
+ When the is used, only OEM partitions are written to the partition table.
+ Unless configured explicitly with OEM=, a partition is an OEM partition if
+ FactoryReset=no.
+
+
Flags=
diff --git a/man/systemd-repart.xml b/man/systemd-repart.xml
index 1799961527..39912052a4 100644
--- a/man/systemd-repart.xml
+++ b/man/systemd-repart.xml
@@ -440,6 +440,14 @@
due to missing permissions.
+
+ BOOL
+
+ Instructs systemd-repart to only include OEM partitions into the
+ image. Takes a boolean and is off by default. OEM partitions can be configured using the
+ OEM= setting.
+
+
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 74e04b65ab..9ae8ed4c11 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -24,6 +24,7 @@
#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"
@@ -153,6 +154,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 bool arg_oem = false;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
@@ -205,6 +207,7 @@ typedef struct Partition {
bool dropped;
bool factory_reset;
+ int oem;
int32_t priority;
uint32_t weight, padding_weight;
@@ -350,6 +353,7 @@ static Partition *partition_new(void) {
.no_auto = -1,
.read_only = -1,
.growfs = -1,
+ .oem = -1,
};
return p;
@@ -423,9 +427,16 @@ 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;
@@ -1631,6 +1642,7 @@ 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;
@@ -6004,6 +6016,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"
+ " --oem=BOOL Whether to only include OEM partitions\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
@@ -6013,6 +6026,17 @@ 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 {
@@ -6047,6 +6071,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SKIP_PARTITIONS,
ARG_ARCHITECTURE,
ARG_OFFLINE,
+ ARG_OEM,
};
static const struct option options[] = {
@@ -6081,6 +6106,7 @@ 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 },
{}
};
@@ -6402,6 +6428,13 @@ 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;
@@ -6898,6 +6931,10 @@ 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;
diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh
index fbfc9e7b3a..f90c3b1b4e 100755
--- a/test/units/testsuite-58.sh
+++ b/test/units/testsuite-58.sh
@@ -132,6 +132,9 @@ 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" <