diff options
author | David Tardon <dtardon@redhat.com> | 2018-05-09 09:35:52 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-05-11 08:11:02 -0700 |
commit | c0a1bfacfea9c65ea79fd07682a5b60b5d711a33 (patch) | |
tree | 74247ace55d72720a944634ad46819a234d3cbd9 /src/analyze | |
parent | 7456fa02670ce1b37345150aed80f16dfe970442 (diff) | |
download | systemd-c0a1bfacfea9c65ea79fd07682a5b60b5d711a33.tar.gz |
systemd-analyze: make dump work for large # of units
If there is a large number of units, the size of the generated dump
string can overstep DBus message size limit. So let's pass that string
via a fd.
Diffstat (limited to 'src/analyze')
-rw-r--r-- | src/analyze/analyze.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 5e1766b053..580bc30e12 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -21,6 +21,8 @@ #include "calendarspec.h" #include "def.h" #include "conf-files.h" +#include "copy.h" +#include "fd-util.h" #include "glob-util.h" #include "hashmap.h" #include "locale-util.h" @@ -1279,11 +1281,39 @@ static int dot(int argc, char *argv[], void *userdata) { return 0; } +static int dump_fallback(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + const char *text = NULL; + int r; + + assert(bus); + + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Dump", + &error, + &reply, + NULL); + if (r < 0) + return log_error_errno(r, "Failed to issue method call Dump: %s", bus_error_message(&error, r)); + + r = sd_bus_message_read(reply, "s", &text); + if (r < 0) + return bus_log_parse_error(r); + + fputs(text, stdout); + return 0; +} + static int dump(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; - const char *text = NULL; + int fd = -1; int r; r = acquire_bus(&bus, NULL); @@ -1292,24 +1322,32 @@ static int dump(int argc, char *argv[], void *userdata) { (void) pager_open(arg_no_pager, false); + if (!sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD)) + return dump_fallback(bus); + r = sd_bus_call_method( bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "Dump", + "DumpByFileDescriptor", &error, &reply, NULL); - if (r < 0) - return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r)); + if (r < 0) { + /* fall back to Dump if DumpByFileDescriptor is not supported */ + if (!IN_SET(r, -EACCES, -EBADR)) + return log_error_errno(r, "Failed to issue method call DumpByFileDescriptor: %s", bus_error_message(&error, r)); - r = sd_bus_message_read(reply, "s", &text); + return dump_fallback(bus); + } + + r = sd_bus_message_read(reply, "h", &fd); if (r < 0) return bus_log_parse_error(r); - fputs(text, stdout); - return 0; + fflush(stdout); + return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0); } static int cat_config(int argc, char *argv[], void *userdata) { |