Merge pull request #1854 from poettering/unit-deps
Dependency engine improvements
This commit is contained in:
@@ -128,7 +128,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
} else if (c == quote) { /* found the end quote */
|
||||
quote = 0;
|
||||
break;
|
||||
} else if (c == '\\') {
|
||||
} else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
|
||||
backslash = true;
|
||||
break;
|
||||
} else {
|
||||
@@ -146,7 +146,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||
else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) {
|
||||
quote = c;
|
||||
break;
|
||||
} else if (c == '\\') {
|
||||
} else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
|
||||
backslash = true;
|
||||
break;
|
||||
} else if (strchr(separators, c)) {
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
#include "macro.h"
|
||||
|
||||
typedef enum ExtractFlags {
|
||||
EXTRACT_RELAX = 1,
|
||||
EXTRACT_CUNESCAPE = 2,
|
||||
EXTRACT_CUNESCAPE_RELAX = 4,
|
||||
EXTRACT_QUOTES = 8,
|
||||
EXTRACT_RELAX = 1,
|
||||
EXTRACT_CUNESCAPE = 2,
|
||||
EXTRACT_CUNESCAPE_RELAX = 4,
|
||||
EXTRACT_QUOTES = 8,
|
||||
EXTRACT_DONT_COALESCE_SEPARATORS = 16,
|
||||
EXTRACT_RETAIN_ESCAPE = 32,
|
||||
} ExtractFlags;
|
||||
|
||||
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
|
||||
|
||||
+2
-2
@@ -311,7 +311,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (mode > 0) {
|
||||
if (mode != MODE_INVALID) {
|
||||
r = fchmod(fd, mode);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
@@ -338,7 +338,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
|
||||
}
|
||||
|
||||
int touch(const char *path) {
|
||||
return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
|
||||
return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
|
||||
}
|
||||
|
||||
int symlink_idempotent(const char *from, const char *to) {
|
||||
|
||||
@@ -148,6 +148,9 @@ static int automount_add_default_dependencies(Automount *a) {
|
||||
|
||||
assert(a);
|
||||
|
||||
if (!UNIT(a)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
if (UNIT(a)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
@@ -219,11 +222,9 @@ static int automount_load(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (UNIT(a)->default_dependencies) {
|
||||
r = automount_add_default_dependencies(a);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = automount_add_default_dependencies(a);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return automount_verify(a);
|
||||
|
||||
@@ -122,7 +122,7 @@ int config_parse_unit_deps(const char *unit,
|
||||
_cleanup_free_ char *word = NULL, *k = NULL;
|
||||
int r;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_RETAIN_ESCAPE);
|
||||
if (r == 0)
|
||||
break;
|
||||
if (r == -ENOMEM)
|
||||
|
||||
+29
-24
@@ -387,12 +387,15 @@ static bool should_umount(Mount *m) {
|
||||
}
|
||||
|
||||
static int mount_add_default_dependencies(Mount *m) {
|
||||
const char *after, *after2, *online;
|
||||
MountParameters *p;
|
||||
const char *after;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (!UNIT(m)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
@@ -413,31 +416,35 @@ static int mount_add_default_dependencies(Mount *m) {
|
||||
return 0;
|
||||
|
||||
if (mount_is_network(p)) {
|
||||
/* We order ourselves after network.target. This is
|
||||
* primarily useful at shutdown: services that take
|
||||
* down the network should order themselves before
|
||||
* network.target, so that they are shut down only
|
||||
* after this mount unit is stopped. */
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* We pull in network-online.target, and order
|
||||
* ourselves after it. This is useful at start-up to
|
||||
* actively pull in tools that want to be started
|
||||
* before we start mounting network file systems, and
|
||||
* whose purpose it is to delay this until the network
|
||||
* is "up". */
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
after = SPECIAL_REMOTE_FS_PRE_TARGET;
|
||||
after2 = SPECIAL_NETWORK_TARGET;
|
||||
online = SPECIAL_NETWORK_ONLINE_TARGET;
|
||||
} else {
|
||||
} else
|
||||
after = SPECIAL_LOCAL_FS_PRE_TARGET;
|
||||
after2 = NULL;
|
||||
online = NULL;
|
||||
}
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (after2) {
|
||||
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (online) {
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (should_umount(m)) {
|
||||
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
@@ -533,11 +540,9 @@ static int mount_add_extras(Mount *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u->default_dependencies) {
|
||||
r = mount_add_default_dependencies(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = mount_add_default_dependencies(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+9
-11
@@ -315,20 +315,20 @@ static int path_add_default_dependencies(Path *p) {
|
||||
|
||||
assert(p);
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE,
|
||||
SPECIAL_PATHS_TARGET, NULL, true);
|
||||
if (!UNIT(p)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_PATHS_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (UNIT(p)->manager->running_as == MANAGER_SYSTEM) {
|
||||
r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES,
|
||||
SPECIAL_SYSINIT_TARGET, NULL, true);
|
||||
r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, NULL, true);
|
||||
return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
|
||||
}
|
||||
|
||||
static int path_load(Unit *u) {
|
||||
@@ -360,11 +360,9 @@ static int path_load(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (UNIT(p)->default_dependencies) {
|
||||
r = path_add_default_dependencies(p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = path_add_default_dependencies(p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return path_verify(p);
|
||||
|
||||
+6
-5
@@ -122,6 +122,9 @@ static int scope_add_default_dependencies(Scope *s) {
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!UNIT(s)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
/* Make sure scopes are unloaded on shutdown */
|
||||
r = unit_add_two_dependencies_by_name(
|
||||
UNIT(s),
|
||||
@@ -173,11 +176,9 @@ static int scope_load(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u->default_dependencies) {
|
||||
r = scope_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = scope_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return scope_verify(s);
|
||||
}
|
||||
|
||||
+69
-22
@@ -515,15 +515,38 @@ static int service_add_default_dependencies(Service *s) {
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!UNIT(s)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
/* Add a number of automatic dependencies useful for the
|
||||
* majority of services. */
|
||||
|
||||
/* First, pull in base system */
|
||||
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true);
|
||||
if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
|
||||
/* First, pull in the really early boot stuff, and
|
||||
* require it, so that we fail if we can't acquire
|
||||
* it. */
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
|
||||
/* In the --user instance there's no sysinit.target,
|
||||
* in that case require basic.target instead. */
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Second, if the rest of the base system is in the same
|
||||
* transaction, order us after it, but do not pull it in or
|
||||
* even require it. */
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Second, activate normal shutdown */
|
||||
/* Third, add us in for normal shutdown. */
|
||||
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
|
||||
}
|
||||
|
||||
@@ -545,6 +568,43 @@ static void service_fix_output(Service *s) {
|
||||
s->exec_context.std_output = UNIT(s)->manager->default_std_output;
|
||||
}
|
||||
|
||||
static int service_setup_bus_name(Service *s) {
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!s->bus_name)
|
||||
return 0;
|
||||
|
||||
if (is_kdbus_available()) {
|
||||
const char *n;
|
||||
|
||||
n = strjoina(s->bus_name, ".busname");
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(UNIT(s), r, "Failed to add dependency to .busname unit: %m");
|
||||
|
||||
} else {
|
||||
/* If kdbus is not available, we know the dbus socket is required, hence pull it in, and require it */
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
|
||||
}
|
||||
|
||||
/* Regardless if kdbus is used or not, we always want to be ordered against dbus.socket if both are in the transaction. */
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true);
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(UNIT(s), r, "Failed to add depdendency on " SPECIAL_DBUS_SOCKET ": %m");
|
||||
|
||||
r = unit_watch_bus_name(UNIT(s), s->bus_name);
|
||||
if (r == -EEXIST)
|
||||
return log_unit_error_errno(UNIT(s), r, "Two services allocated for the same bus name %s, refusing operation.", s->bus_name);
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(UNIT(s), r, "Cannot watch bus name %s: %m", s->bus_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int service_add_extras(Service *s) {
|
||||
int r;
|
||||
|
||||
@@ -584,26 +644,13 @@ static int service_add_extras(Service *s) {
|
||||
if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
|
||||
s->notify_access = NOTIFY_MAIN;
|
||||
|
||||
if (s->bus_name) {
|
||||
const char *n;
|
||||
r = service_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n = strjoina(s->bus_name, ".busname");
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_watch_bus_name(UNIT(s), s->bus_name);
|
||||
if (r == -EEXIST)
|
||||
return log_unit_error_errno(UNIT(s), r, "Two services allocated for the same bus name %s, refusing operation.", s->bus_name);
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(UNIT(s), r, "Cannot watch bus name %s: %m", s->bus_name);
|
||||
}
|
||||
|
||||
if (UNIT(s)->default_dependencies) {
|
||||
r = service_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = service_setup_bus_name(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+6
-6
@@ -85,6 +85,9 @@ static int slice_add_default_dependencies(Slice *s) {
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!UNIT(s)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
/* Make sure slices are unloaded on shutdown */
|
||||
r = unit_add_two_dependencies_by_name(
|
||||
UNIT(s),
|
||||
@@ -96,7 +99,6 @@ static int slice_add_default_dependencies(Slice *s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int slice_verify(Slice *s) {
|
||||
_cleanup_free_ char *parent = NULL;
|
||||
int r;
|
||||
@@ -144,11 +146,9 @@ static int slice_load(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u->default_dependencies) {
|
||||
r = slice_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = slice_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return slice_verify(s);
|
||||
|
||||
+6
-5
@@ -296,6 +296,9 @@ static int socket_add_default_dependencies(Socket *s) {
|
||||
int r;
|
||||
assert(s);
|
||||
|
||||
if (!UNIT(s)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -365,11 +368,9 @@ static int socket_add_extras(Socket *s) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (u->default_dependencies) {
|
||||
r = socket_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = socket_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+6
-5
@@ -213,6 +213,9 @@ static int swap_add_device_links(Swap *s) {
|
||||
static int swap_add_default_dependencies(Swap *s) {
|
||||
assert(s);
|
||||
|
||||
if (!UNIT(s)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
|
||||
return 0;
|
||||
|
||||
@@ -331,11 +334,9 @@ static int swap_load(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (UNIT(s)->default_dependencies) {
|
||||
r = swap_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = swap_add_default_dependencies(s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return swap_verify(s);
|
||||
|
||||
+8
-7
@@ -102,6 +102,9 @@ static int timer_add_default_dependencies(Timer *t) {
|
||||
|
||||
assert(t);
|
||||
|
||||
if (!UNIT(t)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -192,11 +195,9 @@ static int timer_load(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u->default_dependencies) {
|
||||
r = timer_add_default_dependencies(t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
r = timer_add_default_dependencies(t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return timer_verify(t);
|
||||
@@ -518,7 +519,7 @@ static void timer_enter_running(Timer *t) {
|
||||
dual_timestamp_get(&t->last_trigger);
|
||||
|
||||
if (t->stamp_path)
|
||||
touch_file(t->stamp_path, true, t->last_trigger.realtime, UID_INVALID, GID_INVALID, 0);
|
||||
touch_file(t->stamp_path, true, t->last_trigger.realtime, UID_INVALID, GID_INVALID, MODE_INVALID);
|
||||
|
||||
timer_set_state(t, TIMER_RUNNING);
|
||||
return;
|
||||
@@ -554,7 +555,7 @@ static int timer_start(Unit *u) {
|
||||
/* The timer has never run before,
|
||||
* make sure a stamp file exists.
|
||||
*/
|
||||
touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
|
||||
touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
|
||||
}
|
||||
|
||||
t->result = TIMER_SUCCESS;
|
||||
|
||||
+73
-39
@@ -133,9 +133,9 @@ static enum {
|
||||
ACTION_UPDATE_CATALOG,
|
||||
ACTION_LIST_BOOTS,
|
||||
ACTION_FLUSH,
|
||||
ACTION_SYNC,
|
||||
ACTION_ROTATE,
|
||||
ACTION_VACUUM,
|
||||
ACTION_SYNC,
|
||||
} arg_action = ACTION_SHOW;
|
||||
|
||||
typedef struct BootId {
|
||||
@@ -1771,6 +1771,11 @@ static int flush_to_var(void) {
|
||||
_cleanup_close_ int watch_fd = -1;
|
||||
int r;
|
||||
|
||||
if (arg_machine) {
|
||||
log_error("--flush is not supported in conjunction with --machine=.");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* Quick exit */
|
||||
if (access("/run/systemd/journal/flushed", F_OK) >= 0)
|
||||
return 0;
|
||||
@@ -1828,6 +1833,11 @@ static int send_signal_and_wait(int sig, const char *watch_path) {
|
||||
usec_t start;
|
||||
int r;
|
||||
|
||||
if (arg_machine) {
|
||||
log_error("--sync and --rotate are not supported in conjunction with --machine=.");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
start = now(CLOCK_REALTIME);
|
||||
|
||||
/* This call sends the specified signal to journald, and waits
|
||||
@@ -1935,35 +1945,19 @@ int main(int argc, char *argv[]) {
|
||||
* be split up into many files. */
|
||||
setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
|
||||
|
||||
if (arg_action == ACTION_NEW_ID128) {
|
||||
switch (arg_action) {
|
||||
|
||||
case ACTION_NEW_ID128:
|
||||
r = generate_new_id128();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_FLUSH) {
|
||||
r = flush_to_var();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_SYNC) {
|
||||
r = sync_journal();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_ROTATE) {
|
||||
r = rotate();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_SETUP_KEYS) {
|
||||
case ACTION_SETUP_KEYS:
|
||||
r = setup_keys();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_UPDATE_CATALOG ||
|
||||
arg_action == ACTION_LIST_CATALOG ||
|
||||
arg_action == ACTION_DUMP_CATALOG) {
|
||||
|
||||
case ACTION_LIST_CATALOG:
|
||||
case ACTION_DUMP_CATALOG:
|
||||
case ACTION_UPDATE_CATALOG: {
|
||||
_cleanup_free_ char *database;
|
||||
|
||||
database = path_join(arg_root, CATALOG_DATABASE, NULL);
|
||||
@@ -1980,9 +1974,9 @@ int main(int argc, char *argv[]) {
|
||||
bool oneline = arg_action == ACTION_LIST_CATALOG;
|
||||
|
||||
pager_open_if_enabled();
|
||||
|
||||
if (optind < argc)
|
||||
r = catalog_list_items(stdout, database,
|
||||
oneline, argv + optind);
|
||||
r = catalog_list_items(stdout, database, oneline, argv + optind);
|
||||
else
|
||||
r = catalog_list(stdout, database, oneline);
|
||||
if (r < 0)
|
||||
@@ -1992,6 +1986,31 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
case ACTION_FLUSH:
|
||||
r = flush_to_var();
|
||||
goto finish;
|
||||
|
||||
case ACTION_SYNC:
|
||||
r = sync_journal();
|
||||
goto finish;
|
||||
|
||||
case ACTION_ROTATE:
|
||||
r = rotate();
|
||||
goto finish;
|
||||
|
||||
case ACTION_SHOW:
|
||||
case ACTION_PRINT_HEADER:
|
||||
case ACTION_VERIFY:
|
||||
case ACTION_DISK_USAGE:
|
||||
case ACTION_LIST_BOOTS:
|
||||
case ACTION_VACUUM:
|
||||
/* These ones require access to the journal files, continue below. */
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached("Unknown action");
|
||||
}
|
||||
|
||||
if (arg_directory)
|
||||
r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
|
||||
else if (arg_file)
|
||||
@@ -2001,8 +2020,7 @@ int main(int argc, char *argv[]) {
|
||||
else
|
||||
r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to open %s: %m",
|
||||
arg_directory ? arg_directory : arg_file ? "files" : "journal");
|
||||
log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -2010,18 +2028,28 @@ int main(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
if (arg_action == ACTION_VERIFY) {
|
||||
r = verify(j);
|
||||
goto finish;
|
||||
}
|
||||
switch (arg_action) {
|
||||
|
||||
if (arg_action == ACTION_PRINT_HEADER) {
|
||||
case ACTION_NEW_ID128:
|
||||
case ACTION_SETUP_KEYS:
|
||||
case ACTION_LIST_CATALOG:
|
||||
case ACTION_DUMP_CATALOG:
|
||||
case ACTION_UPDATE_CATALOG:
|
||||
case ACTION_FLUSH:
|
||||
case ACTION_SYNC:
|
||||
case ACTION_ROTATE:
|
||||
assert_not_reached("Unexpected action.");
|
||||
|
||||
case ACTION_PRINT_HEADER:
|
||||
journal_print_header(j);
|
||||
r = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_DISK_USAGE) {
|
||||
case ACTION_VERIFY:
|
||||
r = verify(j);
|
||||
goto finish;
|
||||
|
||||
case ACTION_DISK_USAGE: {
|
||||
uint64_t bytes = 0;
|
||||
char sbytes[FORMAT_BYTES_MAX];
|
||||
|
||||
@@ -2034,7 +2062,11 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_VACUUM) {
|
||||
case ACTION_LIST_BOOTS:
|
||||
r = list_boots(j);
|
||||
goto finish;
|
||||
|
||||
case ACTION_VACUUM: {
|
||||
Directory *d;
|
||||
Iterator i;
|
||||
|
||||
@@ -2054,9 +2086,11 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_LIST_BOOTS) {
|
||||
r = list_boots(j);
|
||||
goto finish;
|
||||
case ACTION_SHOW:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached("Unknown action");
|
||||
}
|
||||
|
||||
/* add_boot() must be called first!
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "conf-files.h"
|
||||
#include "fs-util.h"
|
||||
#include "macro.h"
|
||||
#include "parse-util.h"
|
||||
#include "rm-rf.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -40,7 +41,7 @@ static void setup_test_dir(char *tmp_dir, const char *files, ...) {
|
||||
va_start(ap, files);
|
||||
while (files != NULL) {
|
||||
_cleanup_free_ char *path = strappend(tmp_dir, files);
|
||||
assert_se(touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0) == 0);
|
||||
assert_se(touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID) == 0);
|
||||
files = va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
@@ -325,6 +325,18 @@ static void test_extract_first_word(void) {
|
||||
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
|
||||
assert_se(!t);
|
||||
assert_se(!p);
|
||||
|
||||
p = "foo\\xbar";
|
||||
assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
|
||||
assert_se(streq(t, "fooxbar"));
|
||||
free(t);
|
||||
assert_se(p == NULL);
|
||||
|
||||
p = "foo\\xbar";
|
||||
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0);
|
||||
assert_se(streq(t, "foo\\xbar"));
|
||||
free(t);
|
||||
assert_se(p == NULL);
|
||||
}
|
||||
|
||||
static void test_extract_first_word_and_warn(void) {
|
||||
|
||||
Reference in New Issue
Block a user