[systemd-commits] 11 commits - src/core src/nss-myhostname src/shared src/systemctl src/test TODO
Zbigniew Jędrzejewski-Szmek
zbyszek at kemper.freedesktop.org
Mon Dec 15 21:30:54 PST 2014
TODO | 5
src/core/load-dropin.c | 138 +--------
src/core/load-dropin.h | 9
src/core/unit.c | 2
src/nss-myhostname/nss-myhostname.c | 4
src/shared/dropin.c | 136 +++++++++
src/shared/dropin.h | 29 ++
src/shared/path-util.c | 6
src/shared/utf8.c | 1
src/systemctl/systemctl.c | 504 +++++++++++++++++-------------------
src/test/test-path-util.c | 4
11 files changed, 439 insertions(+), 399 deletions(-)
New commits:
commit b0ceb53a7ddb94269f70b2769bbc72870e574111
Author: Susant Sahani <susant at redhat.com>
Date: Tue Dec 16 08:48:34 2014 +0530
fix compiler warning
src/shared/utf8.c:268:13: warning: unused variable 'd'
[-Wunused-variable]
int d;
diff --git a/src/shared/utf8.c b/src/shared/utf8.c
index 67f6285..03a0abe 100644
--- a/src/shared/utf8.c
+++ b/src/shared/utf8.c
@@ -265,7 +265,6 @@ char *ascii_is_valid(const char *str) {
int utf8_encode_unichar(uint16_t c, char *p) {
uint8_t *t = (uint8_t*) p;
- int d;
if (c < 0x80) {
t[0] = (uint8_t) c;
commit 75836b9d2071aab978ee78d7d797126a18a32052
Author: Jan Synacek <jsynacek at redhat.com>
Date: Mon Dec 15 10:39:00 2014 +0100
systemctl: fix argument handling when invoked as "shutdown"
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 649fb5c..4c4648f 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -6926,7 +6926,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
switch (c) {
case ARG_HELP:
@@ -6967,6 +6967,8 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
case 't':
case 'a':
+ case 'f':
+ case 'F':
/* Compatibility nops */
break;
commit df17ddee0853482bfaefc36b9bd3424a64621915
Author: Harald Hoyer <harald at redhat.com>
Date: Mon Dec 15 11:34:24 2014 +0100
nss-myhostname: also recognize "gateway."
"gateway." skips adding the domain search path and saves some queries to
the nameserver.
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
index aa92cc9..2f76860 100644
--- a/src/nss-myhostname/nss-myhostname.c
+++ b/src/nss-myhostname/nss-myhostname.c
@@ -78,7 +78,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
canonical = "localhost";
local_address_ipv4 = htonl(INADDR_LOOPBACK);
- } else if (streq(name, "gateway")) {
+ } else if (streq(name, "gateway") || streq(name, "gateway.")) {
n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
if (n_addresses <= 0) {
@@ -348,7 +348,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
canonical = "localhost";
local_address_ipv4 = htonl(INADDR_LOOPBACK);
- } else if (streq(name, "gateway")) {
+ } else if (streq(name, "gateway") || streq(name, "gateway.")) {
n_addresses = local_gateways(NULL, 0, af, &addresses);
if (n_addresses <= 0) {
commit b42de08aa4c97636e42c28c7bce08f0d7c2a719a
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Tue Dec 16 00:22:58 2014 -0500
Update TODO
diff --git a/TODO b/TODO
index c0da5c8..393ee5e 100644
--- a/TODO
+++ b/TODO
@@ -123,7 +123,10 @@ Features:
* systemctl: if some operation fails, show log output?
-* systemctl edit: add commented help text to the end, like git commit
+* systemctl edit:
+- allow creation of units from scratch
+- use equvalent of cat() to insert existing config as a comment, prepended with #.
+ Upon editor exit, lines with one # are removed, lines with two # are left with one #, etc.
* refcounting in sd-resolve is borked
commit bc854dc7cd051e1e5a6ebcca8084b07168051c6c
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Dec 15 23:01:05 2014 -0500
systemctl: refuse to edit runtime dropins when they already exist in /etc
The check for existing unit files and dropins is unified.
path_join() is updated to not insert duplicate separators.
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index b3fe0b8..dcc8321 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -439,14 +439,14 @@ char* path_join(const char *root, const char *path, const char *rest) {
assert(path);
if (!isempty(root))
- return strjoin(root, "/",
+ return strjoin(root, endswith(root, "/") ? "" : "/",
path[0] == '/' ? path+1 : path,
- rest ? "/" : NULL,
+ rest ? (endswith(path, "/") ? "" : "/") : NULL,
rest && rest[0] == '/' ? rest+1 : rest,
NULL);
else
return strjoin(path,
- rest ? "/" : NULL,
+ rest ? (endswith(path, "/") ? "" : "/") : NULL,
rest && rest[0] == '/' ? rest+1 : rest,
NULL);
}
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 51ba330..649fb5c 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -5902,41 +5902,58 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
return 0;
}
-static int get_drop_in_to_edit(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_path) {
- char *tmp_new_path;
- char *tmp;
-
- assert(unit_name);
- assert(ret_path);
+static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
+ _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
switch (arg_scope) {
case UNIT_FILE_SYSTEM:
- tmp = strappenda(arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
+ path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
+ if (arg_runtime)
+ run = path_join(arg_root, "/run/systemd/system/", name);
break;
case UNIT_FILE_GLOBAL:
- tmp = strappenda(arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
+ path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
+ if (arg_runtime)
+ run = path_join(arg_root, "/run/systemd/user/", name);
break;
case UNIT_FILE_USER:
assert(user_home);
assert(user_runtime);
- tmp = strappenda(arg_runtime ? user_runtime : user_home, "/", unit_name, ".d/override.conf");
+ path = path_join(arg_root, user_home, name);
+ if (arg_runtime) {
+ path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
+ if (!path2)
+ return log_oom();
+ run = path_join(arg_root, user_runtime, name);
+ }
break;
default:
assert_not_reached("Invalid scope");
}
-
- tmp_new_path = path_join(arg_root, tmp, NULL);
- if (!tmp_new_path)
+ if (!path || (arg_runtime && !run))
return log_oom();
- *ret_path = tmp_new_path;
+ if (arg_runtime) {
+ if (access(path, F_OK) >= 0)
+ return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
+ run, path);
+ if (path2 && access(path2, F_OK) >= 0)
+ return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
+ run, path2);
+ *ret_path = run;
+ run = NULL;
+ } else {
+ *ret_path = path;
+ path = NULL;
+ }
return 0;
}
-static int unit_file_create_drop_in(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
- char *tmp_new_path;
+
+static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
+ char *tmp_new_path, *ending;
char *tmp_tmp_path;
int r;
@@ -5944,7 +5961,8 @@ static int unit_file_create_drop_in(const char *unit_name, const char *user_home
assert(ret_new_path);
assert(ret_tmp_path);
- r = get_drop_in_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
+ ending = strappenda(unit_name, ".d/override.conf");
+ r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
if (r < 0)
return r;
@@ -5960,91 +5978,6 @@ static int unit_file_create_drop_in(const char *unit_name, const char *user_home
return 0;
}
-static bool unit_is_editable(const char *unit_name, const char *fragment_path, const char *user_home) {
- bool editable = true;
- const char *invalid_path;
-
- assert(unit_name);
-
- if (!arg_runtime)
- return true;
-
- switch (arg_scope) {
- case UNIT_FILE_SYSTEM:
- if (path_startswith(fragment_path, "/etc/systemd/system")) {
- editable = false;
- invalid_path = "/etc/systemd/system";
- } else if (path_startswith(fragment_path, SYSTEM_CONFIG_UNIT_PATH)) {
- editable = false;
- invalid_path = SYSTEM_CONFIG_UNIT_PATH;
- }
- break;
- case UNIT_FILE_GLOBAL:
- if (path_startswith(fragment_path, "/etc/systemd/user")) {
- editable = false;
- invalid_path = "/etc/systemd/user";
- } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
- editable = false;
- invalid_path = USER_CONFIG_UNIT_PATH;
- }
- break;
- case UNIT_FILE_USER:
- assert(user_home);
-
- if (path_startswith(fragment_path, "/etc/systemd/user")) {
- editable = false;
- invalid_path = "/etc/systemd/user";
- } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
- editable = false;
- invalid_path = USER_CONFIG_UNIT_PATH;
- } else if (path_startswith(fragment_path, user_home)) {
- editable = false;
- invalid_path = user_home;
- }
- break;
- default:
- assert_not_reached("Invalid scope");
- }
-
- if (!editable)
- log_error("%s ignored: cannot temporarily edit units from %s", unit_name, invalid_path);
-
- return editable;
-}
-
-static int get_copy_to_edit(const char *unit_name, const char *fragment_path, const char *user_home, const char *user_runtime, char **ret_path) {
- char *tmp_new_path;
-
- assert(unit_name);
- assert(ret_path);
-
- if (!unit_is_editable(unit_name, fragment_path, user_home))
- return -EINVAL;
-
- switch (arg_scope) {
- case UNIT_FILE_SYSTEM:
- tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH, unit_name);
- break;
- case UNIT_FILE_GLOBAL:
- tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH, unit_name);
- break;
- case UNIT_FILE_USER:
- assert(user_home);
- assert(user_runtime);
-
- tmp_new_path = path_join(arg_root, arg_runtime ? user_runtime : user_home, unit_name);
- break;
- default:
- assert_not_reached("Invalid scope");
- }
- if (!tmp_new_path)
- return log_oom();
-
- *ret_path = tmp_new_path;
-
- return 0;
-}
-
static int unit_file_create_copy(const char *unit_name,
const char *fragment_path,
const char *user_home,
@@ -6060,7 +5993,7 @@ static int unit_file_create_copy(const char *unit_name,
assert(ret_new_path);
assert(ret_tmp_path);
- r = get_copy_to_edit(unit_name, fragment_path, user_home, user_runtime, &tmp_new_path);
+ r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
if (r < 0)
return r;
@@ -6192,7 +6125,7 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
if (arg_full)
r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
else
- r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
+ r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
if (r < 0)
return r;
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index 58b456a..11aa52a 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -176,13 +176,13 @@ static void test_path_join(void) {
test_join("/root", "/a/b", "/c", "/root/a/b/c");
test_join("/root", "a/b", "c", "/root/a/b/c");
test_join("/root", "/a/b", "c", "/root/a/b/c");
- test_join("/root", "/", "c", "/root//c");
+ test_join("/root", "/", "c", "/root/c");
test_join("/root", "/", NULL, "/root/");
test_join(NULL, "/a/b", "/c", "/a/b/c");
test_join(NULL, "a/b", "c", "a/b/c");
test_join(NULL, "/a/b", "c", "/a/b/c");
- test_join(NULL, "/", "c", "//c");
+ test_join(NULL, "/", "c", "/c");
test_join(NULL, "/", NULL, "/");
}
commit ad2a035820e0fca29e49816f735bec1fcdabf82a
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Sat Dec 13 16:38:35 2014 -0500
systemctl: share path lookup between 'cat' and 'edit'
'systemctl cat' now works for templates too.
'systemctl edit' does not refuse to edit units that have changed on
disk. That restriction didn't seem useful, actually editing units that
have changed on disk before they are started is very reasonable.
'edit' with instances and templates works again:
Now:
$ build/systemctl edit getty@
Failed to copy /etc/systemd/system/getty at .service.d/override.conf to /etc/systemd/system/getty at .service.d/.override.confdff6290408c86369: Permission denied
$ build/systemctl edit getty at tty3
Failed to create directories for /etc/systemd/system/getty at tty3.service.d/override.conf: Permission denied
$ build/systemctl edit --full getty at tty3
Failed to copy /usr/lib/systemd/system/getty at .service to /etc/systemd/system/.getty at tty3.serviced3d175087e7e439b: Permission denied
Failed to create temporary file for /etc/systemd/system/getty at tty3.service: Permission denied
$ build/systemctl edit --full getty@
Failed to copy /usr/lib/systemd/system/getty at .service to /etc/systemd/system/.getty at .servicea3caad491c0f2f3d: Permission denied
Failed to create temporary file for /etc/systemd/system/getty at .service: Permission denied
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 68cb71c..51ba330 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -74,6 +74,7 @@
#include "bus-error.h"
#include "bus-common-errors.h"
#include "mkdir.h"
+#include "dropin.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
@@ -2286,7 +2287,7 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un
assert(unit_path);
STRV_FOREACH(p, lp->unit_path) {
- char *path;
+ _cleanup_free_ char *path;
path = path_join(arg_root, *p, unit_name);
if (!path)
@@ -2294,35 +2295,46 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un
if (access(path, F_OK) == 0) {
*unit_path = path;
+ path = NULL;
return 1;
}
-
- free(path);
}
return 0;
}
-static int unit_find_path(sd_bus *bus, const char *unit_name, const char *template, bool avoid_bus_cache, LookupPaths *lp, char **path) {
+static int unit_find_paths(sd_bus *bus,
+ const char *unit_name,
+ bool avoid_bus_cache,
+ LookupPaths *lp,
+ char **fragment_path,
+ char ***dropin_paths) {
int r;
+ /**
+ * Finds where the unit is defined on disk. Returns 0 if the unit
+ * is not found. Returns 1 if it is found, and sets
+ * - the path to the unit in *path, if it exists on disk,
+ * - and a strv of existing drop-ins in *dropins,
+ * if the arg is not NULL and any dropins were found.
+ */
+
assert(unit_name);
- assert(path);
+ assert(fragment_path);
assert(lp);
if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *unit = NULL;
- _cleanup_free_ char *tmp_path = NULL;
+ _cleanup_free_ char *path = NULL;
+ _cleanup_strv_free_ char **dropins = NULL;
unit = unit_dbus_path_from_name(unit_name);
if (!unit)
return log_oom();
- if (need_daemon_reload(bus, unit_name) > 0) {
+ if (need_daemon_reload(bus, unit_name) > 0)
warn_unit_file_changed(unit_name);
- return 0;
- }
r = sd_bus_get_property_string(
bus,
@@ -2331,29 +2343,67 @@ static int unit_find_path(sd_bus *bus, const char *unit_name, const char *templa
"org.freedesktop.systemd1.Unit",
"FragmentPath",
&error,
- &tmp_path);
- if (r < 0) {
- log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
- return 0;
+ &path);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
+
+ r = sd_bus_get_property_strv(
+ bus,
+ "org.freedesktop.systemd1",
+ unit,
+ "org.freedesktop.systemd1.Unit",
+ "DropInPaths",
+ &error,
+ &dropins);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
+
+ r = 0;
+ if (!isempty(path)) {
+ *fragment_path = path;
+ path = NULL;
+ r = 1;
}
- if (isempty(tmp_path)) {
- log_warning("%s ignored: not found", template);
- return 0;
+ if (dropin_paths && !strv_isempty(dropins)) {
+ *dropin_paths = dropins;
+ dropins = NULL;
+ r = 1;
}
+ } else {
+ _cleanup_set_free_ Set *names;
- *path = tmp_path;
- tmp_path = NULL;
+ names = set_new(NULL);
+ if (!names)
+ return -ENOMEM;
- return 1;
- } else {
- r = unit_file_find_path(lp, template, path);
- if (r == 0)
- log_warning("%s ignored: not found", template);
- return r;
+ r = set_put(names, unit_name);
+ if (r < 0)
+ return r;
+
+ r = unit_file_find_path(lp, unit_name, fragment_path);
+ if (r < 0)
+ return r;
+
+ if (r == 0) {
+ _cleanup_free_ char *template;
+
+ template = unit_name_template(unit_name);
+ if (!template)
+ return log_oom();
+
+ if (!streq(template, unit_name)) {
+ r = unit_file_find_path(lp, template, fragment_path);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ if (dropin_paths)
+ r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
}
- return 0;
+ return r;
}
typedef struct WaitData {
@@ -2810,6 +2860,9 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_free_ UnitInfo *unit_infos = NULL;
+ if (!bus)
+ return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
+
r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
if (r < 0)
return r;
@@ -4701,56 +4754,38 @@ static int init_home_and_lookup_paths(char **user_home, char **user_runtime, Loo
}
static int cat(sd_bus *bus, char **args) {
+ _cleanup_free_ char *user_home = NULL;
+ _cleanup_free_ char *user_runtime = NULL;
+ _cleanup_lookup_paths_free_ LookupPaths lp = {};
_cleanup_strv_free_ char **names = NULL;
char **name;
- bool first = true;
+ bool first = true, avoid_bus_cache;
int r = 0;
- assert(bus);
assert(args);
+ r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
+ if (r < 0)
+ return r;
+
r = expand_names(bus, args + 1, NULL, &names);
if (r < 0)
log_error_errno(r, "Failed to expand names: %m");
+ avoid_bus_cache = !bus || avoid_bus();
+
pager_open_if_enabled();
STRV_FOREACH(name, names) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *fragment_path = NULL;
_cleanup_strv_free_ char **dropin_paths = NULL;
- _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
char **path;
- unit = unit_dbus_path_from_name(*name);
- if (!unit)
- return log_oom();
-
- if (need_daemon_reload(bus, *name) > 0)
- warn_unit_file_changed(*name);
-
- r = sd_bus_get_property_string(
- bus,
- "org.freedesktop.systemd1",
- unit,
- "org.freedesktop.systemd1.Unit",
- "FragmentPath",
- &error,
- &fragment_path);
- if (r < 0) {
- log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
- continue;
- }
-
- r = sd_bus_get_property_strv(
- bus,
- "org.freedesktop.systemd1",
- unit,
- "org.freedesktop.systemd1.Unit",
- "DropInPaths",
- &error,
- &dropin_paths);
- if (r < 0) {
- log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
+ r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
+ if (r < 0)
+ return r;
+ else if (r == 0) {
+ log_warning("Unit %s does not have any files on disk", *name);
continue;
}
@@ -4759,7 +4794,7 @@ static int cat(sd_bus *bus, char **args) {
else
puts("");
- if (!isempty(fragment_path)) {
+ if (fragment_path) {
printf("%s# %s%s\n",
ansi_highlight_blue(),
fragment_path,
@@ -6115,7 +6150,7 @@ static int run_editor(char **paths) {
}
}
- log_error("Cannot edit unit(s): No editor available. Please set either SYSTEMD_EDITOR or EDITOR or VISUAL environment variable");
+ log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
_exit(EXIT_FAILURE);
}
@@ -6145,27 +6180,21 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
STRV_FOREACH(name, names) {
_cleanup_free_ char *path = NULL;
- _cleanup_free_ char *template = NULL;
char *new_path, *tmp_path;
- template = unit_name_template(*name);
- if (!template)
- return log_oom();
-
- r = unit_find_path(bus, *name, template, avoid_bus_cache, &lp, &path);
+ r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
if (r < 0)
return r;
- else if (r == 0) {
- continue;
- }
+ else if (r == 0 || !path)
+ // FIXME: support units with path==NULL (no FragmentPath)
+ return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
if (arg_full)
- r = unit_file_create_copy(template, path, user_home, user_runtime, &new_path, &tmp_path);
+ r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
else
- r = unit_file_create_drop_in(template, user_home, user_runtime, &new_path, &tmp_path);
-
+ r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
if (r < 0)
- continue;
+ return r;
r = strv_push_pair(paths, new_path, tmp_path);
if (r < 0)
@@ -7307,7 +7336,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
{ "check", MORE, 2, check_unit_active },
{ "is-failed", MORE, 2, check_unit_failed },
{ "show", MORE, 1, show },
- { "cat", MORE, 2, cat },
+ { "cat", MORE, 2, cat, NOBUS },
{ "status", MORE, 1, show },
{ "help", MORE, 2, show },
{ "snapshot", LESS, 2, snapshot },
commit 8df1850740f2b78407b856e32ba649a7037227d4
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Tue Dec 16 00:28:43 2014 -0500
systemctl: split out LookupPaths initialization
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index d16c673..68cb71c 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -4668,6 +4668,38 @@ static int show(sd_bus *bus, char **args) {
return ret;
}
+static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
+ int r;
+
+ assert(user_home);
+ assert(user_runtime);
+ assert(lp);
+
+ if (arg_scope == UNIT_FILE_USER) {
+ r = user_config_home(user_home);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
+ else if (r == 0)
+ return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
+
+ r = user_runtime_dir(user_runtime);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
+ else if (r == 0)
+ return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
+ }
+
+ r = lookup_paths_init(lp,
+ arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
+ arg_scope == UNIT_FILE_USER,
+ arg_root,
+ NULL, NULL, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
+
+ return 0;
+}
+
static int cat(sd_bus *bus, char **args) {
_cleanup_strv_free_ char **names = NULL;
char **name;
@@ -6105,27 +6137,9 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
assert(names);
assert(paths);
- if (arg_scope == UNIT_FILE_USER) {
- r = user_config_home(&user_home);
- if (r < 0)
- return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
- else if (r == 0)
- return log_error_errno(ENOTDIR, "Cannot edit units: $XDG_CONFIG_HOME and $HOME are not set.");
-
- r = user_runtime_dir(&user_runtime);
- if (r < 0)
- return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
- else if (r == 0)
- return log_error_errno(ENOTDIR, "Cannot edit units: $XDG_RUNTIME_DIR is not set.");
- }
-
- r = lookup_paths_init(&lp,
- arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
- arg_scope == UNIT_FILE_USER,
- arg_root,
- NULL, NULL, NULL);
+ r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
if (r < 0)
- return log_error_errno(r, "Failed get lookup paths: %m");
+ return r;
avoid_bus_cache = !bus || avoid_bus();
commit 33f6c497f3f2da15b94da9140f77aefac92e2866
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Tue Dec 16 00:28:41 2014 -0500
systemctl: move two functions up
No functional change.
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 20bc3bd..d16c673 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2278,6 +2278,84 @@ static void warn_unit_file_changed(const char *name) {
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
}
+static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
+ char **p;
+
+ assert(lp);
+ assert(unit_name);
+ assert(unit_path);
+
+ STRV_FOREACH(p, lp->unit_path) {
+ char *path;
+
+ path = path_join(arg_root, *p, unit_name);
+ if (!path)
+ return log_oom();
+
+ if (access(path, F_OK) == 0) {
+ *unit_path = path;
+ return 1;
+ }
+
+ free(path);
+ }
+
+ return 0;
+}
+
+static int unit_find_path(sd_bus *bus, const char *unit_name, const char *template, bool avoid_bus_cache, LookupPaths *lp, char **path) {
+ int r;
+
+ assert(unit_name);
+ assert(path);
+ assert(lp);
+
+ if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *unit = NULL;
+ _cleanup_free_ char *tmp_path = NULL;
+
+ unit = unit_dbus_path_from_name(unit_name);
+ if (!unit)
+ return log_oom();
+
+ if (need_daemon_reload(bus, unit_name) > 0) {
+ warn_unit_file_changed(unit_name);
+ return 0;
+ }
+
+ r = sd_bus_get_property_string(
+ bus,
+ "org.freedesktop.systemd1",
+ unit,
+ "org.freedesktop.systemd1.Unit",
+ "FragmentPath",
+ &error,
+ &tmp_path);
+ if (r < 0) {
+ log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
+ return 0;
+ }
+
+ if (isempty(tmp_path)) {
+ log_warning("%s ignored: not found", template);
+ return 0;
+ }
+
+ *path = tmp_path;
+ tmp_path = NULL;
+
+ return 1;
+ } else {
+ r = unit_file_find_path(lp, template, path);
+ if (r == 0)
+ log_warning("%s ignored: not found", template);
+ return r;
+ }
+
+ return 0;
+}
+
typedef struct WaitData {
Set *set;
@@ -5719,31 +5797,6 @@ static int is_system_running(sd_bus *bus, char **args) {
return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
}
-static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
- char **p;
-
- assert(lp);
- assert(unit_name);
- assert(unit_path);
-
- STRV_FOREACH(p, lp->unit_path) {
- char *path;
-
- path = path_join(arg_root, *p, unit_name);
- if (!path)
- return log_oom();
-
- if (access(path, F_OK) == 0) {
- *unit_path = path;
- return 1;
- }
-
- free(path);
- }
-
- return 0;
-}
-
static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
char *t;
int r;
@@ -6041,59 +6094,6 @@ static int run_editor(char **paths) {
return r;
}
-static int unit_find_path(sd_bus *bus, const char *unit_name, const char *template, bool avoid_bus_cache, LookupPaths *lp, char **path) {
- int r;
-
- assert(unit_name);
- assert(path);
- assert(lp);
-
- if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *unit = NULL;
- _cleanup_free_ char *tmp_path = NULL;
-
- unit = unit_dbus_path_from_name(unit_name);
- if (!unit)
- return log_oom();
-
- if (need_daemon_reload(bus, unit_name) > 0) {
- warn_unit_file_changed(unit_name);
- return 0;
- }
-
- r = sd_bus_get_property_string(
- bus,
- "org.freedesktop.systemd1",
- unit,
- "org.freedesktop.systemd1.Unit",
- "FragmentPath",
- &error,
- &tmp_path);
- if (r < 0) {
- log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
- return 0;
- }
-
- if (isempty(tmp_path)) {
- log_warning("%s ignored: not found", template);
- return 0;
- }
-
- *path = tmp_path;
- tmp_path = NULL;
-
- return 1;
- } else {
- r = unit_file_find_path(lp, template, path);
- if (r == 0)
- log_warning("%s ignored: not found", template);
- return r;
- }
-
- return 0;
-}
-
static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
_cleanup_free_ char *user_home = NULL;
_cleanup_free_ char *user_runtime = NULL;
commit 3f36991e00634026db3c603a10dfcb3af2c5b7b2
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Dec 15 23:28:38 2014 -0500
systemctl: unify warning about unit files changed on disk
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 324d9b6..20bc3bd 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2270,6 +2270,14 @@ static int need_daemon_reload(sd_bus *bus, const char *unit) {
return b;
}
+static void warn_unit_file_changed(const char *name) {
+ log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
+ ansi_highlight_red(),
+ ansi_highlight_off(),
+ name,
+ arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
+}
+
typedef struct WaitData {
Set *set;
@@ -2676,8 +2684,7 @@ static int start_unit_one(
return bus_log_parse_error(r);
if (need_daemon_reload(bus, name) > 0)
- log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
- name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
+ warn_unit_file_changed(name);
if (s) {
char *p;
@@ -3606,10 +3613,7 @@ static void print_status_info(
}
if (i->need_daemon_reload)
- printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
- ansi_highlight_red(),
- ansi_highlight_off(),
- arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
+ warn_unit_file_changed(i->id);
}
static void show_unit_help(UnitStatusInfo *i) {
@@ -4612,8 +4616,7 @@ static int cat(sd_bus *bus, char **args) {
return log_oom();
if (need_daemon_reload(bus, *name) > 0)
- log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
- *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
+ warn_unit_file_changed(*name);
r = sd_bus_get_property_string(
bus,
@@ -6055,8 +6058,7 @@ static int unit_find_path(sd_bus *bus, const char *unit_name, const char *templa
return log_oom();
if (need_daemon_reload(bus, unit_name) > 0) {
- log_warning("%s ignored: unit file changed on disk. Run 'systemctl%s daemon-reload'.",
- unit_name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
+ warn_unit_file_changed(unit_name);
return 0;
}
commit 5b013a2f67a5914d6e86e3914f40cf44a03da091
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Sat Dec 13 12:43:07 2014 -0500
systemctl: do not use -1 for return code
Also make the error messages more specific to give a hint to the user
how to solve the problem.
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 8a1b481..324d9b6 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -6106,19 +6106,15 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
if (arg_scope == UNIT_FILE_USER) {
r = user_config_home(&user_home);
if (r < 0)
- return log_oom();
- else if (r == 0) {
- log_error("Cannot edit units for the user instance: home directory unknown");
- return -1;
- }
+ return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
+ else if (r == 0)
+ return log_error_errno(ENOTDIR, "Cannot edit units: $XDG_CONFIG_HOME and $HOME are not set.");
r = user_runtime_dir(&user_runtime);
if (r < 0)
- return log_oom();
- else if (r == 0) {
- log_error("Cannot edit units for the user instance: runtime directory unknown");
- return -1;
- }
+ return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
+ else if (r == 0)
+ return log_error_errno(ENOTDIR, "Cannot edit units: $XDG_RUNTIME_DIR is not set.");
}
r = lookup_paths_init(&lp,
@@ -6126,10 +6122,8 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
arg_scope == UNIT_FILE_USER,
arg_root,
NULL, NULL, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed get lookup paths: %m");
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed get lookup paths: %m");
avoid_bus_cache = !bus || avoid_bus();
commit 1a7f1b385cd9de8a0da934fadc379860f914ef33
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Sun Dec 14 23:12:40 2014 -0500
Move dropin listing to shared
No functional change. This is in preparation for using this in
systemctl in the future.
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index 8afaf45..8be1900 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -31,137 +31,27 @@
#include "load-fragment.h"
#include "conf-files.h"
-static int iterate_dir(
- Unit *u,
- const char *path,
+static int add_dependency_consumer(
UnitDependency dependency,
- char ***strv) {
-
- _cleanup_closedir_ DIR *d = NULL;
+ const char *entry,
+ const char* filepath,
+ void *arg) {
+ Unit *u = arg;
int r;
assert(u);
- assert(path);
-
- /* The config directories are special, since the order of the
- * drop-ins matters */
- if (dependency < 0) {
- r = strv_extend(strv, path);
- if (r < 0)
- return log_oom();
-
- return 0;
- }
-
- d = opendir(path);
- if (!d) {
- if (errno == ENOENT)
- return 0;
-
- log_error_errno(errno, "Failed to open directory %s: %m", path);
- return -errno;
- }
-
- for (;;) {
- struct dirent *de;
- _cleanup_free_ char *f = NULL;
-
- errno = 0;
- de = readdir(d);
- if (!de && errno != 0)
- return log_error_errno(errno, "Failed to read directory %s: %m", path);
-
- if (!de)
- break;
-
- if (ignore_file(de->d_name))
- continue;
- f = strjoin(path, "/", de->d_name, NULL);
- if (!f)
- return log_oom();
-
- r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true);
- if (r < 0)
- log_error_errno(r, "Cannot add dependency %s to %s, ignoring: %m", de->d_name, u->id);
- }
+ r = unit_add_dependency_by_name(u, dependency, entry, filepath, true);
+ if (r < 0)
+ log_error_errno(r, "Cannot add dependency %s to %s, ignoring: %m", entry, u->id);
return 0;
}
-static int process_dir(
- Unit *u,
- const char *unit_path,
- const char *name,
- const char *suffix,
- UnitDependency dependency,
- char ***strv) {
-
- _cleanup_free_ char *path = NULL;
-
- assert(u);
- assert(unit_path);
- assert(name);
- assert(suffix);
-
- path = strjoin(unit_path, "/", name, suffix, NULL);
- if (!path)
- return log_oom();
-
- if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, path))
- iterate_dir(u, path, dependency, strv);
-
- if (u->instance) {
- _cleanup_free_ char *template = NULL, *p = NULL;
- /* Also try the template dir */
-
- template = unit_name_template(name);
- if (!template)
- return log_oom();
-
- p = strjoin(unit_path, "/", template, suffix, NULL);
- if (!p)
- return log_oom();
-
- if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, p))
- iterate_dir(u, p, dependency, strv);
- }
-
- return 0;
-}
-
-char **unit_find_dropin_paths(Unit *u) {
- _cleanup_strv_free_ char **strv = NULL;
- char **configs = NULL;
- Iterator i;
- char *t;
- int r;
-
- assert(u);
-
- SET_FOREACH(t, u->names, i) {
- char **p;
-
- STRV_FOREACH(p, u->manager->lookup_paths.unit_path)
- process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
- }
-
- if (strv_isempty(strv))
- return NULL;
-
- r = conf_files_list_strv(&configs, ".conf", NULL, (const char**) strv);
- if (r < 0) {
- log_error_errno(r, "Failed to get list of configuration files: %m");
- strv_free(configs);
- return NULL;
- }
-
- return configs;
-}
-
int unit_load_dropin(Unit *u) {
Iterator i;
char *t, **f;
+ int r;
assert(u);
@@ -171,13 +61,15 @@ int unit_load_dropin(Unit *u) {
char **p;
STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
- process_dir(u, *p, t, ".wants", UNIT_WANTS, NULL);
- process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL);
+ unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".wants", UNIT_WANTS,
+ add_dependency_consumer, u, NULL);
+ unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".requires", UNIT_REQUIRES,
+ add_dependency_consumer, u, NULL);
}
}
- u->dropin_paths = unit_find_dropin_paths(u);
- if (!u->dropin_paths)
+ r = unit_find_dropin_paths(u, &u->dropin_paths);
+ if (r <= 0)
return 0;
STRV_FOREACH(f, u->dropin_paths) {
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
index fd55117..1e018c4 100644
--- a/src/core/load-dropin.h
+++ b/src/core/load-dropin.h
@@ -22,8 +22,15 @@
***/
#include "unit.h"
+#include "dropin.h"
/* Read service data supplementary drop-in directories */
-char **unit_find_dropin_paths(Unit *u);
+static inline int unit_find_dropin_paths(Unit *u, char ***paths) {
+ return unit_file_find_dropin_paths(u->manager->lookup_paths.unit_path,
+ u->manager->unit_path_cache,
+ u->names,
+ paths);
+}
+
int unit_load_dropin(Unit *u);
diff --git a/src/core/unit.c b/src/core/unit.c
index 8cec0e7..a2f3728 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2894,7 +2894,7 @@ bool unit_need_daemon_reload(Unit *u) {
return true;
}
- t = unit_find_dropin_paths(u);
+ (void) unit_find_dropin_paths(u, &t);
loaded_cnt = strv_length(t);
current_cnt = strv_length(u->dropin_paths);
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
index c5c4f95..40e6fee 100644
--- a/src/shared/dropin.c
+++ b/src/shared/dropin.c
@@ -21,8 +21,10 @@
#include "dropin.h"
#include "util.h"
+#include "strv.h"
#include "mkdir.h"
#include "fileio-label.h"
+#include "conf-files.h"
int drop_in_file(const char *dir, const char *unit, unsigned level,
const char *name, char **_p, char **_q) {
@@ -100,3 +102,137 @@ int write_drop_in_format(const char *dir, const char *unit, unsigned level,
return write_drop_in(dir, unit, level, name, p);
}
+
+static int iterate_dir(
+ const char *path,
+ UnitDependency dependency,
+ dependency_consumer_t consumer,
+ void *arg,
+ char ***strv) {
+
+ _cleanup_closedir_ DIR *d = NULL;
+ int r;
+
+ assert(path);
+
+ /* The config directories are special, since the order of the
+ * drop-ins matters */
+ if (dependency < 0) {
+ r = strv_extend(strv, path);
+ if (r < 0)
+ return log_oom();
+
+ return 0;
+ }
+
+ assert(consumer);
+
+ d = opendir(path);
+ if (!d) {
+ if (errno == ENOENT)
+ return 0;
+
+ log_error_errno(errno, "Failed to open directory %s: %m", path);
+ return -errno;
+ }
+
+ for (;;) {
+ struct dirent *de;
+ _cleanup_free_ char *f = NULL;
+
+ errno = 0;
+ de = readdir(d);
+ if (!de && errno != 0)
+ return log_error_errno(errno, "Failed to read directory %s: %m", path);
+
+ if (!de)
+ break;
+
+ if (ignore_file(de->d_name))
+ continue;
+
+ f = strjoin(path, "/", de->d_name, NULL);
+ if (!f)
+ return log_oom();
+
+ r = consumer(dependency, de->d_name, f, arg);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+int unit_file_process_dir(
+ Set * unit_path_cache,
+ const char *unit_path,
+ const char *name,
+ const char *suffix,
+ UnitDependency dependency,
+ dependency_consumer_t consumer,
+ void *arg,
+ char ***strv) {
+
+ _cleanup_free_ char *path = NULL;
+
+ assert(unit_path);
+ assert(name);
+ assert(suffix);
+
+ path = strjoin(unit_path, "/", name, suffix, NULL);
+ if (!path)
+ return log_oom();
+
+ if (!unit_path_cache || set_get(unit_path_cache, path))
+ iterate_dir(path, dependency, consumer, arg, strv);
+
+ if (unit_name_is_instance(name)) {
+ _cleanup_free_ char *template = NULL, *p = NULL;
+ /* Also try the template dir */
+
+ template = unit_name_template(name);
+ if (!template)
+ return log_oom();
+
+ p = strjoin(unit_path, "/", template, suffix, NULL);
+ if (!p)
+ return log_oom();
+
+ if (!unit_path_cache || set_get(unit_path_cache, p))
+ iterate_dir(p, dependency, consumer, arg, strv);
+ }
+
+ return 0;
+}
+
+int unit_file_find_dropin_paths(
+ char **lookup_path,
+ Set *unit_path_cache,
+ Set *names,
+ char ***paths) {
+
+ _cleanup_strv_free_ char **strv = NULL, **ans = NULL;
+ Iterator i;
+ char *t;
+ int r;
+
+ assert(paths);
+
+ SET_FOREACH(t, names, i) {
+ char **p;
+
+ STRV_FOREACH(p, lookup_path)
+ unit_file_process_dir(unit_path_cache, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, NULL, NULL, &strv);
+ }
+
+ if (strv_isempty(strv))
+ return 0;
+
+ r = conf_files_list_strv(&ans, ".conf", NULL, (const char**) strv);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to get list of configuration files: %m");
+
+ *paths = ans;
+ ans = NULL;
+ return 1;
+}
diff --git a/src/shared/dropin.h b/src/shared/dropin.h
index 9c9742d..d4531fc 100644
--- a/src/shared/dropin.h
+++ b/src/shared/dropin.h
@@ -22,6 +22,8 @@
***/
#include "macro.h"
+#include "set.h"
+#include "unit-name.h"
int drop_in_file(const char *dir, const char *unit, unsigned level,
const char *name, char **_p, char **_q);
@@ -31,3 +33,30 @@ int write_drop_in(const char *dir, const char *unit, unsigned level,
int write_drop_in_format(const char *dir, const char *unit, unsigned level,
const char *name, const char *format, ...) _printf_(5, 6);
+
+/**
+ * This callback will be called for each directory entry @entry,
+ * with @filepath being the full path to the entry.
+ *
+ * If return value is negative, loop will be aborted.
+ */
+typedef int (*dependency_consumer_t)(UnitDependency dependency,
+ const char *entry,
+ const char* filepath,
+ void *arg);
+
+int unit_file_process_dir(
+ Set * unit_path_cache,
+ const char *unit_path,
+ const char *name,
+ const char *suffix,
+ UnitDependency dependency,
+ dependency_consumer_t consumer,
+ void *arg,
+ char ***strv);
+
+int unit_file_find_dropin_paths(
+ char **lookup_path,
+ Set *unit_path_cache,
+ Set *names,
+ char ***paths);
More information about the systemd-commits
mailing list