mirror of
https://github.com/systemd/systemd
synced 2026-02-26 09:14:46 +01:00
Compare commits
4 Commits
bd7ba0a645
...
3a7486c9fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a7486c9fc | ||
|
|
05f5156ad1 | ||
|
|
3660f0e7da | ||
|
|
a109189fab |
1
TODO
1
TODO
@ -968,7 +968,6 @@ Features:
|
|||||||
* Varlinkification of the following command line tools, to open them up to
|
* Varlinkification of the following command line tools, to open them up to
|
||||||
other programs via IPC:
|
other programs via IPC:
|
||||||
- bootctl
|
- bootctl
|
||||||
- journalctl (allowing journal read access via IPC)
|
|
||||||
- coredumpcl
|
- coredumpcl
|
||||||
- systemd-bless-boot
|
- systemd-bless-boot
|
||||||
- systemd-measure
|
- systemd-measure
|
||||||
|
|||||||
@ -895,6 +895,7 @@ foreach option : ['adm-gid',
|
|||||||
'video-gid',
|
'video-gid',
|
||||||
'wheel-gid',
|
'wheel-gid',
|
||||||
'systemd-journal-gid',
|
'systemd-journal-gid',
|
||||||
|
'systemd-journal-uid',
|
||||||
'systemd-network-uid',
|
'systemd-network-uid',
|
||||||
'systemd-resolve-uid',
|
'systemd-resolve-uid',
|
||||||
'systemd-timesync-uid']
|
'systemd-timesync-uid']
|
||||||
|
|||||||
@ -328,6 +328,8 @@ option('wheel-gid', type : 'integer', value : 0,
|
|||||||
description : 'soft-static allocation for the "wheel" group')
|
description : 'soft-static allocation for the "wheel" group')
|
||||||
option('systemd-journal-gid', type : 'integer', value : 0,
|
option('systemd-journal-gid', type : 'integer', value : 0,
|
||||||
description : 'soft-static allocation for the systemd-journal group')
|
description : 'soft-static allocation for the systemd-journal group')
|
||||||
|
option('systemd-journal-uid', type : 'integer', value : 0,
|
||||||
|
description : 'soft-static allocation for the systemd-journal user')
|
||||||
option('systemd-network-uid', type : 'integer', value : 0,
|
option('systemd-network-uid', type : 'integer', value : 0,
|
||||||
description : 'soft-static allocation for the systemd-network user')
|
description : 'soft-static allocation for the systemd-network user')
|
||||||
option('systemd-resolve-uid', type : 'integer', value : 0,
|
option('systemd-resolve-uid', type : 'integer', value : 0,
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "transaction.h" /* IWYU pragma: keep */
|
#include "transaction.h" /* IWYU pragma: keep */
|
||||||
#include "unit-name.h"
|
#include "unit-name.h"
|
||||||
|
#include "user-util.h"
|
||||||
#include "web-util.h"
|
#include "web-util.h"
|
||||||
|
|
||||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
|
||||||
@ -1649,6 +1650,9 @@ int bus_unit_method_attach_processes(sd_bus_message *message, void *userdata, sd
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return sd_bus_error_setf(reterr_error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by client's UID. Refusing.", pidref->pid);
|
return sd_bus_error_setf(reterr_error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by client's UID. Refusing.", pidref->pid);
|
||||||
|
|
||||||
|
if (!uid_is_valid(u->ref_uid)) /* process_is_owned_by_uid() requires a valid uid */
|
||||||
|
return sd_bus_error_setf(reterr_error, SD_BUS_ERROR_ACCESS_DENIED, "Unit does not have a valid ref_uid, refusing to attach process " PID_FMT ".", pidref->pid);
|
||||||
|
|
||||||
r = process_is_owned_by_uid(pidref, u->ref_uid);
|
r = process_is_owned_by_uid(pidref, u->ref_uid);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return sd_bus_error_set_errnof(reterr_error, r, "Failed to check if process " PID_FMT " is owned by target unit's UID: %m", pidref->pid);
|
return sd_bus_error_set_errnof(reterr_error, r, "Failed to check if process " PID_FMT " is owned by target unit's UID: %m", pidref->pid);
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
#include "chase.h"
|
#include "chase.h"
|
||||||
#include "devnum-util.h"
|
#include "devnum-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "glob-util.h"
|
|
||||||
#include "journal-internal.h"
|
#include "journal-internal.h"
|
||||||
#include "journalctl.h"
|
#include "journalctl.h"
|
||||||
#include "journalctl-filter.h"
|
#include "journalctl-filter.h"
|
||||||
@ -73,112 +72,17 @@ static int add_dmesg(sd_journal *j) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int add_units(sd_journal *j) {
|
static int add_units(sd_journal *j) {
|
||||||
_cleanup_strv_free_ char **patterns = NULL;
|
|
||||||
bool added = false;
|
|
||||||
MatchUnitFlag flags = MATCH_UNIT_ALL;
|
MatchUnitFlag flags = MATCH_UNIT_ALL;
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(j);
|
assert(j);
|
||||||
|
|
||||||
if (strv_isempty(arg_system_units) && strv_isempty(arg_user_units))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* When --directory/-D, --root, --file/-i, or --machine/-M is specified, the opened journal file may
|
/* When --directory/-D, --root, --file/-i, or --machine/-M is specified, the opened journal file may
|
||||||
* be external, and the uid of the systemd-coredump user that generates the coredump entries may be
|
* be external, and the uid of the systemd-coredump user that generates the coredump entries may be
|
||||||
* different from the one in the current host. Let's relax the filter condition in such cases. */
|
* different from the one in the current host. Let's relax the filter condition in such cases. */
|
||||||
if (arg_directory || arg_root || arg_file_stdin || arg_file || arg_machine)
|
if (arg_directory || arg_root || arg_file_stdin || arg_file || arg_machine)
|
||||||
flags &= ~MATCH_UNIT_COREDUMP_UID;
|
flags &= ~MATCH_UNIT_COREDUMP_UID;
|
||||||
|
|
||||||
STRV_FOREACH(i, arg_system_units) {
|
return journal_add_unit_matches(j, flags, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, arg_system_units, arg_user_units);
|
||||||
_cleanup_free_ char *u = NULL;
|
|
||||||
|
|
||||||
r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (string_is_glob(u)) {
|
|
||||||
r = strv_consume(&patterns, TAKE_PTR(u));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
} else {
|
|
||||||
r = add_matches_for_unit_full(j, flags, u);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
r = sd_journal_add_disjunction(j);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strv_isempty(patterns)) {
|
|
||||||
_cleanup_set_free_ Set *units = NULL;
|
|
||||||
char *u;
|
|
||||||
|
|
||||||
r = get_possible_units(j, SYSTEM_UNITS_FULL, patterns, &units);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
SET_FOREACH(u, units) {
|
|
||||||
r = add_matches_for_unit_full(j, flags, u);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
r = sd_journal_add_disjunction(j);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
patterns = strv_free(patterns);
|
|
||||||
|
|
||||||
STRV_FOREACH(i, arg_user_units) {
|
|
||||||
_cleanup_free_ char *u = NULL;
|
|
||||||
|
|
||||||
r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (string_is_glob(u)) {
|
|
||||||
r = strv_consume(&patterns, TAKE_PTR(u));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
} else {
|
|
||||||
r = add_matches_for_user_unit_full(j, flags, u);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
r = sd_journal_add_disjunction(j);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strv_isempty(patterns)) {
|
|
||||||
_cleanup_set_free_ Set *units = NULL;
|
|
||||||
char *u;
|
|
||||||
|
|
||||||
r = get_possible_units(j, USER_UNITS_FULL, patterns, &units);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
SET_FOREACH(u, units) {
|
|
||||||
r = add_matches_for_user_unit_full(j, flags, u);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
r = sd_journal_add_disjunction(j);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Complain if the user request matches but nothing whatsoever was found, since otherwise everything
|
|
||||||
* would be matched. */
|
|
||||||
if (!added)
|
|
||||||
return -ENODATA;
|
|
||||||
|
|
||||||
return sd_journal_add_conjunction(j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_syslog_identifier(sd_journal *j) {
|
static int add_syslog_identifier(sd_journal *j) {
|
||||||
|
|||||||
@ -177,6 +177,108 @@ int get_possible_units(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int journal_add_unit_matches(sd_journal *j, MatchUnitFlag flags, UnitNameMangle mangle_flags, char **system_units, char **user_units) {
|
||||||
|
_cleanup_strv_free_ char **patterns = NULL;
|
||||||
|
bool added = false;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(j);
|
||||||
|
|
||||||
|
if (strv_isempty(system_units) && strv_isempty(user_units))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
STRV_FOREACH(i, system_units) {
|
||||||
|
_cleanup_free_ char *u = NULL;
|
||||||
|
|
||||||
|
r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | mangle_flags, &u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (string_is_glob(u)) {
|
||||||
|
r = strv_consume(&patterns, TAKE_PTR(u));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
r = add_matches_for_unit_full(j, flags, u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
r = sd_journal_add_disjunction(j);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strv_isempty(patterns)) {
|
||||||
|
_cleanup_set_free_ Set *units = NULL;
|
||||||
|
|
||||||
|
r = get_possible_units(j, SYSTEM_UNITS_FULL, patterns, &units);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
char *u;
|
||||||
|
SET_FOREACH(u, units) {
|
||||||
|
r = add_matches_for_unit_full(j, flags, u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
r = sd_journal_add_disjunction(j);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
patterns = strv_free(patterns);
|
||||||
|
|
||||||
|
STRV_FOREACH(i, user_units) {
|
||||||
|
_cleanup_free_ char *u = NULL;
|
||||||
|
|
||||||
|
r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | mangle_flags, &u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (string_is_glob(u)) {
|
||||||
|
r = strv_consume(&patterns, TAKE_PTR(u));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
r = add_matches_for_user_unit_full(j, flags, u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
r = sd_journal_add_disjunction(j);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strv_isempty(patterns)) {
|
||||||
|
_cleanup_set_free_ Set *units = NULL;
|
||||||
|
|
||||||
|
r = get_possible_units(j, USER_UNITS_FULL, patterns, &units);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
char *u;
|
||||||
|
SET_FOREACH(u, units) {
|
||||||
|
r = add_matches_for_user_unit_full(j, flags, u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
r = sd_journal_add_disjunction(j);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Complain if the user request matches but nothing whatsoever was found, since otherwise everything
|
||||||
|
* would be matched. */
|
||||||
|
if (!added)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
return sd_journal_add_conjunction(j);
|
||||||
|
}
|
||||||
|
|
||||||
int acquire_unit(sd_journal *j, const char *option_name, const char **ret_unit, LogIdType *ret_type) {
|
int acquire_unit(sd_journal *j, const char *option_name, const char **ret_unit, LogIdType *ret_type) {
|
||||||
size_t n;
|
size_t n;
|
||||||
int r;
|
int r;
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "shared-forward.h"
|
#include "shared-forward.h"
|
||||||
#include "logs-show.h"
|
#include "logs-show.h"
|
||||||
|
#include "unit-name.h"
|
||||||
|
|
||||||
/* The lists below are supposed to return the superset of unit names possibly matched by rules added with
|
/* The lists below are supposed to return the superset of unit names possibly matched by rules added with
|
||||||
* add_matches_for_unit() and add_matches_for_user_unit(). */
|
* add_matches_for_unit() and add_matches_for_user_unit(). */
|
||||||
@ -31,5 +32,6 @@ int acquire_journal(sd_journal **ret);
|
|||||||
bool journal_boot_has_effect(sd_journal *j);
|
bool journal_boot_has_effect(sd_journal *j);
|
||||||
int journal_acquire_boot(sd_journal *j);
|
int journal_acquire_boot(sd_journal *j);
|
||||||
int get_possible_units(sd_journal *j, const char *fields, char * const *patterns, Set **ret);
|
int get_possible_units(sd_journal *j, const char *fields, char * const *patterns, Set **ret);
|
||||||
|
int journal_add_unit_matches(sd_journal *j, MatchUnitFlag flags, UnitNameMangle mangle_flags, char **system_units, char **user_units);
|
||||||
int acquire_unit(sd_journal *j, const char *option_name, const char **ret_unit, LogIdType *ret_type);
|
int acquire_unit(sd_journal *j, const char *option_name, const char **ret_unit, LogIdType *ret_type);
|
||||||
int journal_acquire_invocation(sd_journal *j);
|
int journal_acquire_invocation(sd_journal *j);
|
||||||
|
|||||||
114
src/journal/journalctl-varlink-server.c
Normal file
114
src/journal/journalctl-varlink-server.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include "sd-journal.h"
|
||||||
|
#include "sd-varlink.h"
|
||||||
|
|
||||||
|
#include "journal-internal.h"
|
||||||
|
#include "journalctl-util.h"
|
||||||
|
#include "journalctl-varlink-server.h"
|
||||||
|
#include "json-util.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "logs-show.h"
|
||||||
|
#include "output-mode.h"
|
||||||
|
#include "strv.h"
|
||||||
|
#include "varlink-util.h"
|
||||||
|
|
||||||
|
typedef struct GetEntriesParameters {
|
||||||
|
char **units;
|
||||||
|
char **user_units;
|
||||||
|
const char *namespace;
|
||||||
|
int priority;
|
||||||
|
uint64_t limit;
|
||||||
|
} GetEntriesParameters;
|
||||||
|
|
||||||
|
static void get_entries_parameters_done(GetEntriesParameters *p) {
|
||||||
|
assert(p);
|
||||||
|
p->units = strv_free(p->units);
|
||||||
|
p->user_units = strv_free(p->user_units);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vl_method_get_entries(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||||
|
|
||||||
|
static const sd_json_dispatch_field dispatch_table[] = {
|
||||||
|
{ "units", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, offsetof(GetEntriesParameters, units), 0 },
|
||||||
|
{ "userUnits", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, offsetof(GetEntriesParameters, user_units), 0 },
|
||||||
|
{ "namespace", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(GetEntriesParameters, namespace), 0 },
|
||||||
|
{ "priority", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_log_level, offsetof(GetEntriesParameters, priority), 0 },
|
||||||
|
{ "limit", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(GetEntriesParameters, limit), 0 },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
_cleanup_(get_entries_parameters_done) GetEntriesParameters p = {
|
||||||
|
.priority = -1,
|
||||||
|
};
|
||||||
|
_cleanup_(sd_journal_closep) sd_journal *j = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(FLAGS_SET(flags, SD_VARLINK_METHOD_MORE));
|
||||||
|
|
||||||
|
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* systemd ships with sensible defaults for the system/user services and the socket permissions so we
|
||||||
|
* do not need to do extra sd_varlink_get_peer_uid() or policykit checks here */
|
||||||
|
r = sd_journal_open_namespace(&j, p.namespace, SD_JOURNAL_LOCAL_ONLY | SD_JOURNAL_ASSUME_IMMUTABLE);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to open journal: %m");
|
||||||
|
|
||||||
|
r = journal_add_unit_matches(j, MATCH_UNIT_ALL, /* mangle_flags= */ 0, p.units, p.user_units);
|
||||||
|
if (r == -ENODATA)
|
||||||
|
return sd_varlink_error(link, SD_VARLINK_ERROR_INVALID_PARAMETER, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add unit matches: %m");
|
||||||
|
|
||||||
|
if (p.priority >= 0) {
|
||||||
|
for (int i = 0; i <= p.priority; i++) {
|
||||||
|
r = journal_add_matchf(j, "PRIORITY=%d", i);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add priority match: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_add_conjunction(j);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this simulates "journalctl -n $p.limit" */
|
||||||
|
r = sd_journal_seek_tail(j);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to seek to tail: %m");
|
||||||
|
|
||||||
|
/* FIXME: this restriction should be removed eventually */
|
||||||
|
if (p.limit > 10000)
|
||||||
|
return sd_varlink_error_invalid_parameter_name(link, "limit");
|
||||||
|
|
||||||
|
uint64_t n = p.limit == 0 ? 100 : p.limit;
|
||||||
|
|
||||||
|
r = varlink_set_sentinel(link, "io.systemd.JournalAccess.NoEntries");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < n; i++) {
|
||||||
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *entry = NULL;
|
||||||
|
|
||||||
|
r = sd_journal_previous(j);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to iterate journal: %m");
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
r = journal_entry_to_json(j, OUTPUT_SHOW_ALL, /* output_fields= */ NULL, &entry);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
continue; /* skip corrupted entry */
|
||||||
|
|
||||||
|
r = sd_varlink_replybo(link, SD_JSON_BUILD_PAIR("entry", SD_JSON_BUILD_VARIANT(entry)));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
6
src/journal/journalctl-varlink-server.h
Normal file
6
src/journal/journalctl-varlink-server.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sd-varlink.h"
|
||||||
|
|
||||||
|
int vl_method_get_entries(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||||
@ -4,6 +4,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
#include "sd-journal.h"
|
#include "sd-journal.h"
|
||||||
|
#include "sd-varlink.h"
|
||||||
|
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include "dissect-image.h"
|
#include "dissect-image.h"
|
||||||
@ -17,6 +18,7 @@
|
|||||||
#include "journalctl-misc.h"
|
#include "journalctl-misc.h"
|
||||||
#include "journalctl-show.h"
|
#include "journalctl-show.h"
|
||||||
#include "journalctl-varlink.h"
|
#include "journalctl-varlink.h"
|
||||||
|
#include "journalctl-varlink-server.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "loop-util.h"
|
#include "loop-util.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
@ -35,6 +37,8 @@
|
|||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "syslog-util.h"
|
#include "syslog-util.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
#include "varlink-io.systemd.JournalAccess.h"
|
||||||
|
#include "varlink-util.h"
|
||||||
|
|
||||||
#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
|
#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
|
||||||
|
|
||||||
@ -107,6 +111,7 @@ pcre2_code *arg_compiled_pattern = NULL;
|
|||||||
PatternCompileCase arg_case = PATTERN_COMPILE_CASE_AUTO;
|
PatternCompileCase arg_case = PATTERN_COMPILE_CASE_AUTO;
|
||||||
ImagePolicy *arg_image_policy = NULL;
|
ImagePolicy *arg_image_policy = NULL;
|
||||||
bool arg_synchronize_on_exit = false;
|
bool arg_synchronize_on_exit = false;
|
||||||
|
static bool arg_varlink = false;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_cursor, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_cursor, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_cursor_file, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_cursor_file, freep);
|
||||||
@ -324,6 +329,29 @@ static int help(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vl_server(void) {
|
||||||
|
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = varlink_server_new(&varlink_server, /* flags= */ 0, /* userdata= */ NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||||
|
|
||||||
|
r = sd_varlink_server_add_interface(varlink_server, &vl_interface_io_systemd_JournalAccess);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add Varlink interface: %m");
|
||||||
|
|
||||||
|
r = sd_varlink_server_bind_method(varlink_server, "io.systemd.JournalAccess.GetEntries", vl_method_get_entries);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to bind Varlink method: %m");
|
||||||
|
|
||||||
|
r = sd_varlink_server_loop_auto(varlink_server);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_argv(int argc, char *argv[]) {
|
static int parse_argv(int argc, char *argv[]) {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -453,6 +481,15 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
|
|
||||||
|
r = sd_varlink_invocation(SD_VARLINK_ALLOW_ACCEPT);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to check if invoked in Varlink mode: %m");
|
||||||
|
if (r > 0) {
|
||||||
|
arg_varlink = true;
|
||||||
|
arg_pager_flags |= PAGER_DISABLE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:g:c:S:U:t:T:u:INF:xrM:i:W", options, NULL)) >= 0)
|
while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:g:c:S:U:t:T:u:INF:xrM:i:W", options, NULL)) >= 0)
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@ -1094,6 +1131,9 @@ static int run(int argc, char *argv[]) {
|
|||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (arg_varlink)
|
||||||
|
return vl_server();
|
||||||
|
|
||||||
r = strv_copy_unless_empty(strv_skip(argv, optind), &args);
|
r = strv_copy_unless_empty(strv_skip(argv, optind), &args);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include "sd-event.h"
|
|
||||||
|
|
||||||
#include "journald-manager.h"
|
#include "journald-manager.h"
|
||||||
#include "journald-sync.h"
|
#include "journald-sync.h"
|
||||||
#include "journald-varlink.h"
|
#include "journald-varlink.h"
|
||||||
|
|||||||
@ -41,6 +41,7 @@ journalctl_sources = files(
|
|||||||
'journalctl-show.c',
|
'journalctl-show.c',
|
||||||
'journalctl-util.c',
|
'journalctl-util.c',
|
||||||
'journalctl-varlink.c',
|
'journalctl-varlink.c',
|
||||||
|
'journalctl-varlink-server.c',
|
||||||
)
|
)
|
||||||
|
|
||||||
if get_option('link-journalctl-shared')
|
if get_option('link-journalctl-shared')
|
||||||
|
|||||||
@ -1193,16 +1193,7 @@ static int update_json_data_split(
|
|||||||
return update_json_data(h, flags, name, eq + 1, size - fieldlen - 1);
|
return update_json_data(h, flags, name, eq + 1, size - fieldlen - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int output_json(
|
int journal_entry_to_json(sd_journal *j, OutputFlags flags, const Set *output_fields, sd_json_variant **ret) {
|
||||||
FILE *f,
|
|
||||||
sd_journal *j,
|
|
||||||
OutputMode mode,
|
|
||||||
unsigned n_columns,
|
|
||||||
OutputFlags flags,
|
|
||||||
const Set *output_fields,
|
|
||||||
const size_t highlight[2],
|
|
||||||
dual_timestamp *previous_display_ts, /* unused */
|
|
||||||
sd_id128_t *previous_boot_id) { /* unused */
|
|
||||||
|
|
||||||
char usecbuf[CONST_MAX(DECIMAL_STR_MAX(usec_t), DECIMAL_STR_MAX(uint64_t))];
|
char usecbuf[CONST_MAX(DECIMAL_STR_MAX(usec_t), DECIMAL_STR_MAX(uint64_t))];
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *object = NULL;
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *object = NULL;
|
||||||
@ -1217,6 +1208,7 @@ static int output_json(
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(j);
|
assert(j);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
(void) sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : JSON_THRESHOLD);
|
(void) sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : JSON_THRESHOLD);
|
||||||
|
|
||||||
@ -1323,6 +1315,28 @@ static int output_json(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to allocate JSON object: %m");
|
return log_error_errno(r, "Failed to allocate JSON object: %m");
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(object);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int output_json(
|
||||||
|
FILE *f,
|
||||||
|
sd_journal *j,
|
||||||
|
OutputMode mode,
|
||||||
|
unsigned n_columns,
|
||||||
|
OutputFlags flags,
|
||||||
|
const Set *output_fields,
|
||||||
|
const size_t highlight[2],
|
||||||
|
dual_timestamp *previous_display_ts, /* unused */
|
||||||
|
sd_id128_t *previous_boot_id) { /* unused */
|
||||||
|
|
||||||
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *object = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = journal_entry_to_json(j, flags, output_fields, &object);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
return sd_json_variant_dump(object,
|
return sd_json_variant_dump(object,
|
||||||
output_mode_to_json_format_flags(mode) |
|
output_mode_to_json_format_flags(mode) |
|
||||||
(FLAGS_SET(flags, OUTPUT_COLOR) ? SD_JSON_FORMAT_COLOR : 0),
|
(FLAGS_SET(flags, OUTPUT_COLOR) ? SD_JSON_FORMAT_COLOR : 0),
|
||||||
|
|||||||
@ -81,6 +81,8 @@ void json_escape(
|
|||||||
size_t l,
|
size_t l,
|
||||||
OutputFlags flags);
|
OutputFlags flags);
|
||||||
|
|
||||||
|
int journal_entry_to_json(sd_journal *j, OutputFlags flags, const Set *output_fields, sd_json_variant **ret);
|
||||||
|
|
||||||
int discover_next_id(
|
int discover_next_id(
|
||||||
sd_journal *j,
|
sd_journal *j,
|
||||||
LogIdType type,
|
LogIdType type,
|
||||||
|
|||||||
@ -205,6 +205,7 @@ shared_sources = files(
|
|||||||
'varlink-io.systemd.Hostname.c',
|
'varlink-io.systemd.Hostname.c',
|
||||||
'varlink-io.systemd.Import.c',
|
'varlink-io.systemd.Import.c',
|
||||||
'varlink-io.systemd.Journal.c',
|
'varlink-io.systemd.Journal.c',
|
||||||
|
'varlink-io.systemd.JournalAccess.c',
|
||||||
'varlink-io.systemd.Login.c',
|
'varlink-io.systemd.Login.c',
|
||||||
'varlink-io.systemd.Machine.c',
|
'varlink-io.systemd.Machine.c',
|
||||||
'varlink-io.systemd.MachineImage.c',
|
'varlink-io.systemd.MachineImage.c',
|
||||||
|
|||||||
30
src/shared/varlink-io.systemd.JournalAccess.c
Normal file
30
src/shared/varlink-io.systemd.JournalAccess.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include "varlink-io.systemd.JournalAccess.h"
|
||||||
|
|
||||||
|
static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||||
|
GetEntries,
|
||||||
|
SD_VARLINK_REQUIRES_MORE,
|
||||||
|
SD_VARLINK_FIELD_COMMENT("Show messages for the specified systemd units (e.g. ['foo.service'])."),
|
||||||
|
SD_VARLINK_DEFINE_INPUT(units, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY),
|
||||||
|
SD_VARLINK_FIELD_COMMENT("Show messages for the specified user units (e.g. ['foo.service'])."),
|
||||||
|
SD_VARLINK_DEFINE_INPUT(userUnits, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY),
|
||||||
|
SD_VARLINK_FIELD_COMMENT("If specified, shows the log data of the specified namespace, otherwise the default namespace."),
|
||||||
|
SD_VARLINK_DEFINE_INPUT(namespace, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||||
|
SD_VARLINK_FIELD_COMMENT("Filter output by message priorities or priority ranges (i.e. between 0/'emerg' and 7/'debug')"),
|
||||||
|
SD_VARLINK_DEFINE_INPUT(priority, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||||
|
SD_VARLINK_FIELD_COMMENT("Maximum number of entries to return. Defaults to 100, capped at 10000."),
|
||||||
|
SD_VARLINK_DEFINE_INPUT(limit, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||||
|
SD_VARLINK_FIELD_COMMENT("The journal entry in flat JSON format, matching journalctl --output=json."),
|
||||||
|
SD_VARLINK_DEFINE_OUTPUT(entry, SD_VARLINK_OBJECT, SD_VARLINK_NULLABLE));
|
||||||
|
|
||||||
|
static SD_VARLINK_DEFINE_ERROR(NoEntries);
|
||||||
|
|
||||||
|
SD_VARLINK_DEFINE_INTERFACE(
|
||||||
|
io_systemd_JournalAccess,
|
||||||
|
"io.systemd.JournalAccess",
|
||||||
|
SD_VARLINK_INTERFACE_COMMENT("Journal log read APIs"),
|
||||||
|
SD_VARLINK_SYMBOL_COMMENT("Retrieve journal log entries, optionally filtered by unit, priority, etc."),
|
||||||
|
&vl_method_GetEntries,
|
||||||
|
SD_VARLINK_SYMBOL_COMMENT("No journal entries matched the specified filters."),
|
||||||
|
&vl_error_NoEntries);
|
||||||
6
src/shared/varlink-io.systemd.JournalAccess.h
Normal file
6
src/shared/varlink-io.systemd.JournalAccess.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sd-varlink-idl.h"
|
||||||
|
|
||||||
|
extern const sd_varlink_interface vl_interface_io_systemd_JournalAccess;
|
||||||
@ -6,3 +6,4 @@
|
|||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
g systemd-journal {{SYSTEMD_JOURNAL_GID}} -
|
g systemd-journal {{SYSTEMD_JOURNAL_GID}} -
|
||||||
|
u! systemd-journal {{SYSTEMD_JOURNAL_UID}} "systemd Journal"
|
||||||
|
|||||||
59
test/units/TEST-04-JOURNAL.journalctl-varlink.sh
Executable file
59
test/units/TEST-04-JOURNAL.journalctl-varlink.sh
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
VARLINK_SOCKET="/run/systemd/io.systemd.JournalAccess"
|
||||||
|
|
||||||
|
# ensure the varlink basics work
|
||||||
|
varlinkctl list-interfaces "$VARLINK_SOCKET" | grep io.systemd.JournalAccess
|
||||||
|
varlinkctl introspect "$VARLINK_SOCKET" | grep "method GetEntries("
|
||||||
|
|
||||||
|
# lets start with a basic log entry
|
||||||
|
TAG="$(systemd-id128 new)"
|
||||||
|
echo "varlink-test-message" | systemd-cat -t "$TAG"
|
||||||
|
systemd-cat -t "$TAG" -p warning echo "varlink-test-warning"
|
||||||
|
journalctl --sync
|
||||||
|
|
||||||
|
# most basic call works
|
||||||
|
varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{}' | jq --seq .
|
||||||
|
# validate the JSON has some basic properties (similar to journalctls json output)
|
||||||
|
varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{}' | jq --seq '.entry | {MESSAGE, PRIORITY, _UID}'
|
||||||
|
|
||||||
|
# check that default limit works (100), we don't know how many entries we have so we just check
|
||||||
|
# bounds
|
||||||
|
ENTRIES=$(varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{}' | wc -l)
|
||||||
|
test "$ENTRIES" -gt 0
|
||||||
|
test "$ENTRIES" -le 100
|
||||||
|
|
||||||
|
# check explicit limit
|
||||||
|
ENTRIES=$(varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{"limit": 3}' | wc -l)
|
||||||
|
test "$ENTRIES" -le 3
|
||||||
|
|
||||||
|
# check unit filter: use transient units to get deterministic results
|
||||||
|
UNIT_NAME_1="test-journalctl-varlink-1-$RANDOM.service"
|
||||||
|
systemd-run --unit="$UNIT_NAME_1" --wait bash -c 'echo hello-from-varlink-test-1'
|
||||||
|
UNIT_NAME_2="test-journalctl-varlink-2-$RANDOM.service"
|
||||||
|
systemd-run --unit="$UNIT_NAME_2" --wait bash -c 'echo hello-from-varlink-test-2'
|
||||||
|
journalctl --sync
|
||||||
|
|
||||||
|
# single unit filter
|
||||||
|
varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries "{\"units\": [\"$UNIT_NAME_1\"]}" | grep -q "hello-from-varlink-test-1"
|
||||||
|
(! varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries "{\"units\": [\"$UNIT_NAME_1\"]}" | grep "hello-from-varlink-test-2")
|
||||||
|
# multi unit filter
|
||||||
|
varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries "{\"units\": [\"$UNIT_NAME_1\", \"$UNIT_NAME_2\"]}" | grep -q "hello-from-varlink-test-1"
|
||||||
|
varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries "{\"units\": [\"$UNIT_NAME_1\", \"$UNIT_NAME_2\"]}" | grep -q "hello-from-varlink-test-2"
|
||||||
|
|
||||||
|
# check priority filter: priority 4 (warning) should include our warning message
|
||||||
|
varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{"priority": 4, "limit": 1000}' | grep -q "varlink-test-warning"
|
||||||
|
# check priority filter: priority 3 (error) should NOT include our warning (priority 4)
|
||||||
|
(! varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{"priority": 3, "limit": 1000}' | grep "varlink-test-warning")
|
||||||
|
|
||||||
|
# invalid parameter: limit over 10000 should fail
|
||||||
|
(! varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{"limit": 99999}')
|
||||||
|
|
||||||
|
# invalid parameter: priority over 7 should fail
|
||||||
|
(! varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{"priority": 99}')
|
||||||
|
|
||||||
|
# NoEntries error is raised if there is no result
|
||||||
|
(! varlinkctl call --more "$VARLINK_SOCKET" io.systemd.JournalAccess.GetEntries '{"units": ["nonexistent-unit-that-should-have-no-entries.service"]}' 2>&1 | grep io.systemd.JournalAccess.NoEntries )
|
||||||
34
test/units/TEST-07-PID1.attach_processes.sh
Executable file
34
test/units/TEST-07-PID1.attach_processes.sh
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
# Assert when calling AttachProcesses on a unit without ref_uid set
|
||||||
|
|
||||||
|
at_exit() {
|
||||||
|
set +e
|
||||||
|
|
||||||
|
systemctl stop attach_and_barf.service
|
||||||
|
rm -f /run/systemd/system/attach_and_barf.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
}
|
||||||
|
|
||||||
|
trap at_exit EXIT
|
||||||
|
|
||||||
|
mkdir -p /run/systemd/system
|
||||||
|
|
||||||
|
cat >/run/systemd/system/attach_and_barf.service <<EOF
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Delegate=yes
|
||||||
|
ExecStart=sleep infinity
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl start attach_and_barf.service
|
||||||
|
run0 -u testuser \
|
||||||
|
busctl --system call \
|
||||||
|
org.freedesktop.systemd1 \
|
||||||
|
/org/freedesktop/systemd1 \
|
||||||
|
org.freedesktop.systemd1.Manager \
|
||||||
|
AttachProcessesToUnit \
|
||||||
|
"ssau" "attach_and_barf.service" "" 1 0 |& grep -F "Access denied" &>/dev/null
|
||||||
@ -439,6 +439,11 @@ units = [
|
|||||||
'file' : 'systemd-journal-upload.service.in',
|
'file' : 'systemd-journal-upload.service.in',
|
||||||
'conditions' : ['ENABLE_REMOTE', 'HAVE_LIBCURL'],
|
'conditions' : ['ENABLE_REMOTE', 'HAVE_LIBCURL'],
|
||||||
},
|
},
|
||||||
|
{ 'file' : 'systemd-journalctl@.service' },
|
||||||
|
{
|
||||||
|
'file' : 'systemd-journalctl.socket',
|
||||||
|
'symlinks' : ['sockets.target.wants/'],
|
||||||
|
},
|
||||||
{ 'file' : 'systemd-journald-audit.socket' },
|
{ 'file' : 'systemd-journald-audit.socket' },
|
||||||
{
|
{
|
||||||
'file' : 'systemd-journald-dev-log.socket',
|
'file' : 'systemd-journald-dev-log.socket',
|
||||||
|
|||||||
23
units/systemd-journalctl.socket
Normal file
23
units/systemd-journalctl.socket
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
#
|
||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Journal Log Access Socket
|
||||||
|
Documentation=man:journalctl(1)
|
||||||
|
DefaultDependencies=no
|
||||||
|
Before=sockets.target
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=/run/systemd/io.systemd.JournalAccess
|
||||||
|
Symlinks=/run/varlink/registry/io.systemd.JournalAccess
|
||||||
|
FileDescriptorName=varlink
|
||||||
|
SocketGroup=systemd-journal
|
||||||
|
SocketMode=0660
|
||||||
|
Accept=yes
|
||||||
|
MaxConnectionsPerSource=16
|
||||||
19
units/systemd-journalctl@.service
Normal file
19
units/systemd-journalctl@.service
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
#
|
||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Journal Log Access Service
|
||||||
|
Documentation=man:journalctl(1)
|
||||||
|
DefaultDependencies=no
|
||||||
|
Conflicts=shutdown.target
|
||||||
|
Before=shutdown.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=journalctl
|
||||||
|
User=systemd-journal
|
||||||
@ -56,6 +56,11 @@ units = [
|
|||||||
},
|
},
|
||||||
{ 'file' : 'systemd-ask-password@.service' },
|
{ 'file' : 'systemd-ask-password@.service' },
|
||||||
{ 'file' : 'systemd-exit.service' },
|
{ 'file' : 'systemd-exit.service' },
|
||||||
|
{ 'file' : 'systemd-journalctl@.service' },
|
||||||
|
{
|
||||||
|
'file' : 'systemd-journalctl.socket',
|
||||||
|
'symlinks' : ['sockets.target.wants/'],
|
||||||
|
},
|
||||||
{ 'file' : 'systemd-tmpfiles-clean.service' },
|
{ 'file' : 'systemd-tmpfiles-clean.service' },
|
||||||
{ 'file' : 'systemd-tmpfiles-clean.timer' },
|
{ 'file' : 'systemd-tmpfiles-clean.timer' },
|
||||||
{ 'file' : 'systemd-tmpfiles-setup.service' },
|
{ 'file' : 'systemd-tmpfiles-setup.service' },
|
||||||
|
|||||||
20
units/user/systemd-journalctl.socket
Normal file
20
units/user/systemd-journalctl.socket
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
#
|
||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Journal Log Access Socket
|
||||||
|
Documentation=man:journalctl(1)
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=%t/systemd/io.systemd.JournalAccess
|
||||||
|
Symlinks=%t/varlink/registry/io.systemd.JournalAccess
|
||||||
|
FileDescriptorName=varlink
|
||||||
|
SocketMode=0600
|
||||||
|
Accept=yes
|
||||||
|
MaxConnectionsPerSource=16
|
||||||
15
units/user/systemd-journalctl@.service
Normal file
15
units/user/systemd-journalctl@.service
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
#
|
||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Journal Log Access Service
|
||||||
|
Documentation=man:journalctl(1)
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=journalctl
|
||||||
Loading…
x
Reference in New Issue
Block a user