summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-11-08 00:31:09 -0500
committerLennart Poettering <lennart@poettering.net>2010-11-10 22:38:44 +0100
commite9ddabc246ced239cbce436e16792dc4c3d1b52d (patch)
treeb14a4b8a026547baa4876da64021a0211315be99 /src
parent70ca520f43d8cd3f9c6895d20ec87498b626bd75 (diff)
manager: parse RD_TIMESTAMP passed from initrd
Diffstat (limited to 'src')
-rw-r--r--src/dbus-manager.c3
-rw-r--r--src/main.c30
-rw-r--r--src/manager.c36
-rw-r--r--src/manager.h1
-rw-r--r--src/timestamp.c39
-rw-r--r--src/util.c19
-rw-r--r--src/util.h2
7 files changed, 116 insertions, 14 deletions
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index c1950319f6..769035f607 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -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 },
diff --git a/src/main.c b/src/main.c
index f7d76a2941..cd73ee2cff 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
diff --git a/src/manager.c b/src/manager.c
index c7de1ea95c..d690a0f16b 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -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));
diff --git a/src/manager.h b/src/manager.h
index 8a64750584..ab7f26368c 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -143,6 +143,7 @@ struct Manager {
char **environment;
+ dual_timestamp initrd_timestamp;
dual_timestamp startup_timestamp;
dual_timestamp finish_timestamp;
diff --git a/src/timestamp.c b/src/timestamp.c
new file mode 100644
index 0000000000..ce5142946a
--- /dev/null
+++ b/src/timestamp.c
@@ -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;
+}
diff --git a/src/util.c b/src/util.c
index 6f9399b418..f41861b64e 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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",
diff --git a/src/util.h b/src/util.h
index b7ef51e2ce..5567da8544 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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)