1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-11 09:18:07 +03:00

Merge pull request #6892 from keszybz/enablement-work

Fix various issues with enabled/disabled units
This commit is contained in:
Lennart Poettering 2017-09-23 12:44:49 +02:00 committed by GitHub
commit b887cfa652
8 changed files with 162 additions and 83 deletions

View File

@ -1245,7 +1245,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<tbody> <tbody>
<row> <row>
<entry><literal>enabled</literal></entry> <entry><literal>enabled</literal></entry>
<entry morerows='1'>Enabled via <filename>.wants/</filename>, <filename>.requires/</filename> or alias symlinks (permanently in <filename>/etc/systemd/system/</filename>, or transiently in <filename>/run/systemd/system/</filename>).</entry> <entry morerows='1'>Enabled via <filename>.wants/</filename>, <filename>.requires/</filename> or <varname>Alias=</varname> symlinks (permanently in <filename>/etc/systemd/system/</filename>, or transiently in <filename>/run/systemd/system/</filename>).</entry>
<entry morerows='1'>0</entry> <entry morerows='1'>0</entry>
</row> </row>
<row> <row>
@ -1274,7 +1274,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
</row> </row>
<row> <row>
<entry><literal>indirect</literal></entry> <entry><literal>indirect</literal></entry>
<entry>The unit file itself is not enabled, but it has a non-empty <varname>Also=</varname> setting in the <literal>[Install]</literal> unit file section, listing other unit files that might be enabled.</entry> <entry>The unit file itself is not enabled, but it has a non-empty <varname>Also=</varname> setting in the <literal>[Install]</literal> unit file section, listing other unit files that might be enabled, or it has an alias under a different name through a symlink that is not specified in Also=. For template unit file, an instance different than the one specified in <varname>DefaultInstance=</varname> is enabled.</entry>
<entry>0</entry> <entry>0</entry>
</row> </row>
<row> <row>

View File

@ -104,13 +104,10 @@
<term><command>status</command></term> <term><command>status</command></term>
<listitem><para>Show current settings of the system clock and <listitem><para>Show current settings of the system clock and
RTC, including whether network time synchronization is RTC, including whether network time synchronization through
on. Note that whether network time synchronization is on <filename>systemd-timesyncd.service</filename> is active.
simply reflects whether the Even if is off, a different service might still synchronize the
<filename>systemd-timesyncd.service</filename> unit is clock with the network.</para></listitem>
enabled. Even if this command shows the status as off, a
different service might still synchronize the clock with the
network.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -206,13 +203,13 @@
<title>Examples</title> <title>Examples</title>
<para>Show current settings: <para>Show current settings:
<programlisting>$ timedatectl <programlisting>$ timedatectl
Local time: Di 2015-04-07 16:26:56 CEST Local time: Thu 2017-09-21 16:08:56 CEST
Universal time: Di 2015-04-07 14:26:56 UTC Universal time: Thu 2017-09-21 14:08:56 UTC
RTC time: Di 2015-04-07 14:26:56 RTC time: Thu 2017-09-21 14:08:56
Time zone: Europe/Berlin (CEST, +0200) Time zone: Europe/Warsaw (CEST, +0200)
Network time on: yes System clock synchronized: yes
NTP synchronized: yes systemd-timesyncd.service active: yes
RTC in local TZ: no</programlisting> RTC in local TZ: no</programlisting>
</para> </para>
<para>Enable network time synchronization: <para>Enable network time synchronization:

View File

@ -83,6 +83,20 @@ typedef struct {
size_t n_rules; size_t n_rules;
} Presets; } Presets;
static inline bool unit_file_install_info_has_rules(UnitFileInstallInfo *i) {
assert(i);
return !strv_isempty(i->aliases) ||
!strv_isempty(i->wanted_by) ||
!strv_isempty(i->required_by);
}
static inline bool unit_file_install_info_has_also(UnitFileInstallInfo *i) {
assert(i);
return !strv_isempty(i->also);
}
static inline void presets_freep(Presets *p) { static inline void presets_freep(Presets *p) {
size_t i; size_t i;
@ -685,9 +699,35 @@ static int remove_marked_symlinks(
return r; return r;
} }
static bool is_symlink_with_known_name(const UnitFileInstallInfo *i, const char *name) {
int r;
if (streq(name, i->name))
return true;
if (strv_contains(i->aliases, name))
return true;
/* Look for template symlink matching DefaultInstance */
if (i->default_instance && unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE)) {
_cleanup_free_ char *s = NULL;
r = unit_name_replace_instance(i->name, i->default_instance, &s);
if (r < 0) {
if (r != -EINVAL)
return r;
} else if (streq(name, s))
return true;
}
return false;
}
static int find_symlinks_fd( static int find_symlinks_fd(
const char *root_dir, const char *root_dir,
const char *name, UnitFileInstallInfo *i,
bool match_aliases,
int fd, int fd,
const char *path, const char *path,
const char *config_path, const char *config_path,
@ -697,7 +737,7 @@ static int find_symlinks_fd(
struct dirent *de; struct dirent *de;
int r = 0; int r = 0;
assert(name); assert(i);
assert(fd >= 0); assert(fd >= 0);
assert(path); assert(path);
assert(config_path); assert(config_path);
@ -734,7 +774,8 @@ static int find_symlinks_fd(
} }
/* This will close nfd, regardless whether it succeeds or not */ /* This will close nfd, regardless whether it succeeds or not */
q = find_symlinks_fd(root_dir, name, nfd, p, config_path, same_name_link); q = find_symlinks_fd(root_dir, i, match_aliases, nfd,
p, config_path, same_name_link);
if (q > 0) if (q > 0)
return 1; return 1;
if (r == 0) if (r == 0)
@ -774,24 +815,24 @@ static int find_symlinks_fd(
/* Check if the symlink itself matches what we /* Check if the symlink itself matches what we
* are looking for */ * are looking for */
if (path_is_absolute(name)) if (path_is_absolute(i->name))
found_path = path_equal(p, name); found_path = path_equal(p, i->name);
else else
found_path = streq(de->d_name, name); found_path = streq(de->d_name, i->name);
/* Check if what the symlink points to /* Check if what the symlink points to
* matches what we are looking for */ * matches what we are looking for */
if (path_is_absolute(name)) if (path_is_absolute(i->name))
found_dest = path_equal(dest, name); found_dest = path_equal(dest, i->name);
else else
found_dest = streq(basename(dest), name); found_dest = streq(basename(dest), i->name);
if (found_path && found_dest) { if (found_path && found_dest) {
_cleanup_free_ char *t = NULL; _cleanup_free_ char *t = NULL;
/* Filter out same name links in the main /* Filter out same name links in the main
* config path */ * config path */
t = path_make_absolute(name, config_path); t = path_make_absolute(i->name, config_path);
if (!t) if (!t)
return -ENOMEM; return -ENOMEM;
@ -800,8 +841,18 @@ static int find_symlinks_fd(
if (b) if (b)
*same_name_link = true; *same_name_link = true;
else if (found_path || found_dest) else if (found_path || found_dest) {
return 1; if (!match_aliases)
return 1;
/* Check if symlink name is in the set of names used by [Install] */
q = is_symlink_with_known_name(i, de->d_name);
log_info("is_symlink_with_known_name(%s, %s) → %d", i->name, de->d_name, q);
if (q < 0)
return q;
if (q > 0)
return 1;
}
} }
} }
@ -810,13 +861,14 @@ static int find_symlinks_fd(
static int find_symlinks( static int find_symlinks(
const char *root_dir, const char *root_dir,
const char *name, UnitFileInstallInfo *i,
bool match_name,
const char *config_path, const char *config_path,
bool *same_name_link) { bool *same_name_link) {
int fd; int fd;
assert(name); assert(i);
assert(config_path); assert(config_path);
assert(same_name_link); assert(same_name_link);
@ -828,12 +880,15 @@ static int find_symlinks(
} }
/* This takes possession of fd and closes it */ /* This takes possession of fd and closes it */
return find_symlinks_fd(root_dir, name, fd, config_path, config_path, same_name_link); return find_symlinks_fd(root_dir, i, match_name, fd,
config_path, config_path, same_name_link);
} }
static int find_symlinks_in_scope( static int find_symlinks_in_scope(
UnitFileScope scope,
const LookupPaths *paths, const LookupPaths *paths,
const char *name, UnitFileInstallInfo *i,
bool match_name,
UnitFileState *state) { UnitFileState *state) {
bool same_name_link_runtime = false, same_name_link_config = false; bool same_name_link_runtime = false, same_name_link_config = false;
@ -842,12 +897,12 @@ static int find_symlinks_in_scope(
int r; int r;
assert(paths); assert(paths);
assert(name); assert(i);
STRV_FOREACH(p, paths->search_path) { STRV_FOREACH(p, paths->search_path) {
bool same_name_link = false; bool same_name_link = false;
r = find_symlinks(paths->root_dir, name, *p, &same_name_link); r = find_symlinks(paths->root_dir, i, match_name, *p, &same_name_link);
if (r < 0) if (r < 0)
return r; return r;
if (r > 0) { if (r > 0) {
@ -862,6 +917,12 @@ static int find_symlinks_in_scope(
return 1; return 1;
} }
/* look for globally enablement of user units */
if (scope == UNIT_FILE_USER && path_is_user_config_dir(*p)) {
*state = UNIT_FILE_ENABLED;
return 1;
}
r = path_is_runtime(paths, *p, false); r = path_is_runtime(paths, *p, false);
if (r < 0) if (r < 0)
return r; return r;
@ -896,7 +957,7 @@ static int find_symlinks_in_scope(
* outside of runtime and configuration directory, then we consider it statically enabled. Note we do that only * outside of runtime and configuration directory, then we consider it statically enabled. Note we do that only
* for instance, not for regular names, as those are merely aliases, while instances explicitly instantiate * for instance, not for regular names, as those are merely aliases, while instances explicitly instantiate
* something, and hence are a much stronger concept. */ * something, and hence are a much stronger concept. */
if (enabled_at_all && unit_name_is_valid(name, UNIT_NAME_INSTANCE)) { if (enabled_at_all && unit_name_is_valid(i->name, UNIT_NAME_INSTANCE)) {
*state = UNIT_FILE_STATIC; *state = UNIT_FILE_STATIC;
return 1; return 1;
} }
@ -2589,13 +2650,26 @@ static int unit_file_lookup_state(
break; break;
} }
r = find_symlinks_in_scope(paths, i->name, &state); /* Check if any of the Alias= symlinks have been created.
* We ignore other aliases, and only check those that would
* be created by systemctl enable for this unit. */
r = find_symlinks_in_scope(scope, paths, i, true, &state);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0) { if (r > 0)
if (UNIT_FILE_INSTALL_INFO_HAS_RULES(i)) break;
/* Check if the file is known under other names. If it is,
* it might be in use. Report that as UNIT_FILE_INDIRECT. */
r = find_symlinks_in_scope(scope, paths, i, false, &state);
if (r < 0)
return r;
if (r > 0)
state = UNIT_FILE_INDIRECT;
else {
if (unit_file_install_info_has_rules(i))
state = UNIT_FILE_DISABLED; state = UNIT_FILE_DISABLED;
else if (UNIT_FILE_INSTALL_INFO_HAS_ALSO(i)) else if (unit_file_install_info_has_also(i))
state = UNIT_FILE_INDIRECT; state = UNIT_FILE_INDIRECT;
else else
state = UNIT_FILE_STATIC; state = UNIT_FILE_STATIC;

View File

@ -132,20 +132,6 @@ struct UnitFileInstallInfo {
bool auxiliary; bool auxiliary;
}; };
static inline bool UNIT_FILE_INSTALL_INFO_HAS_RULES(UnitFileInstallInfo *i) {
assert(i);
return !strv_isempty(i->aliases) ||
!strv_isempty(i->wanted_by) ||
!strv_isempty(i->required_by);
}
static inline bool UNIT_FILE_INSTALL_INFO_HAS_ALSO(UnitFileInstallInfo *i) {
assert(i);
return !strv_isempty(i->also);
}
bool unit_type_may_alias(UnitType type) _const_; bool unit_type_may_alias(UnitType type) _const_;
bool unit_type_may_template(UnitType type) _const_; bool unit_type_may_template(UnitType type) _const_;

View File

@ -115,6 +115,21 @@ static int user_data_dir(char **ret, const char *suffix) {
return 1; return 1;
} }
static const char* const user_data_unit_paths[] = {
"/usr/local/lib/systemd/user",
"/usr/local/share/systemd/user",
USER_DATA_UNIT_PATH,
"/usr/lib/systemd/user",
"/usr/share/systemd/user",
NULL
};
static const char* const user_config_unit_paths[] = {
USER_CONFIG_UNIT_PATH,
"/etc/systemd/user",
NULL
};
static char** user_dirs( static char** user_dirs(
const char *persistent_config, const char *persistent_config,
const char *runtime_config, const char *runtime_config,
@ -125,21 +140,6 @@ static char** user_dirs(
const char *persistent_control, const char *persistent_control,
const char *runtime_control) { const char *runtime_control) {
const char * const config_unit_paths[] = {
USER_CONFIG_UNIT_PATH,
"/etc/systemd/user",
NULL
};
const char * const data_unit_paths[] = {
"/usr/local/lib/systemd/user",
"/usr/local/share/systemd/user",
USER_DATA_UNIT_PATH,
"/usr/lib/systemd/user",
"/usr/share/systemd/user",
NULL
};
_cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL; _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
_cleanup_free_ char *data_home = NULL; _cleanup_free_ char *data_home = NULL;
_cleanup_strv_free_ char **res = NULL; _cleanup_strv_free_ char **res = NULL;
@ -196,7 +196,7 @@ static char** user_dirs(
if (strv_extend(&res, persistent_config) < 0) if (strv_extend(&res, persistent_config) < 0)
return NULL; return NULL;
if (strv_extend_strv(&res, (char**) config_unit_paths, false) < 0) if (strv_extend_strv(&res, (char**) user_config_unit_paths, false) < 0)
return NULL; return NULL;
if (strv_extend(&res, runtime_config) < 0) if (strv_extend(&res, runtime_config) < 0)
@ -211,7 +211,7 @@ static char** user_dirs(
if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0) if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
return NULL; return NULL;
if (strv_extend_strv(&res, (char**) data_unit_paths, false) < 0) if (strv_extend_strv(&res, (char**) user_data_unit_paths, false) < 0)
return NULL; return NULL;
if (strv_extend(&res, generator_late) < 0) if (strv_extend(&res, generator_late) < 0)
@ -226,6 +226,18 @@ static char** user_dirs(
return tmp; return tmp;
} }
bool path_is_user_data_dir(const char *path) {
assert(path);
return strv_contains((char**) user_data_unit_paths, path);
}
bool path_is_user_config_dir(const char *path) {
assert(path);
return strv_contains((char**) user_config_unit_paths, path);
}
static int acquire_generator_dirs( static int acquire_generator_dirs(
UnitFileScope scope, UnitFileScope scope,
const char *tempdir, const char *tempdir,

View File

@ -67,6 +67,8 @@ struct LookupPaths {
}; };
int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir); int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir);
bool path_is_user_data_dir(const char *path);
bool path_is_user_config_dir(const char *path);
int lookup_paths_reduce(LookupPaths *p); int lookup_paths_reduce(LookupPaths *p);

View File

@ -381,6 +381,8 @@ static void test_template_enable(const char *root) {
UnitFileState state; UnitFileState state;
const char *p; const char *p;
log_info("== %s ==", __func__);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) == -ENOENT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) == -ENOENT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) == -ENOENT);
@ -402,6 +404,8 @@ static void test_template_enable(const char *root) {
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);
log_info("== %s with template@.service enabled ==", __func__);
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type == UNIT_FILE_SYMLINK);
@ -432,6 +436,8 @@ static void test_template_enable(const char *root) {
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);
log_info("== %s with template@foo.service enabled ==", __func__);
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
@ -440,7 +446,7 @@ static void test_template_enable(const char *root) {
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0; changes = NULL; n_changes = 0;
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_INDIRECT);
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_ENABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.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_ENABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
@ -463,6 +469,8 @@ static void test_template_enable(const char *root) {
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);
log_info("== %s with template-symlink@quux.service enabled ==", __func__);
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
@ -471,11 +479,11 @@ static void test_template_enable(const char *root) {
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0; changes = NULL; n_changes = 0;
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_INDIRECT);
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_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@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);

View File

@ -103,13 +103,13 @@ static void print_status_info(const StatusInfo *i) {
if (have_time) { if (have_time) {
xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)); xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
printf(" Local time: %.*s\n", (int) sizeof(a), a); printf(" Local time: %.*s\n", (int) sizeof(a), a);
xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm)); xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
printf(" Universal time: %.*s\n", (int) sizeof(a), a); printf(" Universal time: %.*s\n", (int) sizeof(a), a);
} else { } else {
printf(" Local time: %s\n", "n/a"); printf(" Local time: %s\n", "n/a");
printf(" Universal time: %s\n", "n/a"); printf(" Universal time: %s\n", "n/a");
} }
if (i->rtc_time > 0) { if (i->rtc_time > 0) {
@ -117,9 +117,9 @@ static void print_status_info(const StatusInfo *i) {
rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC); rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm)); xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
printf(" RTC time: %.*s\n", (int) sizeof(a), a); printf(" RTC time: %.*s\n", (int) sizeof(a), a);
} else } else
printf(" RTC time: %s\n", "n/a"); printf(" RTC time: %s\n", "n/a");
if (have_time) if (have_time)
xstrftime(a, "%Z, %z", localtime_r(&sec, &tm)); xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));
@ -134,10 +134,10 @@ static void print_status_info(const StatusInfo *i) {
else else
tzset(); tzset();
printf(" Time zone: %s (%.*s)\n" printf(" Time zone: %s (%.*s)\n"
" Network time on: %s\n" " System clock synchronized: %s\n"
"NTP synchronized: %s\n" "systemd-timesyncd.service active: %s\n"
" RTC in local TZ: %s\n", " RTC in local TZ: %s\n",
strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a", strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a", i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
yes_no(i->ntp_synced), yes_no(i->ntp_synced),