mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
install: beef up preset logic to limit to only enable or only disable, and do all-unit preset operations
The new "systemctl preset-all" command may now be used to put all installed units back into the enable/disable state the vendor/admin encoded in preset files. Also, introduce "systemctl --preset-mode=enable-only" and "systemctl --preset-mode=disable-only" to only apply the enable or only the disable operations of a "systemctl preset" or "systemctl preset-all" operation. "systemctl preset-all" implements this RFE: https://bugzilla.redhat.com/show_bug.cgi?id=630174
This commit is contained in:
parent
bcafe923a7
commit
d309c1c364
|
@ -476,6 +476,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<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 use 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>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-n</option></term>
|
||||
<term><option>--lines=</option></term>
|
||||
|
@ -1025,16 +1039,35 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
|
|||
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 files. For
|
||||
more information on the preset policy format, see
|
||||
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>For more information on the preset policy format,
|
||||
see
|
||||
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
For more information on the concept of presets, please
|
||||
consult the
|
||||
<ulink url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
|
||||
consult the <ulink
|
||||
url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
|
||||
document.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<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>Use <option>--preset-mode=</option> to control
|
||||
whether units shall be enabled and disabled, or only
|
||||
enabled, or only disabled.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>mask <replaceable>NAME</replaceable>...</command></term>
|
||||
|
||||
|
|
|
@ -1487,8 +1487,8 @@ fail:
|
|||
static int method_enable_unit_files_generic(
|
||||
sd_bus *bus,
|
||||
sd_bus_message *message,
|
||||
Manager *m, const
|
||||
char *verb,
|
||||
Manager *m,
|
||||
const char *verb,
|
||||
int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
|
||||
bool carries_install_info,
|
||||
sd_bus_error *error) {
|
||||
|
@ -1510,6 +1510,10 @@ static int method_enable_unit_files_generic(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(message, "bb", &runtime, &force);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
STRV_FOREACH(i, l) {
|
||||
Unit *u;
|
||||
|
@ -1523,10 +1527,6 @@ static int method_enable_unit_files_generic(
|
|||
}
|
||||
#endif
|
||||
|
||||
r = sd_bus_message_read(message, "bb", &runtime, &force);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
||||
|
||||
r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
|
||||
|
@ -1548,14 +1548,74 @@ static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *us
|
|||
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
|
||||
}
|
||||
|
||||
static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
|
||||
return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
|
||||
}
|
||||
|
||||
static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
|
||||
return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
|
||||
}
|
||||
|
||||
static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
|
||||
}
|
||||
|
||||
static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
#ifdef HAVE_SELINUX
|
||||
char **i;
|
||||
#endif
|
||||
UnitFileChange *changes = NULL;
|
||||
unsigned n_changes = 0;
|
||||
Manager *m = userdata;
|
||||
UnitFilePresetMode mm;
|
||||
UnitFileScope scope;
|
||||
int runtime, force, r;
|
||||
const char *mode;
|
||||
|
||||
assert(bus);
|
||||
assert(message);
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_message_read_strv(message, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isempty(mode))
|
||||
mm = UNIT_FILE_PRESET_FULL;
|
||||
else {
|
||||
mm = unit_file_preset_mode_from_string(mode);
|
||||
if (mm < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
STRV_FOREACH(i, l) {
|
||||
Unit *u;
|
||||
|
||||
u = manager_get_unit(m, *i);
|
||||
if (u) {
|
||||
r = selinux_unit_access_check(u, message, "enable", error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
||||
|
||||
r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
|
||||
}
|
||||
|
||||
static int method_disable_unit_files_generic(
|
||||
sd_bus *bus,
|
||||
sd_bus_message *message,
|
||||
|
@ -1632,6 +1692,44 @@ static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void
|
|||
return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
|
||||
}
|
||||
|
||||
static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
UnitFileChange *changes = NULL;
|
||||
unsigned n_changes = 0;
|
||||
Manager *m = userdata;
|
||||
UnitFilePresetMode mm;
|
||||
UnitFileScope scope;
|
||||
const char *mode;
|
||||
int force, runtime, r;
|
||||
|
||||
assert(bus);
|
||||
assert(message);
|
||||
assert(m);
|
||||
|
||||
r = selinux_access_check(message, "enable", error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isempty(mode))
|
||||
mm = UNIT_FILE_PRESET_FULL;
|
||||
else {
|
||||
mm = unit_file_preset_mode_from_string(mode);
|
||||
if (mm < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
||||
|
||||
r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
|
||||
}
|
||||
|
||||
const sd_bus_vtable bus_manager_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
|
@ -1716,10 +1814,12 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
|||
SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
|
||||
SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
|
||||
SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
|
||||
SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, 0),
|
||||
SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
|
||||
SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
|
||||
SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
|
||||
SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, 0),
|
||||
|
||||
SD_BUS_SIGNAL("UnitNew", "so", 0),
|
||||
SD_BUS_SIGNAL("UnitRemoved", "so", 0),
|
||||
|
|
|
@ -1831,12 +1831,12 @@ int unit_file_preset(
|
|||
bool runtime,
|
||||
const char *root_dir,
|
||||
char **files,
|
||||
UnitFilePresetMode mode,
|
||||
bool force,
|
||||
UnitFileChange **changes,
|
||||
unsigned *n_changes) {
|
||||
|
||||
_cleanup_install_context_done_ InstallContext plus = {}, minus = {};
|
||||
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
|
||||
_cleanup_lookup_paths_free_ LookupPaths paths = {};
|
||||
_cleanup_free_ char *config_path = NULL;
|
||||
char **i;
|
||||
|
@ -1844,6 +1844,7 @@ int unit_file_preset(
|
|||
|
||||
assert(scope >= 0);
|
||||
assert(scope < _UNIT_FILE_SCOPE_MAX);
|
||||
assert(mode < _UNIT_FILE_PRESET_MODE_MAX);
|
||||
|
||||
r = lookup_paths_init_from_scope(&paths, scope, root_dir);
|
||||
if (r < 0)
|
||||
|
@ -1862,25 +1863,141 @@ int unit_file_preset(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (r)
|
||||
if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
|
||||
r = install_info_add_auto(&plus, *i);
|
||||
else
|
||||
else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
|
||||
r = install_info_add_auto(&minus, *i);
|
||||
else
|
||||
r = 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
|
||||
r = 0;
|
||||
|
||||
q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
|
||||
if (r == 0)
|
||||
r = q;
|
||||
if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
|
||||
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
|
||||
|
||||
/* Returns number of symlinks that where supposed to be installed. */
|
||||
q = install_context_apply(&plus, &paths, config_path, root_dir, force,
|
||||
changes, n_changes);
|
||||
if (r == 0)
|
||||
r = q;
|
||||
r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
|
||||
|
||||
q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
|
||||
if (r == 0)
|
||||
r = q;
|
||||
}
|
||||
|
||||
if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
|
||||
/* Returns number of symlinks that where supposed to be installed. */
|
||||
q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
|
||||
if (r == 0)
|
||||
r = q;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int unit_file_preset_all(
|
||||
UnitFileScope scope,
|
||||
bool runtime,
|
||||
const char *root_dir,
|
||||
UnitFilePresetMode mode,
|
||||
bool force,
|
||||
UnitFileChange **changes,
|
||||
unsigned *n_changes) {
|
||||
|
||||
_cleanup_install_context_done_ InstallContext plus = {}, minus = {};
|
||||
_cleanup_lookup_paths_free_ LookupPaths paths = {};
|
||||
_cleanup_free_ char *config_path = NULL;
|
||||
char **i;
|
||||
int r, q;
|
||||
|
||||
assert(scope >= 0);
|
||||
assert(scope < _UNIT_FILE_SCOPE_MAX);
|
||||
assert(mode < _UNIT_FILE_PRESET_MODE_MAX);
|
||||
|
||||
r = lookup_paths_init_from_scope(&paths, scope, root_dir);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = get_config_path(scope, runtime, root_dir, &config_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(i, paths.unit_path) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
const char *units_dir;
|
||||
|
||||
if (!isempty(root_dir)) {
|
||||
buf = strjoin(root_dir, "/", *i, NULL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
units_dir = buf;
|
||||
} else
|
||||
units_dir = *i;
|
||||
|
||||
d = opendir(units_dir);
|
||||
if (!d) {
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
struct dirent *de;
|
||||
|
||||
errno = 0;
|
||||
de = readdir(d);
|
||||
if (!de && errno != 0)
|
||||
return -errno;
|
||||
|
||||
if (!de)
|
||||
break;
|
||||
|
||||
if (ignore_file(de->d_name))
|
||||
continue;
|
||||
|
||||
if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
|
||||
continue;
|
||||
|
||||
dirent_ensure_type(d, de);
|
||||
|
||||
if (de->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
r = unit_file_query_preset(scope, de->d_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
|
||||
r = install_info_add_auto(&plus, de->d_name);
|
||||
else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
|
||||
r = install_info_add_auto(&minus, de->d_name);
|
||||
else
|
||||
r = 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
|
||||
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
|
||||
|
||||
r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
|
||||
|
||||
q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
|
||||
if (r == 0)
|
||||
r = q;
|
||||
}
|
||||
|
||||
if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
|
||||
q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
|
||||
if (r == 0)
|
||||
r = q;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -1937,8 +2054,8 @@ int unit_file_get_list(
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
struct dirent *de;
|
||||
_cleanup_unitfilelist_free_ UnitFileList *f = NULL;
|
||||
struct dirent *de;
|
||||
|
||||
errno = 0;
|
||||
de = readdir(d);
|
||||
|
@ -2031,3 +2148,11 @@ static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX]
|
|||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);
|
||||
|
|
|
@ -45,6 +45,14 @@ typedef enum UnitFileState {
|
|||
_UNIT_FILE_STATE_INVALID = -1
|
||||
} UnitFileState;
|
||||
|
||||
typedef enum UnitFilePresetMode {
|
||||
UNIT_FILE_PRESET_FULL,
|
||||
UNIT_FILE_PRESET_ENABLE_ONLY,
|
||||
UNIT_FILE_PRESET_DISABLE_ONLY,
|
||||
_UNIT_FILE_PRESET_MODE_MAX,
|
||||
_UNIT_FILE_PRESET_INVALID = -1
|
||||
} UnitFilePresetMode;
|
||||
|
||||
typedef enum UnitFileChangeType {
|
||||
UNIT_FILE_SYMLINK,
|
||||
UNIT_FILE_UNLINK,
|
||||
|
@ -77,7 +85,8 @@ int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, ch
|
|||
int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_preset_all(UnitFileScope scope, bool runtime, const char *root_dir, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
|
||||
int unit_file_set_default(UnitFileScope scope, const char *root_dir, const char *file, bool force, UnitFileChange **changes, unsigned *n_changes);
|
||||
|
@ -97,3 +106,6 @@ UnitFileState unit_file_state_from_string(const char *s) _pure_;
|
|||
|
||||
const char *unit_file_change_type_to_string(UnitFileChangeType s) _const_;
|
||||
UnitFileChangeType unit_file_change_type_from_string(const char *s) _pure_;
|
||||
|
||||
const char *unit_file_preset_mode_to_string(UnitFilePresetMode m) _const_;
|
||||
UnitFilePresetMode unit_file_preset_mode_from_string(const char *s) _pure_;
|
||||
|
|
|
@ -101,6 +101,7 @@ static bool arg_recursive = false;
|
|||
static int arg_force = 0;
|
||||
static bool arg_ask_password = true;
|
||||
static bool arg_runtime = false;
|
||||
static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
|
||||
static char **arg_wall = NULL;
|
||||
static const char *arg_kill_who = NULL;
|
||||
static int arg_signal = SIGTERM;
|
||||
|
@ -5209,7 +5210,7 @@ static int enable_unit(sd_bus *bus, char **args) {
|
|||
} else if (streq(verb, "link"))
|
||||
r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||
else if (streq(verb, "preset")) {
|
||||
r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||
r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
|
||||
carries_install_info = r;
|
||||
} else if (streq(verb, "mask"))
|
||||
r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
|
||||
|
@ -5231,7 +5232,7 @@ static int enable_unit(sd_bus *bus, char **args) {
|
|||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int expect_carries_install_info = false;
|
||||
bool send_force = true;
|
||||
bool send_force = true, send_preset_mode = false;
|
||||
const char *method;
|
||||
|
||||
if (streq(verb, "enable")) {
|
||||
|
@ -5246,7 +5247,13 @@ static int enable_unit(sd_bus *bus, char **args) {
|
|||
} else if (streq(verb, "link"))
|
||||
method = "LinkUnitFiles";
|
||||
else if (streq(verb, "preset")) {
|
||||
method = "PresetUnitFiles";
|
||||
|
||||
if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
|
||||
method = "PresetUnitFilesWithMode";
|
||||
send_preset_mode = true;
|
||||
} else
|
||||
method = "PresetUnitFiles";
|
||||
|
||||
expect_carries_install_info = true;
|
||||
} else if (streq(verb, "mask"))
|
||||
method = "MaskUnitFiles";
|
||||
|
@ -5270,6 +5277,12 @@ static int enable_unit(sd_bus *bus, char **args) {
|
|||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
if (send_preset_mode) {
|
||||
r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(m, "b", arg_runtime);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
@ -5320,6 +5333,61 @@ finish:
|
|||
return r;
|
||||
}
|
||||
|
||||
static int preset_all(sd_bus *bus, char **args) {
|
||||
UnitFileChange *changes = NULL;
|
||||
unsigned n_changes = 0;
|
||||
int r;
|
||||
|
||||
if (!bus || avoid_bus()) {
|
||||
|
||||
r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
|
||||
if (r < 0) {
|
||||
log_error("Operation failed: %s", strerror(-r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!arg_quiet)
|
||||
dump_unit_file_changes(changes, n_changes);
|
||||
|
||||
r = 0;
|
||||
|
||||
} else {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.systemd1",
|
||||
"/org/freedesktop/systemd1",
|
||||
"org.freedesktop.systemd1.Manager",
|
||||
"PresetAllUnitFiles",
|
||||
&error,
|
||||
&reply,
|
||||
"sbb",
|
||||
unit_file_preset_mode_to_string(arg_preset_mode),
|
||||
arg_runtime,
|
||||
arg_force);
|
||||
if (r < 0) {
|
||||
log_error("Failed to execute operation: %s", bus_error_message(&error, r));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = deserialize_and_dump_unit_file_changes(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!arg_no_reload)
|
||||
r = daemon_reload(bus, args);
|
||||
else
|
||||
r = 0;
|
||||
}
|
||||
|
||||
finish:
|
||||
unit_file_changes_free(changes, n_changes);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int unit_is_enabled(sd_bus *bus, char **args) {
|
||||
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
|
@ -5437,6 +5505,8 @@ static int systemctl_help(void) {
|
|||
" --runtime Enable unit files only temporarily until next reboot\n"
|
||||
" -f --force When enabling unit files, override existing symlinks\n"
|
||||
" When shutting down, execute action immediately\n"
|
||||
" --preset-mode= Specifies whether fully apply presets, or only enable,\n"
|
||||
" or only disable\n"
|
||||
" --root=PATH Enable unit files in the specified root directory\n"
|
||||
" -n --lines=INTEGER Number of journal entries to show\n"
|
||||
" -o --output=STRING Change journal output mode (short, short-monotonic,\n"
|
||||
|
@ -5477,6 +5547,8 @@ static int systemctl_help(void) {
|
|||
" reenable NAME... Reenable one or more unit files\n"
|
||||
" preset NAME... 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"
|
||||
" is-enabled NAME... Check whether unit files are enabled\n\n"
|
||||
" mask NAME... Mask one or more units\n"
|
||||
" unmask NAME... Unmask one or more units\n"
|
||||
|
@ -5625,7 +5697,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
|||
ARG_FORCE,
|
||||
ARG_PLAIN,
|
||||
ARG_STATE,
|
||||
ARG_JOB_MODE
|
||||
ARG_JOB_MODE,
|
||||
ARG_PRESET_MODE,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
|
@ -5667,6 +5740,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
|||
{ "plain", no_argument, NULL, ARG_PLAIN },
|
||||
{ "state", required_argument, NULL, ARG_STATE },
|
||||
{ "recursive", no_argument, NULL, 'r' },
|
||||
{ "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -5932,6 +6006,16 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
|
|||
arg_recursive = true;
|
||||
break;
|
||||
|
||||
case ARG_PRESET_MODE:
|
||||
|
||||
arg_preset_mode = unit_file_preset_mode_from_string(optarg);
|
||||
if (arg_preset_mode < 0) {
|
||||
log_error("Failed to parse preset mode: %s.", optarg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -6483,6 +6567,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
|
|||
{ "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
|
||||
{ "reenable", MORE, 2, enable_unit, NOBUS },
|
||||
{ "preset", MORE, 2, enable_unit, NOBUS },
|
||||
{ "preset-all", EQUAL, 1, preset_all, NOBUS },
|
||||
{ "mask", MORE, 2, enable_unit, NOBUS },
|
||||
{ "unmask", MORE, 2, enable_unit, NOBUS },
|
||||
{ "link", MORE, 2, enable_unit, NOBUS },
|
||||
|
|
|
@ -253,7 +253,7 @@ int main(int argc, char* argv[]) {
|
|||
changes = NULL;
|
||||
n_changes = 0;
|
||||
|
||||
r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
|
||||
r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, UNIT_FILE_PRESET_FULL, false, &changes, &n_changes);
|
||||
assert_se(r >= 0);
|
||||
|
||||
dump_changes(changes, n_changes);
|
||||
|
|
Loading…
Reference in a new issue