diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile.am | 12 | ||||
| -rw-r--r-- | src/dbus-manager.c | 3 | ||||
| -rw-r--r-- | src/main.c | 30 | ||||
| -rw-r--r-- | src/manager.c | 36 | ||||
| -rw-r--r-- | src/manager.h | 1 | ||||
| -rw-r--r-- | src/timestamp.c | 39 | ||||
| -rw-r--r-- | src/util.c | 19 | ||||
| -rw-r--r-- | src/util.h | 2 | 
9 files changed, 128 insertions, 15 deletions
| diff --git a/.gitignore b/.gitignore index 422378881b..a99cd17480 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +systemd-timestamp  systemd-cryptsetup  systemd-cryptsetup-generator  systemd-tty-ask-password-agent diff --git a/Makefile.am b/Makefile.am index 3371c597f4..52bd13fedb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 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) | 
