journal: allow opening journal files specific to some namespace
This commit is contained in:
parent
2f5435a147
commit
456aa87906
|
@ -69,6 +69,7 @@ struct sd_journal {
|
|||
|
||||
char *path;
|
||||
char *prefix;
|
||||
char *namespace;
|
||||
|
||||
OrderedHashmap *files;
|
||||
IteratedCache *files_cache;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "syslog-util.h"
|
||||
|
||||
#define JOURNAL_FILES_MAX 7168
|
||||
|
||||
|
@ -1435,22 +1436,63 @@ static void remove_file_real(sd_journal *j, JournalFile *f) {
|
|||
|
||||
static int dirname_is_machine_id(const char *fn) {
|
||||
sd_id128_t id, machine;
|
||||
const char *e;
|
||||
int r;
|
||||
|
||||
/* Returns true if the specified directory name matches the local machine ID */
|
||||
|
||||
r = sd_id128_get_machine(&machine);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_id128_from_string(fn, &id);
|
||||
e = strchr(fn, '.');
|
||||
if (e) {
|
||||
const char *k;
|
||||
|
||||
/* Looks like it has a namespace suffix. Verify that. */
|
||||
if (!log_namespace_name_valid(e + 1))
|
||||
return false;
|
||||
|
||||
k = strndupa(fn, e - fn);
|
||||
r = sd_id128_from_string(k, &id);
|
||||
} else
|
||||
r = sd_id128_from_string(fn, &id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_id128_equal(id, machine);
|
||||
}
|
||||
|
||||
static int dirname_has_namespace(const char *fn, const char *namespace) {
|
||||
const char *e;
|
||||
|
||||
/* Returns true if the specified directory name matches the specified namespace */
|
||||
|
||||
e = strchr(fn, '.');
|
||||
if (e) {
|
||||
const char *k;
|
||||
|
||||
if (!namespace)
|
||||
return false;
|
||||
|
||||
if (!streq(e + 1, namespace))
|
||||
return false;
|
||||
|
||||
k = strndupa(fn, e - fn);
|
||||
return id128_is_valid(k);
|
||||
}
|
||||
|
||||
if (namespace)
|
||||
return false;
|
||||
|
||||
return id128_is_valid(fn);
|
||||
}
|
||||
|
||||
static bool dirent_is_journal_file(const struct dirent *de) {
|
||||
assert(de);
|
||||
|
||||
/* Returns true if the specified directory entry looks like a journal file we might be interested in */
|
||||
|
||||
if (!IN_SET(de->d_type, DT_REG, DT_LNK, DT_UNKNOWN))
|
||||
return false;
|
||||
|
||||
|
@ -1458,13 +1500,26 @@ static bool dirent_is_journal_file(const struct dirent *de) {
|
|||
endswith(de->d_name, ".journal~");
|
||||
}
|
||||
|
||||
static bool dirent_is_id128_subdir(const struct dirent *de) {
|
||||
static bool dirent_is_journal_subdir(const struct dirent *de) {
|
||||
const char *e, *n;
|
||||
assert(de);
|
||||
|
||||
/* returns true if the specified directory entry looks like a directory that might contain journal
|
||||
* files we might be interested in, i.e. is either a 128bit ID or a 128bit ID suffixed by a
|
||||
* namespace. */
|
||||
|
||||
if (!IN_SET(de->d_type, DT_DIR, DT_LNK, DT_UNKNOWN))
|
||||
return false;
|
||||
|
||||
return id128_is_valid(de->d_name);
|
||||
e = strchr(de->d_name, '.');
|
||||
if (!e)
|
||||
return id128_is_valid(de->d_name); /* No namespace */
|
||||
|
||||
n = strndupa(de->d_name, e - de->d_name);
|
||||
if (!id128_is_valid(n))
|
||||
return false;
|
||||
|
||||
return log_namespace_name_valid(e + 1);
|
||||
}
|
||||
|
||||
static int directory_open(sd_journal *j, const char *path, DIR **ret) {
|
||||
|
@ -1501,7 +1556,7 @@ static void directory_enumerate(sd_journal *j, Directory *m, DIR *d) {
|
|||
if (dirent_is_journal_file(de))
|
||||
(void) add_file_by_name(j, m->path, de->d_name);
|
||||
|
||||
if (m->is_root && dirent_is_id128_subdir(de))
|
||||
if (m->is_root && dirent_is_journal_subdir(de))
|
||||
(void) add_directory(j, m->path, de->d_name);
|
||||
}
|
||||
|
||||
|
@ -1541,7 +1596,11 @@ static void directory_watch(sd_journal *j, Directory *m, int fd, uint32_t mask)
|
|||
}
|
||||
}
|
||||
|
||||
static int add_directory(sd_journal *j, const char *prefix, const char *dirname) {
|
||||
static int add_directory(
|
||||
sd_journal *j,
|
||||
const char *prefix,
|
||||
const char *dirname) {
|
||||
|
||||
_cleanup_free_ char *path = NULL;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
Directory *m;
|
||||
|
@ -1566,6 +1625,11 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
|
|||
!((dirname && dirname_is_machine_id(dirname) > 0) || path_has_prefix(j, path, "/run")))
|
||||
return 0;
|
||||
|
||||
if (!(FLAGS_SET(j->flags, SD_JOURNAL_ALL_NAMESPACES) ||
|
||||
dirname_has_namespace(dirname, j->namespace) > 0 ||
|
||||
(FLAGS_SET(j->flags, SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE) && dirname_has_namespace(dirname, NULL) > 0)))
|
||||
return 0;
|
||||
|
||||
r = directory_open(j, path, &d);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to open directory '%s': %m", path);
|
||||
|
@ -1806,7 +1870,7 @@ static int allocate_inotify(sd_journal *j) {
|
|||
return hashmap_ensure_allocated(&j->directories_by_wd, NULL);
|
||||
}
|
||||
|
||||
static sd_journal *journal_new(int flags, const char *path) {
|
||||
static sd_journal *journal_new(int flags, const char *path, const char *namespace) {
|
||||
_cleanup_(sd_journal_closep) sd_journal *j = NULL;
|
||||
|
||||
j = new0(sd_journal, 1);
|
||||
|
@ -1832,6 +1896,12 @@ static sd_journal *journal_new(int flags, const char *path) {
|
|||
j->path = t;
|
||||
}
|
||||
|
||||
if (namespace) {
|
||||
j->namespace = strdup(namespace);
|
||||
if (!j->namespace)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
j->files = ordered_hashmap_new(&path_hash_ops);
|
||||
if (!j->files)
|
||||
return NULL;
|
||||
|
@ -1848,16 +1918,19 @@ static sd_journal *journal_new(int flags, const char *path) {
|
|||
#define OPEN_ALLOWED_FLAGS \
|
||||
(SD_JOURNAL_LOCAL_ONLY | \
|
||||
SD_JOURNAL_RUNTIME_ONLY | \
|
||||
SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER)
|
||||
SD_JOURNAL_SYSTEM | \
|
||||
SD_JOURNAL_CURRENT_USER | \
|
||||
SD_JOURNAL_ALL_NAMESPACES | \
|
||||
SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE)
|
||||
|
||||
_public_ int sd_journal_open(sd_journal **ret, int flags) {
|
||||
_public_ int sd_journal_open_namespace(sd_journal **ret, const char *namespace, int flags) {
|
||||
_cleanup_(sd_journal_closep) sd_journal *j = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return((flags & ~OPEN_ALLOWED_FLAGS) == 0, -EINVAL);
|
||||
|
||||
j = journal_new(flags, NULL);
|
||||
j = journal_new(flags, NULL, namespace);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1869,6 +1942,10 @@ _public_ int sd_journal_open(sd_journal **ret, int flags) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_journal_open(sd_journal **ret, int flags) {
|
||||
return sd_journal_open_namespace(ret, NULL, flags);
|
||||
}
|
||||
|
||||
#define OPEN_CONTAINER_ALLOWED_FLAGS \
|
||||
(SD_JOURNAL_LOCAL_ONLY | SD_JOURNAL_SYSTEM)
|
||||
|
||||
|
@ -1900,7 +1977,7 @@ _public_ int sd_journal_open_container(sd_journal **ret, const char *machine, in
|
|||
if (!streq_ptr(class, "container"))
|
||||
return -EIO;
|
||||
|
||||
j = journal_new(flags, root);
|
||||
j = journal_new(flags, root, NULL);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1924,7 +2001,7 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f
|
|||
assert_return(path, -EINVAL);
|
||||
assert_return((flags & ~OPEN_DIRECTORY_ALLOWED_FLAGS) == 0, -EINVAL);
|
||||
|
||||
j = journal_new(flags, path);
|
||||
j = journal_new(flags, path, NULL);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1947,7 +2024,7 @@ _public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int fla
|
|||
assert_return(ret, -EINVAL);
|
||||
assert_return(flags == 0, -EINVAL);
|
||||
|
||||
j = journal_new(flags, NULL);
|
||||
j = journal_new(flags, NULL, NULL);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1982,7 +2059,7 @@ _public_ int sd_journal_open_directory_fd(sd_journal **ret, int fd, int flags) {
|
|||
if (!S_ISDIR(st.st_mode))
|
||||
return -EBADFD;
|
||||
|
||||
j = journal_new(flags, NULL);
|
||||
j = journal_new(flags, NULL, NULL);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -2010,7 +2087,7 @@ _public_ int sd_journal_open_files_fd(sd_journal **ret, int fds[], unsigned n_fd
|
|||
assert_return(n_fds > 0, -EBADF);
|
||||
assert_return(flags == 0, -EINVAL);
|
||||
|
||||
j = journal_new(flags, NULL);
|
||||
j = journal_new(flags, NULL, NULL);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -2082,6 +2159,7 @@ _public_ void sd_journal_close(sd_journal *j) {
|
|||
|
||||
free(j->path);
|
||||
free(j->prefix);
|
||||
free(j->namespace);
|
||||
free(j->unique_field);
|
||||
free(j->fields_buffer);
|
||||
free(j);
|
||||
|
|
|
@ -693,4 +693,5 @@ global:
|
|||
sd_event_source_get_child_process_own;
|
||||
sd_event_source_set_child_process_own;
|
||||
sd_event_source_send_child_signal;
|
||||
sd_journal_open_namespace;
|
||||
} LIBSYSTEMD_243;
|
||||
|
|
|
@ -64,11 +64,13 @@ typedef struct sd_journal sd_journal;
|
|||
|
||||
/* Open flags */
|
||||
enum {
|
||||
SD_JOURNAL_LOCAL_ONLY = 1 << 0,
|
||||
SD_JOURNAL_RUNTIME_ONLY = 1 << 1,
|
||||
SD_JOURNAL_SYSTEM = 1 << 2,
|
||||
SD_JOURNAL_CURRENT_USER = 1 << 3,
|
||||
SD_JOURNAL_OS_ROOT = 1 << 4,
|
||||
SD_JOURNAL_LOCAL_ONLY = 1 << 0,
|
||||
SD_JOURNAL_RUNTIME_ONLY = 1 << 1,
|
||||
SD_JOURNAL_SYSTEM = 1 << 2,
|
||||
SD_JOURNAL_CURRENT_USER = 1 << 3,
|
||||
SD_JOURNAL_OS_ROOT = 1 << 4,
|
||||
SD_JOURNAL_ALL_NAMESPACES = 1 << 5, /* Show all namespaces, not just the default or specified one */
|
||||
SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE = 1 << 6, /* Show default namespace in addition to specified one */
|
||||
|
||||
SD_JOURNAL_SYSTEM_ONLY _sd_deprecated_ = SD_JOURNAL_SYSTEM /* deprecated name */
|
||||
};
|
||||
|
@ -81,6 +83,7 @@ enum {
|
|||
};
|
||||
|
||||
int sd_journal_open(sd_journal **ret, int flags);
|
||||
int sd_journal_open_namespace(sd_journal **ret, const char *name_space, int flags);
|
||||
int sd_journal_open_directory(sd_journal **ret, const char *path, int flags);
|
||||
int sd_journal_open_directory_fd(sd_journal **ret, int fd, int flags);
|
||||
int sd_journal_open_files(sd_journal **ret, const char **paths, int flags);
|
||||
|
|
Loading…
Reference in New Issue