usec_t initrd_time;
usec_t userspace_time;
usec_t finish_time;
+ usec_t security_start_time;
+ usec_t security_finish_time;
usec_t generators_start_time;
usec_t generators_finish_time;
usec_t unitsload_start_time;
usec_t unitsload_finish_time;
};
-struct unit_info {
- const char *id;
- const char *description;
- const char *load_state;
- const char *active_state;
- const char *sub_state;
- const char *following;
- const char *unit_path;
- uint32_t job_id;
- const char *job_type;
- const char *job_path;
-};
-
struct unit_times {
char *name;
usec_t activating;
free(t);
}
-static int bus_parse_unit_info(sd_bus_message *message, struct unit_info *u) {
- int r = 0;
-
- assert(message);
- assert(u);
-
- r = sd_bus_message_read(message, "(ssssssouso)", &u->id,
- &u->description,
- &u->load_state,
- &u->active_state,
- &u->sub_state,
- &u->following,
- &u->unit_path,
- &u->job_id,
- &u->job_type,
- &u->job_path);
- if (r < 0)
- return bus_log_parse_error(r);
-
- return r;
-}
-
static int acquire_time_data(sd_bus *bus, struct unit_times **out) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- int r, c = 0, n_units = 0;
+ int r, c = 0;
struct unit_times *unit_times = NULL;
- struct unit_info u;
+ size_t size = 0;
+ UnitInfo u;
r = sd_bus_call_method(
bus,
while ((r = bus_parse_unit_info(reply, &u)) > 0) {
struct unit_times *t;
- if (r < 0)
+ if (!GREEDY_REALLOC(unit_times, size, c+1)) {
+ r = log_oom();
goto fail;
-
- if (c >= n_units) {
- struct unit_times *w;
-
- n_units = MAX(2*c, 16);
- w = realloc(unit_times, sizeof(struct unit_times) * n_units);
-
- if (!w) {
- r = log_oom();
- goto fail;
- }
-
- unit_times = w;
}
+
t = unit_times+c;
t->name = NULL;
}
c++;
}
+ if (r < 0) {
+ bus_log_parse_error(r);
+ goto fail;
+ }
*out = unit_times;
return c;
"org.freedesktop.systemd1.Manager",
"FinishTimestampMonotonic",
×.finish_time) < 0 ||
+ bus_get_uint64_property(bus,
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "SecurityStartTimestampMonotonic",
+ ×.security_start_time) < 0 ||
+ bus_get_uint64_property(bus,
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "SecurityFinishTimestampMonotonic",
+ ×.security_finish_time) < 0 ||
bus_get_uint64_property(bus,
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
" rect.firmware { fill: rgb(150,150,150); fill-opacity: 0.7; }\n"
" rect.loader { fill: rgb(150,150,150); fill-opacity: 0.7; }\n"
" rect.userspace { fill: rgb(150,150,150); fill-opacity: 0.7; }\n"
+ " rect.security { fill: rgb(144,238,144); fill-opacity: 0.7; }\n"
" rect.generators { fill: rgb(102,204,255); fill-opacity: 0.7; }\n"
" rect.unitsload { fill: rgb( 82,184,255); fill-opacity: 0.7; }\n"
" rect.box { fill: rgb(240,240,240); stroke: rgb(192,192,192); }\n"
y++;
}
svg_bar("active", boot->userspace_time, boot->finish_time, y);
+ svg_bar("security", boot->security_start_time, boot->security_finish_time, y);
svg_bar("generators", boot->generators_start_time, boot->generators_finish_time, y);
svg_bar("unitsload", boot->unitsload_start_time, boot->unitsload_finish_time, y);
svg_text(true, boot->userspace_time, y, "systemd");
svg_bar("deactivating", 0, 300000, y);
svg_text(true, 400000, y, "Deactivating");
y++;
+ svg_bar("security", 0, 300000, y);
+ svg_text(true, 400000, y, "Setting up security module");
+ y++;
svg_bar("generators", 0, 300000, y);
svg_text(true, 400000, y, "Generators");
y++;
return 0;
}
-static int graph_one_property(sd_bus *bus, const struct unit_info *u, const char* prop, const char *color, char* patterns[]) {
+static int graph_one_property(sd_bus *bus, const UnitInfo *u, const char* prop, const char *color, char* patterns[]) {
_cleanup_strv_free_ char **units = NULL;
char **unit;
int r;
return 0;
}
-static int graph_one(sd_bus *bus, const struct unit_info *u, char *patterns[]) {
+static int graph_one(sd_bus *bus, const UnitInfo *u, char *patterns[]) {
int r;
assert(bus);
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
- struct unit_info u;
+ UnitInfo u;
r = sd_bus_call_method(
bus,
printf("digraph systemd {\n");
while ((r = bus_parse_unit_info(reply, &u)) > 0) {
+
r = graph_one(bus, &u, patterns);
if (r < 0)
return r;
}
+ if (r < 0)
+ return bus_log_parse_error(r);
printf("}\n");
{ "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN },
{ "fuzz", required_argument, NULL, ARG_FUZZ },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "host", required_argument, NULL, 'H' },
+ { "machine", required_argument, NULL, 'M' },
{}
};