Merge pull request #15692 from keszybz/preset-cleanup
Make systemctl list-unit-files output more useful
This commit is contained in:
commit
c92391f52f
|
@ -753,6 +753,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>linked-runtime</literal></entry>
|
<entry><literal>linked-runtime</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><literal>alias</literal></entry>
|
||||||
|
<entry>The name is an alias (symlink to another unit file).</entry>
|
||||||
|
<entry>0</entry>
|
||||||
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>masked</literal></entry>
|
<entry><literal>masked</literal></entry>
|
||||||
<entry morerows='1'>Completely disabled, so that any start operation on it fails (permanently in <filename>/etc/systemd/system/</filename> or transiently in <filename>/run/systemd/systemd/</filename>).</entry>
|
<entry morerows='1'>Completely disabled, so that any start operation on it fails (permanently in <filename>/etc/systemd/system/</filename> or transiently in <filename>/run/systemd/systemd/</filename>).</entry>
|
||||||
|
|
|
@ -891,10 +891,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||||
<term><varname>ProtectSystem=</varname></term>
|
<term><varname>ProtectSystem=</varname></term>
|
||||||
|
|
||||||
<listitem><para>Takes a boolean argument or the special values <literal>full</literal> or
|
<listitem><para>Takes a boolean argument or the special values <literal>full</literal> or
|
||||||
<literal>strict</literal>. If true, mounts the <filename>/usr</filename> and <filename>/boot</filename>
|
<literal>strict</literal>. If true, mounts the <filename>/usr</filename> and the boot loader
|
||||||
directories read-only for processes invoked by this unit. If set to <literal>full</literal>, the
|
directories (<filename>/boot</filename> and <filename>/efi</filename>) read-only for processes
|
||||||
<filename>/etc</filename> directory is mounted read-only, too. If set to <literal>strict</literal> the entire
|
invoked by this unit. If set to <literal>full</literal>, the <filename>/etc</filename> directory is
|
||||||
file system hierarchy is mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
|
mounted read-only, too. If set to <literal>strict</literal> the entire file system hierarchy is
|
||||||
|
mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
|
||||||
<filename>/proc</filename> and <filename>/sys</filename> (protect these directories using
|
<filename>/proc</filename> and <filename>/sys</filename> (protect these directories using
|
||||||
<varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
|
<varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
|
||||||
<varname>ProtectControlGroups=</varname>). This setting ensures that any modification of the vendor-supplied
|
<varname>ProtectControlGroups=</varname>). This setting ensures that any modification of the vendor-supplied
|
||||||
|
|
|
@ -4316,7 +4316,8 @@ int unit_get_unit_file_preset(Unit *u) {
|
||||||
u->unit_file_preset = unit_file_query_preset(
|
u->unit_file_preset = unit_file_query_preset(
|
||||||
u->manager->unit_file_scope,
|
u->manager->unit_file_scope,
|
||||||
NULL,
|
NULL,
|
||||||
basename(u->fragment_path));
|
basename(u->fragment_path),
|
||||||
|
NULL);
|
||||||
|
|
||||||
return u->unit_file_preset;
|
return u->unit_file_preset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,16 +55,11 @@ typedef enum {
|
||||||
PRESET_DISABLE,
|
PRESET_DISABLE,
|
||||||
} PresetAction;
|
} PresetAction;
|
||||||
|
|
||||||
typedef struct {
|
struct UnitFilePresetRule {
|
||||||
char *pattern;
|
char *pattern;
|
||||||
PresetAction action;
|
PresetAction action;
|
||||||
char **instances;
|
char **instances;
|
||||||
} PresetRule;
|
};
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PresetRule *rules;
|
|
||||||
size_t n_rules;
|
|
||||||
} Presets;
|
|
||||||
|
|
||||||
static bool unit_file_install_info_has_rules(const UnitFileInstallInfo *i) {
|
static bool unit_file_install_info_has_rules(const UnitFileInstallInfo *i) {
|
||||||
assert(i);
|
assert(i);
|
||||||
|
@ -80,7 +75,7 @@ static bool unit_file_install_info_has_also(const UnitFileInstallInfo *i) {
|
||||||
return !strv_isempty(i->also);
|
return !strv_isempty(i->also);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void presets_freep(Presets *p) {
|
void unit_file_presets_freep(UnitFilePresets *p) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
|
@ -1231,7 +1226,7 @@ static int unit_file_load(
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) && !unit_type_may_template(type))
|
if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) && !unit_type_may_template(type))
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"Unit type %s cannot be templated.", unit_type_to_string(type));
|
"%s: unit type %s cannot be templated, ignoring.", path, unit_type_to_string(type));
|
||||||
|
|
||||||
if (!(flags & SEARCH_LOAD)) {
|
if (!(flags & SEARCH_LOAD)) {
|
||||||
r = lstat(path, &st);
|
r = lstat(path, &st);
|
||||||
|
@ -2772,6 +2767,12 @@ int unit_file_lookup_state(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UNIT_FILE_TYPE_REGULAR:
|
case UNIT_FILE_TYPE_REGULAR:
|
||||||
|
/* Check if the name we were querying is actually an alias */
|
||||||
|
if (!streq(name, basename(i->path)) && !unit_name_is_valid(i->name, UNIT_NAME_INSTANCE)) {
|
||||||
|
state = UNIT_FILE_ALIAS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
r = path_is_generator(paths, i->path);
|
r = path_is_generator(paths, i->path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -2913,8 +2914,8 @@ static int presets_find_config(UnitFileScope scope, const char *root_dir, char *
|
||||||
return conf_files_list_strv(files, ".preset", root_dir, 0, dirs);
|
return conf_files_list_strv(files, ".preset", root_dir, 0, dirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) {
|
static int read_presets(UnitFileScope scope, const char *root_dir, UnitFilePresets *presets) {
|
||||||
_cleanup_(presets_freep) Presets ps = {};
|
_cleanup_(unit_file_presets_freep) UnitFilePresets ps = {};
|
||||||
size_t n_allocated = 0;
|
size_t n_allocated = 0;
|
||||||
_cleanup_strv_free_ char **files = NULL;
|
_cleanup_strv_free_ char **files = NULL;
|
||||||
char **p;
|
char **p;
|
||||||
|
@ -2942,7 +2943,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
_cleanup_free_ char *line = NULL;
|
_cleanup_free_ char *line = NULL;
|
||||||
PresetRule rule = {};
|
UnitFilePresetRule rule = {};
|
||||||
const char *parameter;
|
const char *parameter;
|
||||||
char *l;
|
char *l;
|
||||||
|
|
||||||
|
@ -2972,7 +2973,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rule = (PresetRule) {
|
rule = (UnitFilePresetRule) {
|
||||||
.pattern = unit_name,
|
.pattern = unit_name,
|
||||||
.action = PRESET_ENABLE,
|
.action = PRESET_ENABLE,
|
||||||
.instances = instances,
|
.instances = instances,
|
||||||
|
@ -2987,7 +2988,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rule = (PresetRule) {
|
rule = (UnitFilePresetRule) {
|
||||||
.pattern = pattern,
|
.pattern = pattern,
|
||||||
.action = PRESET_DISABLE,
|
.action = PRESET_DISABLE,
|
||||||
};
|
};
|
||||||
|
@ -3005,14 +3006,15 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps.initialized = true;
|
||||||
*presets = ps;
|
*presets = ps;
|
||||||
ps = (Presets){};
|
ps = (UnitFilePresets){};
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pattern_match_multiple_instances(
|
static int pattern_match_multiple_instances(
|
||||||
const PresetRule rule,
|
const UnitFilePresetRule rule,
|
||||||
const char *unit_name,
|
const char *unit_name,
|
||||||
char ***ret) {
|
char ***ret) {
|
||||||
|
|
||||||
|
@ -3066,17 +3068,17 @@ static int pattern_match_multiple_instances(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int query_presets(const char *name, const Presets presets, char ***instance_name_list) {
|
static int query_presets(const char *name, const UnitFilePresets *presets, char ***instance_name_list) {
|
||||||
PresetAction action = PRESET_UNKNOWN;
|
PresetAction action = PRESET_UNKNOWN;
|
||||||
size_t i;
|
size_t i;
|
||||||
char **s;
|
char **s;
|
||||||
if (!unit_name_is_valid(name, UNIT_NAME_ANY))
|
if (!unit_name_is_valid(name, UNIT_NAME_ANY))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
for (i = 0; i < presets.n_rules; i++)
|
for (i = 0; i < presets->n_rules; i++)
|
||||||
if (pattern_match_multiple_instances(presets.rules[i], name, instance_name_list) > 0 ||
|
if (pattern_match_multiple_instances(presets->rules[i], name, instance_name_list) > 0 ||
|
||||||
fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) {
|
fnmatch(presets->rules[i].pattern, name, FNM_NOESCAPE) == 0) {
|
||||||
action = presets.rules[i].action;
|
action = presets->rules[i].action;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3099,15 +3101,19 @@ static int query_presets(const char *name, const Presets presets, char ***instan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
|
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name, UnitFilePresets *cached) {
|
||||||
_cleanup_(presets_freep) Presets presets = {};
|
_cleanup_(unit_file_presets_freep) UnitFilePresets tmp = {};
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = read_presets(scope, root_dir, &presets);
|
if (!cached)
|
||||||
if (r < 0)
|
cached = &tmp;
|
||||||
return r;
|
if (!cached->initialized) {
|
||||||
|
r = read_presets(scope, root_dir, cached);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return query_presets(name, presets, NULL);
|
return query_presets(name, cached, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int execute_preset(
|
static int execute_preset(
|
||||||
|
@ -3162,7 +3168,7 @@ static int preset_prepare_one(
|
||||||
InstallContext *minus,
|
InstallContext *minus,
|
||||||
LookupPaths *paths,
|
LookupPaths *paths,
|
||||||
const char *name,
|
const char *name,
|
||||||
Presets presets,
|
const UnitFilePresets *presets,
|
||||||
UnitFileChange **changes,
|
UnitFileChange **changes,
|
||||||
size_t *n_changes) {
|
size_t *n_changes) {
|
||||||
|
|
||||||
|
@ -3221,7 +3227,7 @@ int unit_file_preset(
|
||||||
|
|
||||||
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
||||||
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
||||||
_cleanup_(presets_freep) Presets presets = {};
|
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
|
||||||
const char *config_path;
|
const char *config_path;
|
||||||
char **i;
|
char **i;
|
||||||
int r;
|
int r;
|
||||||
|
@ -3243,7 +3249,7 @@ int unit_file_preset(
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
STRV_FOREACH(i, files) {
|
STRV_FOREACH(i, files) {
|
||||||
r = preset_prepare_one(scope, &plus, &minus, &paths, *i, presets, changes, n_changes);
|
r = preset_prepare_one(scope, &plus, &minus, &paths, *i, &presets, changes, n_changes);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -3261,7 +3267,7 @@ int unit_file_preset_all(
|
||||||
|
|
||||||
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
||||||
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
||||||
_cleanup_(presets_freep) Presets presets = {};
|
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
|
||||||
const char *config_path = NULL;
|
const char *config_path = NULL;
|
||||||
char **i;
|
char **i;
|
||||||
int r;
|
int r;
|
||||||
|
@ -3305,7 +3311,7 @@ int unit_file_preset_all(
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* we don't pass changes[] in, because we want to handle errors on our own */
|
/* we don't pass changes[] in, because we want to handle errors on our own */
|
||||||
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, presets, NULL, 0);
|
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, &presets, NULL, 0);
|
||||||
if (r == -ERFKILL)
|
if (r == -ERFKILL)
|
||||||
r = unit_file_changes_add(changes, n_changes,
|
r = unit_file_changes_add(changes, n_changes,
|
||||||
UNIT_FILE_IS_MASKED, de->d_name, NULL);
|
UNIT_FILE_IS_MASKED, de->d_name, NULL);
|
||||||
|
@ -3344,7 +3350,7 @@ int unit_file_get_list(
|
||||||
char **patterns) {
|
char **patterns) {
|
||||||
|
|
||||||
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
_cleanup_(lookup_paths_free) LookupPaths paths = {};
|
||||||
char **i;
|
char **dirname;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(scope >= 0);
|
assert(scope >= 0);
|
||||||
|
@ -3355,16 +3361,16 @@ int unit_file_get_list(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
STRV_FOREACH(i, paths.search_path) {
|
STRV_FOREACH(dirname, paths.search_path) {
|
||||||
_cleanup_closedir_ DIR *d = NULL;
|
_cleanup_closedir_ DIR *d = NULL;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
|
|
||||||
d = opendir(*i);
|
d = opendir(*dirname);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
continue;
|
continue;
|
||||||
if (IN_SET(errno, ENOTDIR, EACCES)) {
|
if (IN_SET(errno, ENOTDIR, EACCES)) {
|
||||||
log_debug_errno(errno, "Failed to open \"%s\": %m", *i);
|
log_debug_errno(errno, "Failed to open \"%s\": %m", *dirname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3392,7 +3398,7 @@ int unit_file_get_list(
|
||||||
if (!f)
|
if (!f)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
f->path = path_make_absolute(de->d_name, *i);
|
f->path = path_make_absolute(de->d_name, *dirname);
|
||||||
if (!f->path)
|
if (!f->path)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -3416,34 +3422,35 @@ int unit_file_get_list(
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
|
static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
|
||||||
[UNIT_FILE_ENABLED] = "enabled",
|
[UNIT_FILE_ENABLED] = "enabled",
|
||||||
[UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
|
[UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
|
||||||
[UNIT_FILE_LINKED] = "linked",
|
[UNIT_FILE_LINKED] = "linked",
|
||||||
[UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
|
[UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
|
||||||
[UNIT_FILE_MASKED] = "masked",
|
[UNIT_FILE_ALIAS] = "alias",
|
||||||
[UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
|
[UNIT_FILE_MASKED] = "masked",
|
||||||
[UNIT_FILE_STATIC] = "static",
|
[UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
|
||||||
[UNIT_FILE_DISABLED] = "disabled",
|
[UNIT_FILE_STATIC] = "static",
|
||||||
[UNIT_FILE_INDIRECT] = "indirect",
|
[UNIT_FILE_DISABLED] = "disabled",
|
||||||
[UNIT_FILE_GENERATED] = "generated",
|
[UNIT_FILE_INDIRECT] = "indirect",
|
||||||
[UNIT_FILE_TRANSIENT] = "transient",
|
[UNIT_FILE_GENERATED] = "generated",
|
||||||
[UNIT_FILE_BAD] = "bad",
|
[UNIT_FILE_TRANSIENT] = "transient",
|
||||||
|
[UNIT_FILE_BAD] = "bad",
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
|
DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
|
||||||
|
|
||||||
static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
|
static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
|
||||||
[UNIT_FILE_SYMLINK] = "symlink",
|
[UNIT_FILE_SYMLINK] = "symlink",
|
||||||
[UNIT_FILE_UNLINK] = "unlink",
|
[UNIT_FILE_UNLINK] = "unlink",
|
||||||
[UNIT_FILE_IS_MASKED] = "masked",
|
[UNIT_FILE_IS_MASKED] = "masked",
|
||||||
[UNIT_FILE_IS_DANGLING] = "dangling",
|
[UNIT_FILE_IS_DANGLING] = "dangling",
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
|
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
|
||||||
|
|
||||||
static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
|
static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
|
||||||
[UNIT_FILE_PRESET_FULL] = "full",
|
[UNIT_FILE_PRESET_FULL] = "full",
|
||||||
[UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
|
[UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
|
||||||
[UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
|
[UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,16 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
|
||||||
|
|
||||||
int unit_file_verify_alias(const UnitFileInstallInfo *i, const char *dst, char **ret_dst);
|
int unit_file_verify_alias(const UnitFileInstallInfo *i, const char *dst, char **ret_dst);
|
||||||
|
|
||||||
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name);
|
typedef struct UnitFilePresetRule UnitFilePresetRule;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UnitFilePresetRule *rules;
|
||||||
|
size_t n_rules;
|
||||||
|
bool initialized;
|
||||||
|
} UnitFilePresets;
|
||||||
|
|
||||||
|
void unit_file_presets_freep(UnitFilePresets *p);
|
||||||
|
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name, UnitFilePresets *cached);
|
||||||
|
|
||||||
const char *unit_file_state_to_string(UnitFileState s) _const_;
|
const char *unit_file_state_to_string(UnitFileState s) _const_;
|
||||||
UnitFileState unit_file_state_from_string(const char *s) _pure_;
|
UnitFileState unit_file_state_from_string(const char *s) _pure_;
|
||||||
|
|
|
@ -320,7 +320,7 @@ int unit_file_build_name_map(
|
||||||
/* We don't explicitly check for alias loops here. unit_ids_map_get() which
|
/* We don't explicitly check for alias loops here. unit_ids_map_get() which
|
||||||
* limits the number of hops should be used to access the map. */
|
* limits the number of hops should be used to access the map. */
|
||||||
|
|
||||||
_cleanup_free_ char *target = NULL, *target_abs = NULL;
|
_cleanup_free_ char *target = NULL;
|
||||||
|
|
||||||
r = readlinkat_malloc(dirfd(d), de->d_name, &target);
|
r = readlinkat_malloc(dirfd(d), de->d_name, &target);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -329,8 +329,9 @@ int unit_file_build_name_map(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path_is_absolute(target)) {
|
const bool is_abs = path_is_absolute(target);
|
||||||
target_abs = path_join(*dir, target);
|
if (lp->root_dir || !is_abs) {
|
||||||
|
char *target_abs = path_join(is_abs ? lp->root_dir : *dir, target);
|
||||||
if (!target_abs)
|
if (!target_abs)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ enum UnitFileState {
|
||||||
UNIT_FILE_ENABLED_RUNTIME,
|
UNIT_FILE_ENABLED_RUNTIME,
|
||||||
UNIT_FILE_LINKED,
|
UNIT_FILE_LINKED,
|
||||||
UNIT_FILE_LINKED_RUNTIME,
|
UNIT_FILE_LINKED_RUNTIME,
|
||||||
|
UNIT_FILE_ALIAS,
|
||||||
UNIT_FILE_MASKED,
|
UNIT_FILE_MASKED,
|
||||||
UNIT_FILE_MASKED_RUNTIME,
|
UNIT_FILE_MASKED_RUNTIME,
|
||||||
UNIT_FILE_STATIC,
|
UNIT_FILE_STATIC,
|
||||||
|
|
|
@ -45,10 +45,19 @@ bool running_in_chroot_or_offline(void) {
|
||||||
return r > 0;
|
return r > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Verb* verbs_find_verb(const char *name, const Verb verbs[]) {
|
||||||
|
for (size_t i = 0; verbs[i].dispatch; i++)
|
||||||
|
if (streq_ptr(name, verbs[i].verb) ||
|
||||||
|
(!name && FLAGS_SET(verbs[i].flags, VERB_DEFAULT)))
|
||||||
|
return &verbs[i];
|
||||||
|
|
||||||
|
/* At the end of the list? */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
|
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
|
||||||
const Verb *verb;
|
const Verb *verb;
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned i;
|
|
||||||
int left;
|
int left;
|
||||||
|
|
||||||
assert(verbs);
|
assert(verbs);
|
||||||
|
@ -62,31 +71,16 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
|
||||||
optind = 0;
|
optind = 0;
|
||||||
name = argv[0];
|
name = argv[0];
|
||||||
|
|
||||||
for (i = 0;; i++) {
|
verb = verbs_find_verb(name, verbs);
|
||||||
bool found;
|
if (!verb) {
|
||||||
|
|
||||||
/* At the end of the list? */
|
|
||||||
if (!verbs[i].dispatch) {
|
|
||||||
if (name)
|
|
||||||
log_error("Unknown operation %s.", name);
|
|
||||||
else
|
|
||||||
log_error("Requires operation parameter.");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
found = streq(name, verbs[i].verb);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Unknown command verb %s.", name);
|
||||||
else
|
else
|
||||||
found = verbs[i].flags & VERB_DEFAULT;
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Command verb required.");
|
||||||
if (found) {
|
|
||||||
verb = &verbs[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(verb);
|
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
left = 1;
|
left = 1;
|
||||||
|
|
||||||
|
@ -101,10 +95,7 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
|
||||||
"Too many arguments.");
|
"Too many arguments.");
|
||||||
|
|
||||||
if ((verb->flags & VERB_ONLINE_ONLY) && running_in_chroot_or_offline()) {
|
if ((verb->flags & VERB_ONLINE_ONLY) && running_in_chroot_or_offline()) {
|
||||||
if (name)
|
log_info("Running in chroot, ignoring command '%s'", name ?: verb->verb);
|
||||||
log_info("Running in chroot, ignoring request: %s", name);
|
|
||||||
else
|
|
||||||
log_info("Running in chroot, ignoring request.");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#define VERB_ANY ((unsigned) -1)
|
#define VERB_ANY ((unsigned) -1)
|
||||||
|
|
||||||
typedef enum VerbFlags {
|
typedef enum VerbFlags {
|
||||||
VERB_DEFAULT = 1 << 0,
|
VERB_DEFAULT = 1 << 0, /* The verb to run if no verb is specified */
|
||||||
VERB_ONLINE_ONLY = 1 << 1,
|
VERB_ONLINE_ONLY = 1 << 1, /* Just do nothing when running in chroot or offline */
|
||||||
} VerbFlags;
|
} VerbFlags;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -19,4 +19,5 @@ typedef struct {
|
||||||
|
|
||||||
bool running_in_chroot_or_offline(void);
|
bool running_in_chroot_or_offline(void);
|
||||||
|
|
||||||
|
const Verb* verbs_find_verb(const char *name, const Verb verbs[]);
|
||||||
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata);
|
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata);
|
||||||
|
|
|
@ -1456,9 +1456,18 @@ static bool output_show_unit_file(const UnitFileList *u, char **states, char **p
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool show_preset_for_state(UnitFileState state) {
|
||||||
|
/* Don't show preset state in those unit file states, it'll only confuse users. */
|
||||||
|
return !IN_SET(state,
|
||||||
|
UNIT_FILE_ALIAS,
|
||||||
|
UNIT_FILE_STATIC,
|
||||||
|
UNIT_FILE_GENERATED,
|
||||||
|
UNIT_FILE_TRANSIENT);
|
||||||
|
}
|
||||||
|
|
||||||
static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||||
_cleanup_(table_unrefp) Table *table = NULL;
|
_cleanup_(table_unrefp) Table *table = NULL;
|
||||||
const UnitFileList *u;
|
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
table = table_new("unit file", "state", "vendor preset");
|
table = table_new("unit file", "state", "vendor preset");
|
||||||
|
@ -1469,9 +1478,8 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||||
if (arg_full)
|
if (arg_full)
|
||||||
table_set_width(table, 0);
|
table_set_width(table, 0);
|
||||||
|
|
||||||
for (u = units; u < units + c; u++) {
|
for (const UnitFileList *u = units; u < units + c; u++) {
|
||||||
const char *on_underline = NULL, *on_unit_color = NULL, *id;
|
const char *on_underline = NULL, *on_unit_color = NULL, *id;
|
||||||
const char *on_preset_color = NULL, *unit_preset_str;
|
|
||||||
bool underline;
|
bool underline;
|
||||||
|
|
||||||
underline = u + 1 < units + c &&
|
underline = u + 1 < units + c &&
|
||||||
|
@ -1486,32 +1494,44 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
|
||||||
UNIT_FILE_DISABLED,
|
UNIT_FILE_DISABLED,
|
||||||
UNIT_FILE_BAD))
|
UNIT_FILE_BAD))
|
||||||
on_unit_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
on_unit_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||||
else if (u->state == UNIT_FILE_ENABLED)
|
else if (IN_SET(u->state,
|
||||||
|
UNIT_FILE_ENABLED,
|
||||||
|
UNIT_FILE_ALIAS))
|
||||||
on_unit_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
on_unit_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
||||||
else
|
else
|
||||||
on_unit_color = on_underline;
|
on_unit_color = on_underline;
|
||||||
|
|
||||||
id = basename(u->path);
|
id = basename(u->path);
|
||||||
|
|
||||||
r = unit_file_query_preset(arg_scope, NULL, id);
|
|
||||||
if (r < 0) {
|
|
||||||
unit_preset_str = "n/a";
|
|
||||||
on_preset_color = underline ? on_underline : ansi_normal();
|
|
||||||
} else if (r == 0) {
|
|
||||||
unit_preset_str = "disabled";
|
|
||||||
on_preset_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
|
||||||
} else {
|
|
||||||
unit_preset_str = "enabled";
|
|
||||||
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
|
||||||
}
|
|
||||||
|
|
||||||
r = table_add_many(table,
|
r = table_add_many(table,
|
||||||
TABLE_STRING, id,
|
TABLE_STRING, id,
|
||||||
TABLE_SET_COLOR, strempty(on_underline),
|
TABLE_SET_COLOR, strempty(on_underline),
|
||||||
TABLE_STRING, unit_file_state_to_string(u->state),
|
TABLE_STRING, unit_file_state_to_string(u->state),
|
||||||
TABLE_SET_COLOR, strempty(on_unit_color),
|
TABLE_SET_COLOR, strempty(on_unit_color));
|
||||||
TABLE_STRING, unit_preset_str,
|
if (r < 0)
|
||||||
TABLE_SET_COLOR, strempty(on_preset_color));
|
return table_log_add_error(r);
|
||||||
|
|
||||||
|
if (show_preset_for_state(u->state)) {
|
||||||
|
const char *unit_preset_str, *on_preset_color;
|
||||||
|
|
||||||
|
r = unit_file_query_preset(arg_scope, arg_root, id, &presets);
|
||||||
|
if (r < 0) {
|
||||||
|
unit_preset_str = "n/a";
|
||||||
|
on_preset_color = underline ? on_underline : ansi_normal();
|
||||||
|
} else if (r == 0) {
|
||||||
|
unit_preset_str = "disabled";
|
||||||
|
on_preset_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
|
||||||
|
} else {
|
||||||
|
unit_preset_str = "enabled";
|
||||||
|
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
|
||||||
|
}
|
||||||
|
|
||||||
|
r = table_add_many(table,
|
||||||
|
TABLE_STRING, unit_preset_str,
|
||||||
|
TABLE_SET_COLOR, strempty(on_preset_color));
|
||||||
|
} else
|
||||||
|
r = table_add_many(table, TABLE_EMPTY);
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return table_log_add_error(r);
|
return table_log_add_error(r);
|
||||||
}
|
}
|
||||||
|
@ -4246,14 +4266,18 @@ static void print_status_info(
|
||||||
if (!isempty(i->load_error))
|
if (!isempty(i->load_error))
|
||||||
printf(" Loaded: %s%s%s (Reason: %s)\n",
|
printf(" Loaded: %s%s%s (Reason: %s)\n",
|
||||||
on, strna(i->load_state), off, i->load_error);
|
on, strna(i->load_state), off, i->load_error);
|
||||||
else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset) &&
|
else if (path && !isempty(i->unit_file_state)) {
|
||||||
!STR_IN_SET(i->unit_file_state, "generated", "transient"))
|
bool show_preset = !isempty(i->unit_file_preset) &&
|
||||||
printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
|
show_preset_for_state(unit_file_state_from_string(i->unit_file_state));
|
||||||
on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
|
|
||||||
else if (path && !isempty(i->unit_file_state))
|
printf(" Loaded: %s%s%s (%s; %s%s%s)\n",
|
||||||
printf(" Loaded: %s%s%s (%s; %s)\n",
|
on, strna(i->load_state), off,
|
||||||
on, strna(i->load_state), off, path, i->unit_file_state);
|
path,
|
||||||
else if (path)
|
i->unit_file_state,
|
||||||
|
show_preset ? "; vendor preset: " : "",
|
||||||
|
show_preset ? i->unit_file_preset : "");
|
||||||
|
|
||||||
|
} else if (path)
|
||||||
printf(" Loaded: %s%s%s (%s)\n",
|
printf(" Loaded: %s%s%s (%s)\n",
|
||||||
on, strna(i->load_state), off, path);
|
on, strna(i->load_state), off, path);
|
||||||
else
|
else
|
||||||
|
@ -5892,7 +5916,8 @@ static int show(int argc, char *argv[], void *userdata) {
|
||||||
|
|
||||||
if (show_mode == SYSTEMCTL_SHOW_HELP && argc <= 1)
|
if (show_mode == SYSTEMCTL_SHOW_HELP && argc <= 1)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"This command expects one or more unit names. Did you mean --help?");
|
"'help' command expects one or more unit names.\n"
|
||||||
|
"(Alternatively, help for systemctl itself may be shown with --help)");
|
||||||
|
|
||||||
r = acquire_bus(BUS_MANAGER, &bus);
|
r = acquire_bus(BUS_MANAGER, &bus);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -7367,6 +7392,7 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
|
||||||
UNIT_FILE_ENABLED,
|
UNIT_FILE_ENABLED,
|
||||||
UNIT_FILE_ENABLED_RUNTIME,
|
UNIT_FILE_ENABLED_RUNTIME,
|
||||||
UNIT_FILE_STATIC,
|
UNIT_FILE_STATIC,
|
||||||
|
UNIT_FILE_ALIAS,
|
||||||
UNIT_FILE_INDIRECT,
|
UNIT_FILE_INDIRECT,
|
||||||
UNIT_FILE_GENERATED))
|
UNIT_FILE_GENERATED))
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
@ -9211,9 +9237,9 @@ static int systemctl_main(int argc, char *argv[]) {
|
||||||
{ "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
|
{ "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
|
||||||
{ "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
|
{ "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
|
||||||
{ "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
|
{ "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
|
||||||
{ "log-level", VERB_ANY, 2, 0, log_level },
|
{ "log-level", VERB_ANY, 2, VERB_ONLINE_ONLY, log_level },
|
||||||
{ "log-target", VERB_ANY, 2, 0, log_target },
|
{ "log-target", VERB_ANY, 2, VERB_ONLINE_ONLY, log_target },
|
||||||
{ "service-watchdogs", VERB_ANY, 2, 0, service_watchdogs },
|
{ "service-watchdogs", VERB_ANY, 2, VERB_ONLINE_ONLY, service_watchdogs },
|
||||||
{ "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment },
|
{ "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment },
|
||||||
{ "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
|
{ "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
|
||||||
{ "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
|
{ "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
|
||||||
|
@ -9253,6 +9279,12 @@ static int systemctl_main(int argc, char *argv[]) {
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Verb *verb = verbs_find_verb(argv[optind], verbs);
|
||||||
|
if (verb && (verb->flags & VERB_ONLINE_ONLY) && arg_root)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Verb '%s' cannot be used with --root=.",
|
||||||
|
argv[optind] ?: verb->verb);
|
||||||
|
|
||||||
return dispatch_verb(argc, argv, verbs, NULL);
|
return dispatch_verb(argc, argv, verbs, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,20 +36,20 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||||
assert_se(symlink("a.service", p) >= 0);
|
assert_se(symlink("a.service", p) >= 0);
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) >= 0);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) >= 0);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
p = strjoina(root, "/usr/lib/systemd/system/c.service");
|
p = strjoina(root, "/usr/lib/systemd/system/c.service");
|
||||||
assert_se(symlink("/usr/lib/systemd/system/a.service", p) >= 0);
|
assert_se(symlink("/usr/lib/systemd/system/a.service", p) >= 0);
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) >= 0);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) >= 0);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
p = strjoina(root, "/usr/lib/systemd/system/d.service");
|
p = strjoina(root, "/usr/lib/systemd/system/d.service");
|
||||||
assert_se(symlink("c.service", p) >= 0);
|
assert_se(symlink("c.service", p) >= 0);
|
||||||
|
|
||||||
/* This one is interesting, as d follows a relative, then an absolute symlink */
|
/* This one is interesting, as d follows a relative, then an absolute symlink */
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) >= 0);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) >= 0);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
||||||
assert_se(n_changes == 1);
|
assert_se(n_changes == 1);
|
||||||
|
@ -89,9 +89,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||||
changes = NULL; n_changes = 0;
|
changes = NULL; n_changes = 0;
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
/* Enabling it again should succeed but be a NOP */
|
/* Enabling it again should succeed but be a NOP */
|
||||||
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
||||||
|
@ -108,9 +108,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||||
changes = NULL; n_changes = 0;
|
changes = NULL; n_changes = 0;
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
/* Disabling a disabled unit must succeed but be a NOP */
|
/* Disabling a disabled unit must succeed but be a NOP */
|
||||||
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
|
||||||
|
@ -129,9 +129,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||||
changes = NULL; n_changes = 0;
|
changes = NULL; n_changes = 0;
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
/* Let's try to reenable */
|
/* Let's try to reenable */
|
||||||
|
|
||||||
|
@ -147,9 +147,9 @@ static void test_basic_mask_and_enable(const char *root) {
|
||||||
changes = NULL; n_changes = 0;
|
changes = NULL; n_changes = 0;
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_linked_units(const char *root) {
|
static void test_linked_units(const char *root) {
|
||||||
|
@ -386,7 +386,7 @@ static void test_template_enable(const char *root) {
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ static void test_template_enable(const char *root) {
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
|
|
||||||
|
@ -418,7 +418,7 @@ static void test_template_enable(const char *root) {
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ static void test_template_enable(const char *root) {
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
|
@ -469,7 +469,7 @@ static void test_template_enable(const char *root) {
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
|
@ -500,7 +500,7 @@ static void test_indirect(const char *root) {
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
|
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
|
||||||
assert_se(n_changes == 1);
|
assert_se(n_changes == 1);
|
||||||
|
@ -513,7 +513,7 @@ static void test_indirect(const char *root) {
|
||||||
|
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
|
||||||
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
|
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
|
||||||
|
|
||||||
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
|
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
|
||||||
assert_se(n_changes == 1);
|
assert_se(n_changes == 1);
|
||||||
|
@ -624,7 +624,7 @@ static void test_preset_and_list(const char *root) {
|
||||||
got_no = true;
|
got_no = true;
|
||||||
assert_se(fl->state == UNIT_FILE_DISABLED);
|
assert_se(fl->state == UNIT_FILE_DISABLED);
|
||||||
} else
|
} else
|
||||||
assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT));
|
assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT, UNIT_FILE_ALIAS));
|
||||||
}
|
}
|
||||||
|
|
||||||
unit_file_list_free(h);
|
unit_file_list_free(h);
|
||||||
|
|
Loading…
Reference in New Issue