manager: parse RD_TIMESTAMP passed from initrd

This commit is contained in:
Lennart Poettering 2010-11-08 00:31:09 -05:00
parent 70ca520f43
commit e9ddabc246
9 changed files with 128 additions and 15 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
systemd-timestamp
systemd-cryptsetup
systemd-cryptsetup-generator
systemd-tty-ask-password-agent

View file

@ -115,7 +115,8 @@ rootlibexec_PROGRAMS = \
systemd-fsck \
systemd-quotacheck \
systemd-cryptsetup \
systemd-cryptsetup-generator
systemd-cryptsetup-generator \
systemd-timestamp
noinst_PROGRAMS = \
test-engine \
@ -714,6 +715,15 @@ systemd_quotacheck_CFLAGS = \
systemd_quotacheck_LDADD = \
libsystemd-basic.la
systemd_timestamp_SOURCES = \
src/timestamp.c
systemd_timestamp_CFLAGS = \
$(AM_CFLAGS)
systemd_timestamp_LDADD = \
libsystemd-basic.la
systemd_cryptsetup_SOURCES = \
src/cryptsetup.c

View file

@ -150,7 +150,9 @@
#define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \
" <property name=\"Version\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"RunningAs\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"InitRDTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"StartupTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"FinishTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <property name=\"LogLevel\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"LogTarget\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"NNames\" type=\"u\" access=\"read\"/>\n" \
@ -300,6 +302,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
const BusProperty properties[] = {
{ "org.freedesktop.systemd1.Manager", "Version", bus_property_append_string, "s", PACKAGE_STRING },
{ "org.freedesktop.systemd1.Manager", "RunningAs", bus_manager_append_running_as, "s", &m->running_as },
{ "org.freedesktop.systemd1.Manager", "InitRDTimestamp", bus_property_append_uint64, "t", &m->initrd_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "StartupTimestamp", bus_property_append_uint64, "t", &m->startup_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "FinishTimestamp", bus_property_append_uint64, "t", &m->finish_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "LogLevel", bus_manager_append_log_level, "s", NULL },

View file

@ -871,12 +871,31 @@ fail:
return r;
}
static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
const char *e;
unsigned long long a, b;
assert(t);
if (!(e = getenv("RD_TIMESTAMP")))
return NULL;
if (sscanf(e, "%llu %llu", &a, &b) != 2)
return NULL;
t->realtime = (usec_t) a;
t->monotonic = (usec_t) b;
return t;
}
int main(int argc, char *argv[]) {
Manager *m = NULL;
int r, retval = EXIT_FAILURE;
FDSet *fds = NULL;
bool reexecute = false;
const char *shutdown_verb = NULL;
dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
/* This is compatbility support for SysV, where
@ -965,9 +984,13 @@ int main(int argc, char *argv[]) {
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
arg_running_as == MANAGER_SYSTEM);
/* Unset some environment variables passed in from the kernel
* that don't really make sense for us. */
if (arg_running_as == MANAGER_SYSTEM) {
/* Parse the data passed to us by the initrd and unset it */
parse_initrd_timestamp(&initrd_timestamp);
filter_environ("RD_");
/* Unset some environment variables passed in from the
* kernel that don't really make sense for us. */
unsetenv("HOME");
unsetenv("TERM");
}
@ -1030,6 +1053,9 @@ int main(int argc, char *argv[]) {
m->mount_auto = arg_mount_auto;
m->swap_auto = arg_swap_auto;
if (dual_timestamp_is_set(&initrd_timestamp))
m->initrd_timestamp = initrd_timestamp;
if (arg_console)
manager_set_console(m, arg_console);

View file

@ -2501,6 +2501,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
assert(f);
assert(fds);
dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
@ -2555,7 +2556,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (l[0] == 0)
break;
if (startswith(l, "startup-timestamp="))
if (startswith(l, "initrd-timestamp="))
dual_timestamp_deserialize(l+17, &m->initrd_timestamp);
else if (startswith(l, "startup-timestamp="))
dual_timestamp_deserialize(l+18, &m->startup_timestamp);
else if (startswith(l, "finish-timestamp="))
dual_timestamp_deserialize(l+17, &m->finish_timestamp);
@ -2715,7 +2718,7 @@ bool manager_unit_pending_inactive(Manager *m, const char *name) {
}
void manager_check_finished(Manager *m) {
char userspace[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
assert(m);
@ -2727,15 +2730,26 @@ void manager_check_finished(Manager *m) {
dual_timestamp_get(&m->finish_timestamp);
if (m->running_as == MANAGER_SYSTEM)
log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(kernel),
m->startup_timestamp.monotonic),
format_timespan(userspace, sizeof(userspace),
m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
format_timespan(sum, sizeof(sum),
m->finish_timestamp.monotonic));
else
if (m->running_as == MANAGER_SYSTEM) {
if (dual_timestamp_is_set(&m->initrd_timestamp)) {
log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(kernel),
m->initrd_timestamp.monotonic),
format_timespan(initrd, sizeof(initrd),
m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic),
format_timespan(userspace, sizeof(userspace),
m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
format_timespan(sum, sizeof(sum),
m->finish_timestamp.monotonic));
} else
log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
format_timespan(kernel, sizeof(kernel),
m->startup_timestamp.monotonic),
format_timespan(userspace, sizeof(userspace),
m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
format_timespan(sum, sizeof(sum),
m->finish_timestamp.monotonic));
} else
log_debug("Startup finished in %s.",
format_timespan(userspace, sizeof(userspace),
m->finish_timestamp.monotonic - m->startup_timestamp.monotonic));

View file

@ -143,6 +143,7 @@ struct Manager {
char **environment;
dual_timestamp initrd_timestamp;
dual_timestamp startup_timestamp;
dual_timestamp finish_timestamp;

39
src/timestamp.c Normal file
View file

@ -0,0 +1,39 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <stdio.h>
#include "util.h"
int main(int argc, char *argv[]) {
struct dual_timestamp t;
/* This is mostly useful for stuff like init ram disk scripts
* which want to take a proper timestamp to do minimal bootup
* profiling. */
dual_timestamp_get(&t);
printf("%llu %llu\n",
(unsigned long long) t.realtime,
(unsigned long long) t.monotonic);
return 0;
}

View file

@ -3566,7 +3566,6 @@ void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
}
}
char *fstab_node_to_udev_node(const char *p) {
char *dn, *t, *u;
int r;
@ -3617,6 +3616,24 @@ char *fstab_node_to_udev_node(const char *p) {
return strdup(p);
}
void filter_environ(const char *prefix) {
int i, j;
assert(prefix);
if (!environ)
return;
for (i = 0, j = 0; environ[i]; i++) {
if (startswith(environ[i], prefix))
continue;
environ[j++] = environ[i];
}
environ[j] = NULL;
}
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",

View file

@ -372,6 +372,8 @@ void dual_timestamp_deserialize(const char *value, dual_timestamp *t);
char *fstab_node_to_udev_node(const char *p);
void filter_environ(const char *prefix);
#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)