diff options
Diffstat (limited to 'src/analyze')
-rw-r--r-- | src/analyze/analyze-verify.c | 3 | ||||
-rw-r--r-- | src/analyze/analyze-verify.h | 1 | ||||
-rw-r--r-- | src/analyze/analyze.c | 109 | ||||
-rw-r--r-- | src/analyze/meson.build | 17 |
4 files changed, 125 insertions, 5 deletions
diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c index f34c24c53a..461e7852ac 100644 --- a/src/analyze/analyze-verify.c +++ b/src/analyze/analyze-verify.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ /*** This file is part of systemd. @@ -146,7 +147,7 @@ static int verify_socket(Unit *u) { } static int verify_executable(Unit *u, ExecCommand *exec) { - if (exec == NULL) + if (!exec) return 0; if (access(exec->path, X_OK) < 0) diff --git a/src/analyze/analyze-verify.h b/src/analyze/analyze-verify.h index d5466ecdf9..a895130508 100644 --- a/src/analyze/analyze-verify.h +++ b/src/analyze/analyze-verify.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once /*** diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 9fcc20dba3..d45c1dc496 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ /*** This file is part of systemd. @@ -30,6 +31,7 @@ #include "bus-error.h" #include "bus-unit-util.h" #include "bus-util.h" +#include "calendarspec.h" #include "glob-util.h" #include "hashmap.h" #include "locale-util.h" @@ -414,7 +416,7 @@ static int acquire_time_data(sd_bus *bus, struct unit_times **out) { continue; t->name = strdup(u.id); - if (t->name == NULL) { + if (!t->name) { r = log_oom(); goto fail; } @@ -489,11 +491,40 @@ static int pretty_boot_time(sd_bus *bus, char **_buf) { size_t size; char *ptr; int r; + usec_t activated_time = USEC_INFINITY; + _cleanup_free_ char* path = NULL, *unit_id = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; r = acquire_boot_times(bus, &t); if (r < 0) return r; + path = unit_dbus_path_from_name(SPECIAL_DEFAULT_TARGET); + if (!path) + return log_oom(); + + r = sd_bus_get_property_string( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Unit", + "Id", + &error, + &unit_id); + if (r < 0) { + log_error_errno(r, "default.target doesn't seem to exist: %s", bus_error_message(&error, r)); + unit_id = NULL; + } + + r = bus_get_uint64_property(bus, path, + "org.freedesktop.systemd1.Unit", + "ActiveEnterTimestampMonotonic", + &activated_time); + if (r < 0) { + log_info_errno(r, "default.target seems not to be started. Continuing..."); + activated_time = USEC_INFINITY; + } + ptr = buf; size = sizeof(buf); @@ -510,6 +541,9 @@ static int pretty_boot_time(sd_bus *bus, char **_buf) { size = strpcpyf(&ptr, size, "%s (userspace) ", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC)); strpcpyf(&ptr, size, "= %s", format_timespan(ts, sizeof(ts), t->firmware_time + t->finish_time, USEC_PER_MSEC)); + if (unit_id && activated_time != USEC_INFINITY) + size = strpcpyf(&ptr, size, "\n%s reached after %s in userspace", unit_id, format_timespan(ts, sizeof(ts), activated_time - t->userspace_time, USEC_PER_MSEC)); + ptr = strdup(buf); if (!ptr) return log_oom(); @@ -786,7 +820,7 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha assert(deps); path = unit_dbus_path_from_name(name); - if (path == NULL) + if (!path) return -ENOMEM; return bus_get_unit_property_strv(bus, path, "After", deps); @@ -844,7 +878,7 @@ static int list_dependencies_one(sd_bus *bus, const char *name, unsigned int lev } } - if (service_longest == 0 ) + if (service_longest == 0) return r; STRV_FOREACH(c, deps) { @@ -903,7 +937,7 @@ static int list_dependencies(sd_bus *bus, const char *name) { assert(bus); path = unit_dbus_path_from_name(name); - if (path == NULL) + if (!path) return -ENOMEM; r = sd_bus_get_property( @@ -1394,6 +1428,70 @@ static int dump_syscall_filters(char** names) { } #endif +static int test_calendar(char **args) { + int ret = 0, r; + char **p; + usec_t n; + + if (strv_isempty(args)) { + log_error("Expected at least one calendar specification string as argument."); + return -EINVAL; + } + + n = now(CLOCK_REALTIME); + + STRV_FOREACH(p, args) { + _cleanup_(calendar_spec_freep) CalendarSpec *spec = NULL; + _cleanup_free_ char *t = NULL; + usec_t next; + + r = calendar_spec_from_string(*p, &spec); + if (r < 0) { + ret = log_error_errno(r, "Failed to parse calendar specification '%s': %m", *p); + continue; + } + + r = calendar_spec_normalize(spec); + if (r < 0) { + ret = log_error_errno(r, "Failed to normalize calendar specification '%s': %m", *p); + continue; + } + + r = calendar_spec_to_string(spec, &t); + if (r < 0) { + ret = log_error_errno(r, "Failed to fomat calendar specification '%s': %m", *p); + continue; + } + + if (!streq(t, *p)) + printf(" Original form: %s\n", *p); + + printf("Normalized form: %s\n", t); + + r = calendar_spec_next_usec(spec, n, &next); + if (r == -ENOENT) + printf(" Next elapse: never\n"); + else if (r < 0) { + ret = log_error_errno(r, "Failed to determine next elapse for '%s': %m", *p); + continue; + } else { + char buffer[CONST_MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESTAMP_RELATIVE_MAX)]; + + printf(" Next elapse: %s\n", format_timestamp(buffer, sizeof(buffer), next)); + + if (!in_utc_timezone()) + printf(" (in UTC): %s\n", format_timestamp_utc(buffer, sizeof(buffer), next)); + + printf(" From now: %s\n", format_timestamp_relative(buffer, sizeof(buffer), next)); + } + + if (*(p+1)) + putchar('\n'); + } + + return ret; +} + static void help(void) { pager_open(arg_no_pager, false); @@ -1428,6 +1526,7 @@ static void help(void) { " dump Output state serialization of service manager\n" " syscall-filter [NAME...] Print list of syscalls in seccomp filter\n" " verify FILE... Check unit files for correctness\n" + " calendar SPEC... Validate repetitive calendar time events\n" , program_invocation_short_name); /* When updating this list, including descriptions, apply @@ -1617,6 +1716,8 @@ int main(int argc, char *argv[]) { r = get_log_target(bus, argv+optind+1); else if (streq(argv[optind], "syscall-filter")) r = dump_syscall_filters(argv+optind+1); + else if (streq(argv[optind], "calendar")) + r = test_calendar(argv+optind+1); else log_error("Unknown operation '%s'.", argv[optind]); } diff --git a/src/analyze/meson.build b/src/analyze/meson.build index fcbd814233..b32311413b 100644 --- a/src/analyze/meson.build +++ b/src/analyze/meson.build @@ -1,3 +1,20 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# Copyright 2017 Zbigniew Jędrzejewski-Szmek +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see <http://www.gnu.org/licenses/>. + systemd_analyze_sources = files(''' analyze.c analyze-verify.c |