Files
systemd/src/core/manager-dump.c
T
Daan De Meyer 4ea4abb651 core: Remove circular dependencies between headers
Currently there are various circular dependencies between headers
in core/. Let's get rid of these by making judicious use of forward
declarations and moving includes into implementation files instead of
having them in header files.

Getting rid of circular header includes simplifies the code and makes
various clang based tooling such as iwyu work much better on our code.

The most important change is getting rid of the manager.h include in
unit.h which is possible thanks to the previous commits. We also move
the OOMPolicy and StatusType enums to unit.h to remove the need for
other unit headers to include manager.h to get access to these enums.
2025-04-23 10:33:35 +02:00

124 lines
3.7 KiB
C

/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "build.h"
#include "fd-util.h"
#include "fileio.h"
#include "hashmap.h"
#include "manager.h"
#include "manager-dump.h"
#include "memstream-util.h"
#include "unit-serialize.h"
#include "version.h"
void manager_dump_jobs(Manager *s, FILE *f, char **patterns, const char *prefix) {
Job *j;
assert(s);
assert(f);
HASHMAP_FOREACH(j, s->jobs) {
if (!strv_fnmatch_or_empty(patterns, j->unit->id, FNM_NOESCAPE))
continue;
job_dump(j, f, prefix);
}
}
int manager_get_dump_jobs_string(Manager *m, char **patterns, const char *prefix, char **ret) {
_cleanup_(memstream_done) MemStream ms = {};
FILE *f;
assert(m);
assert(ret);
f = memstream_init(&ms);
if (!f)
return -errno;
manager_dump_jobs(m, f, patterns, prefix);
return memstream_finalize(&ms, ret, NULL);
}
void manager_dump_units(Manager *s, FILE *f, char **patterns, const char *prefix) {
Unit *u;
const char *t;
assert(s);
assert(f);
HASHMAP_FOREACH_KEY(u, t, s->units) {
if (u->id != t)
continue;
if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
continue;
unit_dump(u, f, prefix);
}
}
static void manager_dump_header(Manager *m, FILE *f, const char *prefix) {
/* NB: this is a debug interface for developers. It's not supposed to be machine readable or be
* stable between versions. We take the liberty to restructure it entirely between versions and
* add/remove fields at will. */
fprintf(f, "%sManager: systemd " PROJECT_VERSION_FULL " (" GIT_VERSION ")\n", strempty(prefix));
fprintf(f, "%sFeatures: %s\n", strempty(prefix), systemd_features);
for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
const dual_timestamp *t = m->timestamps + q;
if (dual_timestamp_is_set(t))
fprintf(f, "%sTimestamp %s: %s\n",
strempty(prefix),
manager_timestamp_to_string(q),
timestamp_is_set(t->realtime) ? FORMAT_TIMESTAMP(t->realtime) :
FORMAT_TIMESPAN(t->monotonic, 1));
}
for (const char *n = sd_bus_track_first(m->subscribed); n; n = sd_bus_track_next(m->subscribed))
fprintf(f, "%sSubscribed: %s\n", strempty(prefix), n);
}
void manager_dump(Manager *m, FILE *f, char **patterns, const char *prefix) {
assert(m);
assert(f);
/* If no pattern is provided, dump the full manager state including the manager version, features and
* so on. Otherwise limit the dump to the units/jobs matching the specified patterns. */
if (!patterns)
manager_dump_header(m, f, prefix);
manager_dump_units(m, f, patterns, prefix);
manager_dump_jobs(m, f, patterns, prefix);
}
int manager_get_dump_string(Manager *m, char **patterns, char **ret) {
_cleanup_(memstream_done) MemStream ms = {};
FILE *f;
assert(m);
assert(ret);
f = memstream_init(&ms);
if (!f)
return -errno;
manager_dump(m, f, patterns, NULL);
return memstream_finalize(&ms, ret, NULL);
}
void manager_test_summary(Manager *m) {
assert(m);
printf("-> By units:\n");
manager_dump_units(m, stdout, /* patterns= */ NULL, "\t");
printf("-> By jobs:\n");
manager_dump_jobs(m, stdout, /* patterns= */ NULL, "\t");
}