mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
repart: add --append-fstab parameter
If --generate-fstab=PATH is used, there is the possibility that the fstab file already exists, making systemd-repart fail. This commit will add a new --append-fstab= parameter, that will read the file and merge it with the new generated content. Using the comments, the command can separate the automatic-generated section from the user-provided section, allowing for the next append the replacement only of the automatic-generated section, keeping the user one. Signed-off-by: Alberto Planas <aplanas@suse.com>
This commit is contained in:
@@ -619,6 +619,30 @@
|
||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--append-fstab=</option></term>
|
||||
|
||||
<listitem><para>Takes one of <literal>no</literal>, <literal>auto</literal> or
|
||||
<literal>replace</literal>. Controls how the generated
|
||||
<citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
file by <option>--generate-fstab=</option> will behave in case that there is a previously
|
||||
existing file.</para>
|
||||
|
||||
<para>If <literal>no</literal> <command>systemd-repart</command> will complain and abort in
|
||||
case that there is a file. This is the default behaviour. If <literal>replace</literal>
|
||||
the file will be silently replaced with the new generated one.</para>
|
||||
|
||||
<para>If <literal>auto</literal> <command>systemd-repart</command> will search in the pre-existing file
|
||||
the section that belong to the automatically generated content and will replace it with the newer
|
||||
generated content, and keep the user provided section if there is one. The generated section is
|
||||
identified looking for the automatic content surrounded by
|
||||
<literal># Start section ↓ of automatically generated fstab by systemd-repart</literal> and
|
||||
<literal># End section ↑ of automatically generated fstab by systemd-repart</literal>. The content
|
||||
that is before and after those comments are considered user provided, and kept in the new file.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--generate-fstab=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
|
||||
@@ -111,6 +111,9 @@
|
||||
|
||||
#define APIVFS_TMP_DIRS_NULSTR "proc\0sys\0dev\0tmp\0run\0var/tmp\0"
|
||||
|
||||
#define AUTOMATIC_FSTAB_HEADER_START "# Start section ↓ of automatically generated fstab by systemd-repart"
|
||||
#define AUTOMATIC_FSTAB_HEADER_END "# End section ↑ of automatically generated fstab by systemd-repart"
|
||||
|
||||
/* Note: When growing and placing new partitions we always align to 4K sector size. It's how newer hard disks
|
||||
* are designed, and if everything is aligned to that performance is best. And for older hard disks with 512B
|
||||
* sector size devices were generally assumed to have an even number of sectors, hence at the worst we'll
|
||||
@@ -135,6 +138,14 @@ typedef enum FilterPartitionType {
|
||||
_FILTER_PARTITIONS_INVALID = -EINVAL,
|
||||
} FilterPartitionsType;
|
||||
|
||||
typedef enum AppendMode {
|
||||
APPEND_NO,
|
||||
APPEND_AUTO,
|
||||
APPEND_REPLACE,
|
||||
_APPEND_MODE_MAX,
|
||||
_APPEND_MODE_INVALID = -EINVAL,
|
||||
} AppendMode;
|
||||
|
||||
static EmptyMode arg_empty = EMPTY_UNSET;
|
||||
static bool arg_dry_run = true;
|
||||
static char *arg_node = NULL;
|
||||
@@ -181,6 +192,7 @@ static int arg_offline = -1;
|
||||
static char **arg_copy_from = NULL;
|
||||
static char *arg_copy_source = NULL;
|
||||
static char *arg_make_ddi = NULL;
|
||||
static AppendMode arg_append_fstab = APPEND_NO;
|
||||
static char *arg_generate_fstab = NULL;
|
||||
static char *arg_generate_crypttab = NULL;
|
||||
static Set *arg_verity_settings = NULL;
|
||||
@@ -455,6 +467,12 @@ static const char *empty_mode_table[_EMPTY_MODE_MAX] = {
|
||||
[EMPTY_CREATE] = "create",
|
||||
};
|
||||
|
||||
static const char *append_mode_table[_APPEND_MODE_MAX] = {
|
||||
[APPEND_NO] = "no",
|
||||
[APPEND_AUTO] = "auto",
|
||||
[APPEND_REPLACE] = "replace",
|
||||
};
|
||||
|
||||
static const char *encrypt_mode_table[_ENCRYPT_MODE_MAX] = {
|
||||
[ENCRYPT_OFF] = "off",
|
||||
[ENCRYPT_KEY_FILE] = "key-file",
|
||||
@@ -476,6 +494,7 @@ static const char *minimize_mode_table[_MINIMIZE_MODE_MAX] = {
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(empty_mode, EmptyMode);
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(append_mode, AppendMode);
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(encrypt_mode, EncryptMode, ENCRYPT_KEY_FILE);
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(verity_mode, VerityMode);
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(minimize_mode, MinimizeMode, MINIMIZE_BEST);
|
||||
@@ -7495,7 +7514,7 @@ static bool need_fstab(const Context *context) {
|
||||
static int context_fstab(Context *context) {
|
||||
_cleanup_(unlink_and_freep) char *t = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *path = NULL;
|
||||
_cleanup_free_ char *path = NULL, *c = NULL;
|
||||
int r;
|
||||
|
||||
assert(context);
|
||||
@@ -7517,7 +7536,7 @@ static int context_fstab(Context *context) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open temporary file for %s: %m", path);
|
||||
|
||||
fprintf(f, "# Automatically generated by systemd-repart\n\n");
|
||||
fputs(AUTOMATIC_FSTAB_HEADER_START "\n", f);
|
||||
|
||||
LIST_FOREACH(partitions, p, context->partitions) {
|
||||
_cleanup_free_ char *what = NULL, *options = NULL;
|
||||
@@ -7552,7 +7571,38 @@ static int context_fstab(Context *context) {
|
||||
}
|
||||
}
|
||||
|
||||
r = flink_tmpfile(f, t, path, 0);
|
||||
fputs(AUTOMATIC_FSTAB_HEADER_END "\n", f);
|
||||
|
||||
switch (arg_append_fstab) {
|
||||
case APPEND_AUTO: {
|
||||
r = read_full_file(path, &c, NULL);
|
||||
if (r < 0) {
|
||||
if (r == -ENOENT) {
|
||||
log_debug("File fstab not found in %s", path);
|
||||
break;
|
||||
}
|
||||
return log_error_errno(r, "Failed to open %s: %m", path);
|
||||
}
|
||||
|
||||
const char *acs, *ace;
|
||||
acs = find_line(c, AUTOMATIC_FSTAB_HEADER_START);
|
||||
if (acs) {
|
||||
fwrite(c, 1, acs - c, f);
|
||||
ace = find_line_after(acs, AUTOMATIC_FSTAB_HEADER_END);
|
||||
if (ace)
|
||||
fputs(ace, f);
|
||||
} else
|
||||
fputs(c, f);
|
||||
break;
|
||||
}
|
||||
case APPEND_NO:
|
||||
case APPEND_REPLACE:
|
||||
break;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
r = flink_tmpfile(f, t, path, IN_SET(arg_append_fstab, APPEND_AUTO, APPEND_REPLACE) ? LINK_TMPFILE_REPLACE : 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to link temporary file to %s: %m", path);
|
||||
|
||||
@@ -8174,6 +8224,8 @@ static int help(void) {
|
||||
" -C --make-ddi=confext Make a configuration extension DDI\n"
|
||||
" -P --make-ddi=portable Make a portable service DDI\n"
|
||||
"\n%3$sAuxiliary Resource Generation:%4$s\n"
|
||||
" --append-fstab=MODE One of no, auto, replace; controls how to join the\n"
|
||||
" content of a pre-existing fstab with the generated one\n"
|
||||
" --generate-fstab=PATH\n"
|
||||
" Write fstab configuration to the given path\n"
|
||||
" --generate-crypttab=PATH\n"
|
||||
@@ -8229,6 +8281,7 @@ static int parse_argv(int argc, char *argv[], X509 **ret_certificate, EVP_PKEY *
|
||||
ARG_OFFLINE,
|
||||
ARG_COPY_FROM,
|
||||
ARG_MAKE_DDI,
|
||||
ARG_APPEND_FSTAB,
|
||||
ARG_GENERATE_FSTAB,
|
||||
ARG_GENERATE_CRYPTTAB,
|
||||
ARG_LIST_DEVICES,
|
||||
@@ -8275,6 +8328,7 @@ static int parse_argv(int argc, char *argv[], X509 **ret_certificate, EVP_PKEY *
|
||||
{ "copy-from", required_argument, NULL, ARG_COPY_FROM },
|
||||
{ "copy-source", required_argument, NULL, 's' },
|
||||
{ "make-ddi", required_argument, NULL, ARG_MAKE_DDI },
|
||||
{ "append-fstab", required_argument, NULL, ARG_APPEND_FSTAB },
|
||||
{ "generate-fstab", required_argument, NULL, ARG_GENERATE_FSTAB },
|
||||
{ "generate-crypttab", required_argument, NULL, ARG_GENERATE_CRYPTTAB },
|
||||
{ "list-devices", no_argument, NULL, ARG_LIST_DEVICES },
|
||||
@@ -8658,6 +8712,17 @@ static int parse_argv(int argc, char *argv[], X509 **ret_certificate, EVP_PKEY *
|
||||
return r;
|
||||
break;
|
||||
|
||||
case ARG_APPEND_FSTAB:
|
||||
if (isempty(optarg)) {
|
||||
arg_append_fstab = APPEND_AUTO;
|
||||
break;
|
||||
}
|
||||
|
||||
arg_append_fstab = append_mode_from_string(optarg);
|
||||
if (arg_append_fstab < 0)
|
||||
return log_error_errno(arg_append_fstab, "Failed to parse --append-fstab= parameter: %s", optarg);
|
||||
break;
|
||||
|
||||
case ARG_GENERATE_FSTAB:
|
||||
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_generate_fstab);
|
||||
if (r < 0)
|
||||
@@ -8850,6 +8915,9 @@ static int parse_argv(int argc, char *argv[], X509 **ret_certificate, EVP_PKEY *
|
||||
return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
|
||||
}
|
||||
|
||||
if (arg_append_fstab && !arg_generate_fstab)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No --generate-fstab= specified for --append-fstab=%s.", append_mode_to_string(arg_append_fstab));
|
||||
|
||||
*ret_certificate = TAKE_PTR(certificate);
|
||||
*ret_private_key = TAKE_PTR(private_key);
|
||||
*ret_ui = TAKE_PTR(ui);
|
||||
|
||||
Reference in New Issue
Block a user