[systemd-devel] [ systemd-devel ] [PATCH] Fix Bug 72611 (systemctl is-enabled scales poorly with many units
david at davidstrauss.net
david at davidstrauss.net
Tue Apr 15 12:12:50 PDT 2014
From: Rami Rosen <ramirose at gmail.com>
This patch fixes Bug 72611 (systemctl is-enabled scales poorly with many units)
by using a hashmap for enabled/disabled services instead. The hashmap is a
member of the manager and is initialized by a new method, build_enabled_cache(),
which is called from the manager_startup() method.
---
Makefile.am | 3 +-
src/core/dbus-manager.c | 54 ++++++++++------
src/core/manager.c | 9 ++-
src/core/manager.h | 1 +
src/core/unit.c | 2 +-
src/shared/install.c | 154 +++++++++++++++++++++++++++++++++++++++++++++-
src/shared/install.h | 6 +-
src/systemctl/systemctl.c | 2 +-
src/test/test-install.c | 51 +++++++++------
9 files changed, 235 insertions(+), 47 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 5d84605..fa294f1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1520,7 +1520,8 @@ test_install_LDADD = \
libsystemd-units.la \
libsystemd-label.la \
libsystemd-shared.la \
- libsystemd-internal.la
+ libsystemd-internal.la \
+ libsystemd-core.la
test_watchdog_SOURCES = \
src/test/test-watchdog.c
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 135d314..7f196dd 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1298,7 +1298,6 @@ static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *us
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
Manager *m = userdata;
UnitFileList *item;
- Hashmap *h;
Iterator i;
int r;
@@ -1314,27 +1313,17 @@ static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *us
if (r < 0)
return r;
- h = hashmap_new(string_hash_func, string_compare_func);
- if (!h)
- return -ENOMEM;
-
- r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
- if (r < 0)
- goto fail;
-
r = sd_bus_message_open_container(reply, 'a', "(ss)");
if (r < 0)
goto fail;
- HASHMAP_FOREACH(item, h, i) {
+ HASHMAP_FOREACH(item, m->enabled, i) {
r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
if (r < 0)
goto fail;
}
- unit_file_list_free(h);
-
r = sd_bus_message_close_container(reply);
if (r < 0)
return r;
@@ -1342,7 +1331,6 @@ static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *us
return sd_bus_send(bus, reply, NULL);
fail:
- unit_file_list_free(h);
return r;
}
@@ -1350,7 +1338,7 @@ static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void
Manager *m = userdata;
const char *name;
UnitFileState state;
- UnitFileScope scope;
+ UnitFileList *f;
int r;
assert(bus);
@@ -1365,12 +1353,11 @@ static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void
if (r < 0)
return r;
- scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
-
- state = unit_file_get_state(scope, NULL, name);
- if (state < 0)
- return state;
-
+ f = hashmap_get(m->enabled, name);
+ if (f)
+ state = f->state;
+ else
+ state = UNIT_FILE_INVALID;
return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
}
@@ -1480,6 +1467,7 @@ static int method_enable_unit_files_generic(
unsigned n_changes = 0;
UnitFileScope scope;
int runtime, force, r;
+ char **j;
assert(bus);
assert(message);
@@ -1501,6 +1489,22 @@ static int method_enable_unit_files_generic(
}
}
#endif
+ STRV_FOREACH(j, l) {
+ UnitFileList *f;
+ char *val = strdup(*j);
+
+ f = hashmap_get(m->enabled, val);
+ if (!f) {
+ f = new0(UnitFileList, 1);
+ f->path = val;
+ }
+ f->state = UNIT_FILE_ENABLED;
+ r = hashmap_put(m->enabled, val, f);
+ if (r < 0) {
+ free(val);
+ return r;
+ }
+ }
r = sd_bus_message_read(message, "bb", &runtime, &force);
if (r < 0)
@@ -1548,6 +1552,7 @@ static int method_disable_unit_files_generic(
unsigned n_changes = 0;
UnitFileScope scope;
int r, runtime;
+ char **j;
assert(bus);
assert(message);
@@ -1561,6 +1566,15 @@ static int method_disable_unit_files_generic(
if (r < 0)
return r;
+ STRV_FOREACH(j, l) {
+ char *val = strdup(*j);
+ UnitFileList *f;
+
+ f = hashmap_get(m->enabled, val);
+ if (f)
+ f->state = UNIT_FILE_DISABLED;
+ }
+
r = sd_bus_message_read(message, "b", &runtime);
if (r < 0)
return r;
diff --git a/src/core/manager.c b/src/core/manager.c
index ce8759e..2d1deac 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -459,6 +459,10 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
if (r < 0)
goto fail;
+ r = hashmap_ensure_allocated(&m->enabled, string_hash_func, string_compare_func);
+ if (r < 0)
+ goto fail;
+
r = sd_event_default(&m->event);
if (r < 0)
goto fail;
@@ -792,6 +796,7 @@ void manager_free(Manager *m) {
hashmap_free(m->watch_pids1);
hashmap_free(m->watch_pids2);
hashmap_free(m->watch_bus);
+ hashmap_free(m->enabled);
set_free(m->failed_units);
@@ -1027,7 +1032,9 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
* finished */
m->send_reloading_done = true;
}
-
+ r = build_enabled_cache(m, NULL);
+ if (r < 0)
+ log_error("Failed to build the enabled cache");
return r;
}
diff --git a/src/core/manager.h b/src/core/manager.h
index 14cdf81..1884cee 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -78,6 +78,7 @@ struct Manager {
/* Active jobs and units */
Hashmap *units; /* name string => Unit object n:1 */
Hashmap *jobs; /* job id => Job object 1:1 */
+ Hashmap *enabled; /* a hashmap for enabled Units */
/* To make it easy to iterate through the units of a specific
* type we maintain a per type linked list */
diff --git a/src/core/unit.c b/src/core/unit.c
index 153b79b..5ac1062 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2800,7 +2800,7 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
if (u->unit_file_state < 0 && u->fragment_path)
u->unit_file_state = unit_file_get_state(
u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
- NULL, basename(u->fragment_path));
+ NULL, basename(u->fragment_path), u->manager);
return u->unit_file_state;
}
diff --git a/src/shared/install.c b/src/shared/install.c
index 7409046..2b2bc7d 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1654,17 +1654,18 @@ int unit_file_get_default(
return -ENOENT;
}
-
UnitFileState unit_file_get_state(
UnitFileScope scope,
const char *root_dir,
- const char *name) {
+ const char *name,
+ Manager *m) {
_cleanup_lookup_paths_free_ LookupPaths paths = {};
UnitFileState state = _UNIT_FILE_STATE_INVALID;
char **i;
_cleanup_free_ char *path = NULL;
int r;
+ UnitFileList *f = NULL;
assert(scope >= 0);
assert(scope < _UNIT_FILE_SCOPE_MAX);
@@ -1718,6 +1719,10 @@ UnitFileState unit_file_get_state(
return state;
}
}
+ if (m && (m->enabled != NULL))
+ f = hashmap_get(m->enabled, name);
+ if (f)
+ return f->state;
r = find_symlinks_in_scope(scope, root_dir, name, &state);
if (r < 0)
@@ -1983,6 +1988,7 @@ int unit_file_get_list(
}
r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
+
if (r < 0)
return r;
else if (r > 0) {
@@ -1991,6 +1997,7 @@ int unit_file_get_list(
}
r = unit_file_can_install(&paths, root_dir, f->path, true);
+
if (r == -EINVAL || /* Invalid setting? */
r == -EBADMSG || /* Invalid format? */
r == -ENOENT /* Included file not found? */)
@@ -2013,6 +2020,149 @@ int unit_file_get_list(
return r;
}
+int build_enabled_cache(Manager *m, const char *root_dir)
+{
+ char **i;
+ _cleanup_free_ char *buf = NULL;
+ _cleanup_closedir_ DIR *d = NULL;
+ int r;
+ _cleanup_lookup_paths_free_ LookupPaths paths = {};
+
+ r = lookup_paths_init_from_scope(&paths, m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(i, paths.unit_path) {
+ const char *units_dir = *i;
+ if (d)
+ closedir(d);
+
+ 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 ( (de->d_type != DT_DIR) && (!unit_name_is_valid(de->d_name, TEMPLATE_VALID)))
+ continue;
+
+ r = dirent_ensure_type(d, de);
+
+ if (r < 0) {
+ if (r == -ENOENT)
+ continue;
+ return r;
+ }
+
+ if (de->d_type != DT_LNK && de->d_type != DT_REG && de->d_type != DT_DIR)
+ continue;
+
+ if (de->d_type == DT_DIR) {
+ char inner_dir[PATH_MAX];
+ DIR *d1 = NULL;
+ if (d1)
+ closedir(d1);
+ snprintf(inner_dir, sizeof(units_dir) + sizeof(de->d_name),
+ "%s/%s",units_dir, de->d_name);
+ d1 = opendir(inner_dir);
+ if (!d1) {
+ if (errno == ENOENT)
+ continue;
+
+ return -errno;
+ }
+ for (;;) {
+ struct dirent *de1;
+ errno = 0;
+
+ de1 = readdir(d1);
+ if (!de1 && errno != 0)
+ return -errno;
+
+ if (!de1)
+ break;
+
+ if (ignore_file(de1->d_name))
+ continue;
+
+ if (!unit_name_is_valid(de1->d_name, TEMPLATE_VALID))
+ continue;
+
+ r = dirent_ensure_type(d, de1);
+
+ if (r < 0) {
+ if (r == -ENOENT)
+ continue;
+
+ return r;
+ }
+
+ if (de1->d_type != DT_LNK && de1->d_type != DT_REG)
+ continue;
+ if (de1->d_type == DT_LNK) {
+ UnitFileList *f;
+ char *val1 = strdup(de1->d_name);
+ f = new0(UnitFileList, 1);
+ if (!f)
+ return -ENOMEM;
+ f->path = path_make_absolute(de1->d_name, inner_dir);
+
+ if (!f->path)
+ return -ENOMEM;
+
+ r = unit_file_can_install(&m->lookup_paths, root_dir, de1->d_name, true);
+
+ if (r < 0 && errno != ENOENT)
+ return r;
+ else
+ if (r == 0)
+ f->state = UNIT_FILE_STATIC;
+ else
+ f->state = UNIT_FILE_ENABLED;
+ hashmap_put(m->enabled, val1, f);
+ }
+ }
+ }
+ else if (de->d_type == DT_LNK) {
+ UnitFileList *f;
+ char *val = strdup(de->d_name);
+ f = new0(UnitFileList, 1);
+ if (!f)
+ return -ENOMEM;
+ f->path = path_make_absolute(de->d_name, units_dir);
+ if (!f->path)
+ return -ENOMEM;
+
+ r = unit_file_can_install(&m->lookup_paths, root_dir, de->d_name, true);
+
+ if (r < 0 && errno != ENOENT)
+ return r;
+ else
+ if (r == 0)
+ f->state = UNIT_FILE_STATIC;
+ else
+ f->state = UNIT_FILE_ENABLED;
+ hashmap_put(m->enabled, val, f);
+ }
+ }
+ }
+ return 0;
+}
+
static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
[UNIT_FILE_ENABLED] = "enabled",
[UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
diff --git a/src/shared/install.h b/src/shared/install.h
index 5d57b1b..6ba3319 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -52,6 +52,8 @@ typedef enum UnitFileChangeType {
_UNIT_FILE_CHANGE_TYPE_INVALID = -1
} UnitFileChangeType;
+#include "manager.h"
+
typedef struct UnitFileChange {
UnitFileChangeType type;
char *path;
@@ -83,7 +85,7 @@ int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, ch
int unit_file_set_default(UnitFileScope scope, const char *root_dir, const char *file, bool force, UnitFileChange **changes, unsigned *n_changes);
int unit_file_get_default(UnitFileScope scope, const char *root_dir, char **name);
-UnitFileState unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename);
+UnitFileState unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename, Manager *m);
int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h);
@@ -97,3 +99,5 @@ 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_;
+
+int build_enabled_cache(Manager *m, const char *root_dir);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 653a324..8675567 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -5289,7 +5289,7 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
STRV_FOREACH(name, names) {
UnitFileState state;
- state = unit_file_get_state(arg_scope, arg_root, *name);
+ state = unit_file_get_state(arg_scope, arg_root, *name, NULL);
if (state < 0) {
log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
return state;
diff --git a/src/test/test-install.c b/src/test/test-install.c
index 2087d52..e6bc0da 100644
--- a/src/test/test-install.c
+++ b/src/test/test-install.c
@@ -46,19 +46,32 @@ int main(int argc, char* argv[]) {
UnitFileList *p;
Iterator i;
int r;
+ Manager *m = NULL;
+ FILE *serial = NULL;
+ FDSet *fdset = NULL;
const char *const files[] = { "avahi-daemon.service", NULL };
const char *const files2[] = { "/home/lennart/test.service", NULL };
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
- h = hashmap_new(string_hash_func, string_compare_func);
- r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
+ r = manager_new(SYSTEMD_SYSTEM, &m);
+ if (r == -EPERM || r == -EACCES) {
+ puts("manager_new: Permission denied. Skipping test.");
+ return EXIT_TEST_SKIP;
+ }
+ assert(r >= 0);
+ assert_se(manager_startup(m, serial, fdset) >= 0);
+
+ r = build_enabled_cache(m, NULL);
assert_se(r == 0);
+ h = m->enabled;
+
+ assert_se(r >= 0);
HASHMAP_FOREACH(p, h, i) {
UnitFileState s;
- s = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(p->path));
+ s = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(p->path), m);
assert_se(p->state == s);
@@ -67,8 +80,6 @@ int main(int argc, char* argv[]) {
unit_file_state_to_string(p->state));
}
- unit_file_list_free(h);
-
log_error("enable");
r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
@@ -82,7 +93,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], NULL) == UNIT_FILE_ENABLED);
log_error("disable");
@@ -95,7 +106,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], NULL) == UNIT_FILE_DISABLED);
log_error("mask");
changes = NULL;
@@ -110,7 +121,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], m) == UNIT_FILE_MASKED);
log_error("unmask");
changes = NULL;
@@ -125,7 +136,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], NULL) == UNIT_FILE_DISABLED);
log_error("mask");
changes = NULL;
@@ -137,7 +148,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], NULL) == UNIT_FILE_MASKED);
log_error("disable");
changes = NULL;
@@ -152,7 +163,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], NULL) == UNIT_FILE_MASKED);
log_error("umask");
changes = NULL;
@@ -164,7 +175,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], NULL) == UNIT_FILE_DISABLED);
log_error("enable files2");
changes = NULL;
@@ -176,7 +187,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0])) == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), NULL) == UNIT_FILE_ENABLED);
log_error("disable files2");
changes = NULL;
@@ -188,7 +199,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0])) == _UNIT_FILE_STATE_INVALID);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), NULL) == _UNIT_FILE_STATE_INVALID);
log_error("link files2");
changes = NULL;
@@ -200,7 +211,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0])) == UNIT_FILE_LINKED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), NULL) == UNIT_FILE_LINKED);
log_error("disable files2");
changes = NULL;
@@ -212,7 +223,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0])) == _UNIT_FILE_STATE_INVALID);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), NULL) == _UNIT_FILE_STATE_INVALID);
log_error("link files2");
changes = NULL;
@@ -224,7 +235,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0])) == UNIT_FILE_LINKED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), NULL) == UNIT_FILE_LINKED);
log_error("reenable files2");
changes = NULL;
@@ -236,7 +247,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0])) == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), NULL) == UNIT_FILE_ENABLED);
log_error("disable files2");
changes = NULL;
@@ -248,7 +259,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0])) == _UNIT_FILE_STATE_INVALID);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), NULL) == _UNIT_FILE_STATE_INVALID);
log_error("preset files");
changes = NULL;
n_changes = 0;
@@ -259,7 +270,7 @@ int main(int argc, char* argv[]) {
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
- assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files[0])) == UNIT_FILE_ENABLED);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files[0]), NULL) == UNIT_FILE_ENABLED);
return 0;
}
--
1.8.5.3
More information about the systemd-devel
mailing list