#include "chattr-util.h"
#include "constants.h"
#include "devnum-util.h"
+#include "dirent-util.h"
#include "dissect-image.h"
#include "fd-util.h"
#include "fileio.h"
ACTION_ROTATE_AND_VACUUM,
ACTION_LIST_FIELDS,
ACTION_LIST_FIELD_NAMES,
+ ACTION_LIST_NAMESPACES,
} arg_action = ACTION_SHOW;
static int add_matches_for_device(sd_journal *j, const char *devpath) {
ARG_NO_HOSTNAME,
ARG_OUTPUT_FIELDS,
ARG_NAMESPACE,
+ ARG_LIST_NAMESPACES,
};
static const struct option options[] = {
{ "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME },
{ "output-fields", required_argument, NULL, ARG_OUTPUT_FIELDS },
{ "namespace", required_argument, NULL, ARG_NAMESPACE },
+ { "list-namespaces", no_argument, NULL, ARG_LIST_NAMESPACES },
{}
};
break;
+ case ARG_LIST_NAMESPACES:
+ arg_action = ACTION_LIST_NAMESPACES;
+ break;
+
case 'D':
arg_directory = optarg;
break;
return 0;
}
+static int list_namespaces(const char *root) {
+ _cleanup_(table_unrefp) Table *table = NULL;
+ sd_id128_t machine;
+ char machine_id[SD_ID128_STRING_MAX];
+ int r;
+
+ r = sd_id128_get_machine(&machine);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get machine ID: %m");
+
+ sd_id128_to_string(machine, machine_id);
+
+ table = table_new("namespace");
+ if (!table)
+ return log_oom();
+
+ (void) table_set_sort(table, (size_t) 0);
+
+ FOREACH_STRING(dir, "/var/log/journal", "/run/log/journal") {
+ _cleanup_free_ char *path = NULL;
+ _cleanup_closedir_ DIR *dirp = NULL;
+
+ path = path_join(root, dir);
+ if (!path)
+ return log_oom();
+
+ dirp = opendir(path);
+ if (!dirp) {
+ log_debug_errno(errno, "Failed to open directory %s, ignoring: %m", path);
+ continue;
+ }
+
+ FOREACH_DIRENT(de, dirp, return log_error_errno(errno, "Failed to iterate through %s: %m", path)) {
+ char *dot;
+
+ if (!startswith(de->d_name, machine_id))
+ continue;
+
+ dot = strchr(de->d_name, '.');
+ if (!dot)
+ continue;
+
+ if (!log_namespace_name_valid(dot + 1))
+ continue;
+
+ r = table_add_cell(table, NULL, TABLE_STRING, dot + 1);
+ if (r < 0)
+ return table_log_add_error(r);
+ }
+ }
+
+ r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, !arg_quiet);
+ if (r < 0)
+ return table_log_print_error(r);
+
+ return 0;
+}
+
static int list_boots(sd_journal *j) {
_cleanup_(table_unrefp) Table *table = NULL;
_cleanup_free_ BootId *boots = NULL;
case ACTION_ROTATE:
return rotate();
+ case ACTION_LIST_NAMESPACES:
+ return list_namespaces(arg_root);
+
case ACTION_SHOW:
case ACTION_PRINT_HEADER:
case ACTION_VERIFY:
systemd-analyze log-level debug
+journalctl --list-namespaces -o json | jq .
+
systemd-run --wait -p LogNamespace=foobar echo "hello world"
+systemd-run --wait -p LogNamespace=foobaz echo "hello world"
journalctl --namespace=foobar --sync
journalctl -o cat --namespace=foobar >/tmp/hello-world
journalctl -o cat >/tmp/no-hello-world
+journalctl --list-namespaces | grep foobar
+journalctl --list-namespaces | grep foobaz
+journalctl --list-namespaces -o json | jq .
+[[ "$(journalctl --root=/tmp --list-namespaces --quiet)" == "" ]]
+
grep "^hello world$" /tmp/hello-world
(! grep "^hello world$" /tmp/no-hello-world)