diff options
author | Filipe Brandenburger <filbranden@google.com> | 2018-06-06 09:43:37 -0700 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-06-08 15:46:07 +0200 |
commit | df560cf6b13c6133014c7ff07b2fd2f2b62996c1 (patch) | |
tree | 5d69550f2e08abbf8c1dccee62e112fff0344d31 /src/analyze | |
parent | 89278d96dcbb98ca219b233d454e18cd18501e3a (diff) | |
download | systemd-df560cf6b13c6133014c7ff07b2fd2f2b62996c1.tar.gz |
analyze: use _cleanup_ for struct unit_times
This introduces a has_data boolean field in struct unit_files which can
be used to detect the end of the array.
Use a _cleanup_ for struct unit_files in acquire_time_data and its
callers. Code for acquire_time_data is also simplified by replacing
goto's with straight returns.
Tested: By running the commands below, also checking them under valgrind.
- build/systemd-analyze blame
- build/systemd-analyze critical-chain
- build/systemd-analyze plot
Fixes: Coverity finding CID 996464.
Diffstat (limited to 'src/analyze')
-rw-r--r-- | src/analyze/analyze.c | 86 |
1 files changed, 36 insertions, 50 deletions
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 580bc30e12..8695e7a1d2 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -106,6 +106,7 @@ struct boot_times { }; struct unit_times { + bool has_data; char *name; usec_t activating; usec_t activated; @@ -201,15 +202,16 @@ static int compare_unit_start(const void *a, const void *b) { ((struct unit_times *)b)->activating); } -static void free_unit_times(struct unit_times *t, unsigned n) { +static void unit_times_free(struct unit_times *t) { struct unit_times *p; - for (p = t; p < t + n; p++) + for (p = t; p->has_data; p++) free(p->name); - free(t); } +DEFINE_TRIVIAL_CLEANUP_FUNC(struct unit_times *, unit_times_free); + static void subtract_timestamp(usec_t *a, usec_t b) { assert(a); @@ -353,13 +355,13 @@ static int acquire_time_data(sd_bus *bus, struct unit_times **out) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r, c = 0; struct boot_times *boot_times = NULL; - struct unit_times *unit_times = NULL; + _cleanup_(unit_times_freep) struct unit_times *unit_times = NULL; size_t size = 0; UnitInfo u; r = acquire_boot_times(bus, &boot_times); if (r < 0) - goto fail; + return r; r = sd_bus_call_method( bus, @@ -371,24 +373,21 @@ static int acquire_time_data(sd_bus *bus, struct unit_times **out) { NULL); if (r < 0) { log_error("Failed to list units: %s", bus_error_message(&error, -r)); - goto fail; + return r; } r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)"); - if (r < 0) { - bus_log_parse_error(r); - goto fail; - } + if (r < 0) + return bus_log_parse_error(r); while ((r = bus_parse_unit_info(reply, &u)) > 0) { struct unit_times *t; - if (!GREEDY_REALLOC(unit_times, size, c+1)) { - r = log_oom(); - goto fail; - } + if (!GREEDY_REALLOC(unit_times, size, c+2)) + return log_oom(); - t = unit_times+c; + unit_times[c+1].has_data = false; + t = &unit_times[c]; t->name = NULL; assert_cc(sizeof(usec_t) == sizeof(uint64_t)); @@ -408,10 +407,8 @@ static int acquire_time_data(sd_bus *bus, struct unit_times **out) { bus_get_uint64_property(bus, u.unit_path, "org.freedesktop.systemd1.Unit", "InactiveEnterTimestampMonotonic", - &t->deactivated) < 0) { - r = -EIO; - goto fail; - } + &t->deactivated) < 0) + return -EIO; subtract_timestamp(&t->activating, boot_times->reverse_offset); subtract_timestamp(&t->activated, boot_times->reverse_offset); @@ -429,23 +426,17 @@ static int acquire_time_data(sd_bus *bus, struct unit_times **out) { continue; t->name = strdup(u.id); - if (!t->name) { - r = log_oom(); - goto fail; - } + if (!t->name) + return log_oom(); + + t->has_data = true; c++; } - if (r < 0) { - bus_log_parse_error(r); - goto fail; - } + if (r < 0) + return bus_log_parse_error(r); - *out = unit_times; + *out = TAKE_PTR(unit_times); return c; - -fail: - free_unit_times(unit_times, (unsigned) c); - return r; } static int acquire_host_info(sd_bus *bus, struct host_info **hi) { @@ -600,7 +591,7 @@ static void svg_graph_box(double height, double begin, double end) { static int analyze_plot(int argc, char *argv[], void *userdata) { _cleanup_(free_host_infop) struct host_info *host = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; - struct unit_times *times; + _cleanup_(unit_times_freep) struct unit_times *times = NULL; struct boot_times *boot; int n, m = 1, y = 0, r; bool use_full_bus = true; @@ -648,7 +639,7 @@ static int analyze_plot(int argc, char *argv[], void *userdata) { if (boot->kernel_time > 0) m++; - for (u = times; u < times + n; u++) { + for (u = times; u->has_data; u++) { double text_start, text_width; if (u->activating < boot->userspace_time || @@ -762,7 +753,7 @@ static int analyze_plot(int argc, char *argv[], void *userdata) { svg_text(true, boot->userspace_time, y, "systemd"); y++; - for (u = times; u < times + n; u++) { + for (u = times; u->has_data; u++) { char ts[FORMAT_TIMESPAN_MAX]; bool b; @@ -811,10 +802,7 @@ static int analyze_plot(int argc, char *argv[], void *userdata) { svg("</svg>\n"); - free_unit_times(times, (unsigned) n); - - n = 0; - return n; + return 0; } static int list_dependencies_print(const char *name, unsigned int level, unsigned int branches, @@ -1012,8 +1000,8 @@ static int list_dependencies(sd_bus *bus, const char *name) { static int analyze_critical_chain(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; - struct unit_times *times; - unsigned int i; + _cleanup_(unit_times_freep) struct unit_times *times = NULL; + struct unit_times *u; Hashmap *h; int n, r; @@ -1029,8 +1017,8 @@ static int analyze_critical_chain(int argc, char *argv[], void *userdata) { if (!h) return log_oom(); - for (i = 0; i < (unsigned) n; i++) { - r = hashmap_put(h, times[i].name, ×[i]); + for (u = times; u->has_data; u++) { + r = hashmap_put(h, u->name, u); if (r < 0) return log_error_errno(r, "Failed to add entry to hashmap: %m"); } @@ -1049,14 +1037,13 @@ static int analyze_critical_chain(int argc, char *argv[], void *userdata) { list_dependencies(bus, SPECIAL_DEFAULT_TARGET); h = hashmap_free(h); - free_unit_times(times, (unsigned) n); return 0; } static int analyze_blame(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; - struct unit_times *times; - unsigned i; + _cleanup_(unit_times_freep) struct unit_times *times = NULL; + struct unit_times *u; int n, r; r = acquire_bus(&bus, NULL); @@ -1071,14 +1058,13 @@ static int analyze_blame(int argc, char *argv[], void *userdata) { (void) pager_open(arg_no_pager, false); - for (i = 0; i < (unsigned) n; i++) { + for (u = times; u->has_data; u++) { char ts[FORMAT_TIMESPAN_MAX]; - if (times[i].time > 0) - printf("%16s %s\n", format_timespan(ts, sizeof(ts), times[i].time, USEC_PER_MSEC), times[i].name); + if (u->time > 0) + printf("%16s %s\n", format_timespan(ts, sizeof(ts), u->time, USEC_PER_MSEC), u->name); } - free_unit_times(times, (unsigned) n); return 0; } |