summaryrefslogtreecommitdiff
path: root/src/analyze
diff options
context:
space:
mode:
authorDavid Tardon <dtardon@redhat.com>2018-05-09 09:35:52 +0200
committerLennart Poettering <lennart@poettering.net>2018-05-11 08:11:02 -0700
commitc0a1bfacfea9c65ea79fd07682a5b60b5d711a33 (patch)
tree74247ace55d72720a944634ad46819a234d3cbd9 /src/analyze
parent7456fa02670ce1b37345150aed80f16dfe970442 (diff)
downloadsystemd-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.c52
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) {