File 0001-test.patch of Package systemd
From 2f8fd71fa2546296f2210d75899c3c891ea85243 Mon Sep 17 00:00:00 2001
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
Date: Wed, 3 Dec 2025 15:06:32 +0100
Subject: [PATCH] test
---
man/systemctl.xml | 37 ++++++-------
shell-completion/bash/systemctl.in | 2 +-
src/shared/install.c | 67 +++++++++++++++++++++--
src/shared/install.h | 2 +
src/systemctl/systemctl-list-unit-files.c | 1 +
src/systemctl/systemctl-show.c | 19 ++++++-
src/systemctl/systemctl.c | 11 ++--
7 files changed, 105 insertions(+), 34 deletions(-)
diff --git a/man/systemctl.xml b/man/systemctl.xml
index eae6442f58..7914a520cc 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -997,18 +997,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<term><command>preset <replaceable>UNIT</replaceable>…</command></term>
<listitem>
- <para>Reset the enable/disable status of one or more unit files, as specified on
- the command line, to the defaults configured in the preset policy files. This
- has the same effect as <command>disable</command> or
- <command>enable</command>, depending how the unit is listed in the preset
+ <para>Reset the enable/disable/mask status of one or more unit files, as specified on the command line, to
+ the defaults configured in the preset policy files. This has the same effect as <command>disable</command>,
+ <command>enable</command>, or <command>mask</command>, depending how the unit is listed in the preset
files.</para>
- <para>Use <option>--preset-mode=</option> to control whether units shall be
- enabled and disabled, or only enabled, or only disabled.</para>
+ <para>Use <option>--preset-mode=</option> to control whether units shall be enabled, disabled, and masked,
+ or only enabled, or only disabled, or only masked.</para>
- <para>If the unit carries no install information, it will be silently ignored
- by this command. <replaceable>UNIT</replaceable> must be the real unit name,
- any alias names are ignored silently.</para>
+ <para>If the unit carries no install information, it will be silently ignored by this command for the
+ enable/disable directives. <replaceable>UNIT</replaceable> must be the real unit name, any alias names are
+ ignored silently.</para>
<para>For more information on the preset policy format, see
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
@@ -1022,12 +1021,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<term><command>preset-all</command></term>
<listitem>
- <para>Resets all installed unit files to the defaults
- configured in the preset policy file (see above).</para>
+ <para>Resets all installed unit files to the defaults configured in the preset policy file (see above).
+ </para>
- <para>Use <option>--preset-mode=</option> to control
- whether units shall be enabled and disabled, or only
- enabled, or only disabled.</para>
+ <para>Use <option>--preset-mode=</option> to control whether units shall be enabled, disabled, and masked,
+ or only enabled, or only disabled, or only masked.</para>
<xi:include href="version-info.xml" xpointer="v215"/>
</listitem>
@@ -2680,13 +2678,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<term><option>--preset-mode=</option></term>
<listitem>
- <para>Takes one of <literal>full</literal> (the default),
- <literal>enable-only</literal>,
- <literal>disable-only</literal>. When used with the
- <command>preset</command> or <command>preset-all</command>
- commands, controls whether units shall be disabled and
- enabled according to the preset rules, or only enabled, or
- only disabled.</para>
+ <para>Takes one of <literal>full</literal> (the default), <literal>enable-only</literal>,
+ <literal>disable-only</literal>, <literal>mask-only</literal>. When used with the <command>preset</command>
+ or <command>preset-all</command> commands, controls whether units shall be disabled, enabled, and masked
+ according to the preset rules, or only enabled, or only disabled, or only masked.</para>
<xi:include href="version-info.xml" xpointer="v215"/>
</listitem>
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index cbca727cee..60ba21cb41 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -178,7 +178,7 @@ _systemctl () {
comps=$(__systemd_properties)
;;
--preset-mode)
- comps='full enable-only disable-only'
+ comps='full enable-only disable-only mask-only'
;;
--output|-o)
comps=$( systemctl --output=help 2>/dev/null )
diff --git a/src/shared/install.c b/src/shared/install.c
index 8195436564..20f7fb6ad7 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -60,6 +60,7 @@ static const char *const preset_action_past_tense_table[_PRESET_ACTION_MAX] = {
[PRESET_UNKNOWN] = "unknown",
[PRESET_ENABLE] = "enabled",
[PRESET_DISABLE] = "disabled",
+ [PRESET_MASK] = "masked",
[PRESET_IGNORE] = "ignored",
};
@@ -3392,6 +3393,18 @@ static int read_presets(RuntimeScope scope, const char *root_dir, UnitFilePreset
.action = PRESET_DISABLE,
};
+ } else if ((parameter = first_word(line, "mask"))) {
+ char *pattern;
+
+ pattern = strdup(parameter);
+ if (!pattern)
+ return -ENOMEM;
+
+ rule = (UnitFilePresetRule) {
+ .pattern = pattern,
+ .action = PRESET_MASK,
+ };
+
} else if ((parameter = first_word(line, "ignore"))) {
char *pattern;
@@ -3510,6 +3523,10 @@ static int query_presets(const char *name, const UnitFilePresets *presets, char
log_debug("Preset files say disable %s.", name);
return PRESET_DISABLE;
+ case PRESET_MASK:
+ log_debug("Preset files say mask %s.", name);
+ return PRESET_MASK;
+
case PRESET_IGNORE:
log_debug("Preset files say ignore %s.", name);
return PRESET_IGNORE;
@@ -3538,6 +3555,7 @@ static int execute_preset(
UnitFileFlags file_flags,
InstallContext *plus,
InstallContext *minus,
+ char * const *masks,
const LookupPaths *lp,
const char *config_path,
char * const *files,
@@ -3552,7 +3570,24 @@ static int execute_preset(
assert(lp);
assert(config_path);
- if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
+ if (!IN_SET(mode, UNIT_FILE_PRESET_ENABLE_ONLY, UNIT_FILE_PRESET_DISABLE_ONLY))
+ STRV_FOREACH(name, masks) {
+ _cleanup_free_ char *path = NULL;
+
+ path = path_make_absolute(*name, config_path);
+ if (!path)
+ return -ENOMEM;
+
+ RET_GATHER(r, create_symlink(
+ lp,
+ "/dev/null",
+ path,
+ file_flags & UNIT_FILE_FORCE,
+ changes,
+ n_changes));
+ }
+
+ if (!IN_SET(mode, UNIT_FILE_PRESET_ENABLE_ONLY, UNIT_FILE_PRESET_MASK_ONLY)) {
_cleanup_set_free_ Set *remove_symlinks_to = NULL;
r = install_context_mark_for_removal(minus, lp, &remove_symlinks_to, config_path, changes, n_changes);
@@ -3563,7 +3598,7 @@ static int execute_preset(
} else
r = 0;
- if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
+ if (!IN_SET(mode, UNIT_FILE_PRESET_DISABLE_ONLY, UNIT_FILE_PRESET_MASK_ONLY)) {
int q;
/* Returns number of symlinks that where supposed to be installed. */
@@ -3586,6 +3621,7 @@ static int preset_prepare_one(
RuntimeScope scope,
InstallContext *plus,
InstallContext *minus,
+ char ***masks,
LookupPaths *lp,
const char *name,
const UnitFilePresets *presets,
@@ -3632,6 +3668,13 @@ static int preset_prepare_one(
r = install_info_discover(minus, lp, name, SEARCH_FOLLOW_CONFIG_SYMLINKS,
&info, changes, n_changes);
+ else if (r == PRESET_MASK) {
+ if (!unit_name_is_valid(name, UNIT_NAME_ANY))
+ return -EINVAL;
+
+ r = strv_extend(masks, name);
+ }
+
return r;
}
@@ -3645,6 +3688,7 @@ int unit_file_preset(
size_t *n_changes) {
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
+ _cleanup_strv_free_ char **masks = NULL;
_cleanup_(lookup_paths_done) LookupPaths lp = {};
_cleanup_(unit_file_presets_done) UnitFilePresets presets = {};
const char *config_path;
@@ -3667,12 +3711,12 @@ int unit_file_preset(
return r;
STRV_FOREACH(name, names) {
- r = preset_prepare_one(scope, &plus, &minus, &lp, *name, &presets, changes, n_changes);
+ r = preset_prepare_one(scope, &plus, &minus, &masks, &lp, *name, &presets, changes, n_changes);
if (r < 0)
return r;
}
- return execute_preset(file_flags, &plus, &minus, &lp, config_path, names, mode, changes, n_changes);
+ return execute_preset(file_flags, &plus, &minus, masks, &lp, config_path, names, mode, changes, n_changes);
}
int unit_file_preset_all(
@@ -3684,6 +3728,7 @@ int unit_file_preset_all(
size_t *n_changes) {
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
+ _cleanup_strv_free_ char **masks = NULL;
_cleanup_(lookup_paths_done) LookupPaths lp = {};
_cleanup_(unit_file_presets_done) UnitFilePresets presets = {};
const char *config_path = NULL;
@@ -3725,7 +3770,16 @@ int unit_file_preset_all(
if (!IN_SET(de->d_type, DT_LNK, DT_REG))
continue;
- k = preset_prepare_one(scope, &plus, &minus, &lp, de->d_name, &presets, changes, n_changes);
+ k = preset_prepare_one(
+ scope,
+ &plus,
+ &minus,
+ &masks,
+ &lp,
+ de->d_name,
+ &presets,
+ changes,
+ n_changes);
if (k < 0 &&
!IN_SET(k, -EEXIST,
-ERFKILL,
@@ -3745,7 +3799,7 @@ int unit_file_preset_all(
}
}
- return execute_preset(file_flags, &plus, &minus, &lp, config_path, NULL, mode, changes, n_changes);
+ return execute_preset(file_flags, &plus, &minus, masks, &lp, config_path, NULL, mode, changes, n_changes);
}
static UnitFileList* unit_file_list_free(UnitFileList *f) {
@@ -3882,6 +3936,7 @@ static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MODE_MAX]
[UNIT_FILE_PRESET_FULL] = "full",
[UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
[UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
+ [UNIT_FILE_PRESET_MASK_ONLY] = "mask-only",
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);
diff --git a/src/shared/install.h b/src/shared/install.h
index 53753a0366..99ad286f6e 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -9,6 +9,7 @@ typedef enum UnitFilePresetMode {
UNIT_FILE_PRESET_FULL,
UNIT_FILE_PRESET_ENABLE_ONLY,
UNIT_FILE_PRESET_DISABLE_ONLY,
+ UNIT_FILE_PRESET_MASK_ONLY,
_UNIT_FILE_PRESET_MODE_MAX,
_UNIT_FILE_PRESET_MODE_INVALID = -EINVAL,
} UnitFilePresetMode;
@@ -218,6 +219,7 @@ typedef enum PresetAction {
PRESET_UNKNOWN,
PRESET_ENABLE,
PRESET_DISABLE,
+ PRESET_MASK,
PRESET_IGNORE,
_PRESET_ACTION_MAX,
_PRESET_ACTION_INVALID = -EINVAL,
diff --git a/src/systemctl/systemctl-list-unit-files.c b/src/systemctl/systemctl-list-unit-files.c
index 548b2573fc..a8443a3b9b 100644
--- a/src/systemctl/systemctl-list-unit-files.c
+++ b/src/systemctl/systemctl-list-unit-files.c
@@ -86,6 +86,7 @@ static const char* preset_action_to_color(PresetAction action, bool underline) {
case PRESET_ENABLE:
return underline ? ansi_highlight_green_underline() : ansi_highlight_green();
case PRESET_DISABLE:
+ case PRESET_MASK:
return underline ? ansi_highlight_red_underline() : ansi_highlight_red();
case PRESET_IGNORE:
return underline ? ansi_highlight_yellow_underline() : ansi_highlight_yellow();
diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c
index 245ffdde09..124b03c29c 100644
--- a/src/systemctl/systemctl-show.c
+++ b/src/systemctl/systemctl-show.c
@@ -348,6 +348,23 @@ static void format_enable_state(const char *enable_state, const char **enable_on
*enable_on = *enable_off = "";
}
+static void format_preset_state(const char *preset_state, const char **preset_on, const char **preset_off) {
+ assert(preset_on);
+ assert(preset_off);
+
+ if (streq_ptr(preset_state, "masked")) {
+ *preset_on = ansi_highlight_red();
+ *preset_off = ansi_normal();
+ } else if (streq_ptr(preset_state, "disabled")) {
+ *preset_on = ansi_highlight_yellow();
+ *preset_off = ansi_normal();
+ } else if (streq_ptr(preset_state, "enabled")) {
+ *preset_on = ansi_highlight_green();
+ *preset_off = ansi_normal();
+ } else
+ *preset_on = *preset_off = "";
+}
+
static void print_exec_directory_quota(UnitStatusInfo *i, ExecDirectoryType dt) {
assert(i);
@@ -383,7 +400,7 @@ static void print_status_info(
format_active_state(i->active_state, &active_on, &active_off);
format_enable_state(i->unit_file_state, &enable_on, &enable_off);
- format_enable_state(i->unit_file_preset, &preset_on, &preset_off);
+ format_preset_state(i->unit_file_preset, &preset_on, &preset_off);
const Glyph icon = unit_active_state_to_glyph(unit_active_state_from_string(i->active_state));
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 01b5517d14..355f9317cb 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -169,10 +169,10 @@ static int systemctl_help(void) {
" enable [UNIT...|PATH...] Enable one or more unit files\n"
" disable UNIT... Disable one or more unit files\n"
" reenable UNIT... Reenable one or more unit files\n"
- " preset UNIT... Enable/disable one or more unit files\n"
- " based on preset configuration\n"
- " preset-all Enable/disable all unit files based on\n"
- " preset configuration\n"
+ " preset UNIT... Enable/disable/mask one or more unit\n"
+ " files based on preset configuration\n"
+ " preset-all Enable/disable/mask all unit files based\n"
+ " on preset configuration\n"
" is-enabled UNIT... Check whether unit files are enabled\n"
" mask UNIT... Mask one or more units\n"
" unmask UNIT... Unmask one or more units\n"
@@ -285,7 +285,8 @@ static int systemctl_help(void) {
" next reboot\n"
" -f --force When enabling unit files, override existing symlinks\n"
" When shutting down, execute action immediately\n"
- " --preset-mode= Apply only enable, only disable, or all presets\n"
+ " --preset-mode= Apply only enable, only disable, only mask, or all\n"
+ " presets\n"
" --root=PATH Edit/enable/disable/mask unit files in the specified\n"
" root directory\n"
" --image=PATH Edit/enable/disable/mask unit files in the specified\n"
--
2.51.0