mirror of
https://github.com/systemd/systemd.git
synced 2026-07-24 00:11:06 +00:00
120 lines
3.5 KiB
C
120 lines
3.5 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-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 " STRINGIFY(PROJECT_VERSION) " (" 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));
|
|
}
|
|
}
|
|
|
|
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");
|
|
}
|