summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-01-07 11:32:03 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2020-01-07 22:20:37 +0900
commit10c71c3605d7cc59d86e822a20c055b9ca9bf2bc (patch)
tree1e79daaa5af96bc55157ab4eb800143956424aa6
parent0e97a910a63d338f0acce6302de76b3e96c9cd70 (diff)
downloadsystemd-10c71c3605d7cc59d86e822a20c055b9ca9bf2bc.tar.gz
networkctl: status command also shows logs of networkd
Closes #14050.
-rw-r--r--man/networkctl.xml19
-rw-r--r--src/network/networkctl.c95
2 files changed, 111 insertions, 3 deletions
diff --git a/man/networkctl.xml b/man/networkctl.xml
index 0502ab752c..6b3702bfd3 100644
--- a/man/networkctl.xml
+++ b/man/networkctl.xml
@@ -311,6 +311,25 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-l</option></term>
+ <term><option>--full</option></term>
+
+ <listitem>
+ <para>Do not ellipsize the logs in <command>status</command> command.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--lines=</option></term>
+
+ <listitem>
+ <para>When used with <command>status</command>, controls the number of journal lines to show,
+ counting from the most recent ones. Takes a positive integer argument. Defaults to 10.</para>
+ </listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
<xi:include href="standard-options.xml" xpointer="no-legend" />
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 668ec1045d..c3f8c6c10c 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -30,6 +30,7 @@
#include "hwdb-util.h"
#include "local-addresses.h"
#include "locale-util.h"
+#include "logs-show.h"
#include "macro.h"
#include "main-func.h"
#include "netlink-util.h"
@@ -46,6 +47,7 @@
#include "strv.h"
#include "strxcpyx.h"
#include "terminal-util.h"
+#include "unit-def.h"
#include "verbs.h"
#include "wifi-util.h"
@@ -59,6 +61,8 @@ static PagerFlags arg_pager_flags = 0;
static bool arg_legend = true;
static bool arg_all = false;
static bool arg_stats = false;
+static bool arg_full = false;
+static unsigned arg_lines = 10;
static char *link_get_type_string(unsigned short iftype, sd_device *d) {
const char *t, *devtype;
@@ -1067,6 +1071,69 @@ static int dump_statistics(Table *table, const LinkInfo *info) {
return 0;
}
+static OutputFlags get_output_flags(void) {
+ return
+ arg_all * OUTPUT_SHOW_ALL |
+ (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+ colors_enabled() * OUTPUT_COLOR;
+}
+
+static int show_logs(const LinkInfo *info) {
+ _cleanup_(sd_journal_closep) sd_journal *j = NULL;
+ int r;
+
+ if (arg_lines == 0)
+ return 0;
+
+ r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
+ if (r < 0)
+ return log_error_errno(r, "Failed to open journal: %m");
+
+ r = add_match_this_boot(j, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add boot matches: %m");
+
+ if (info) {
+ char m1[STRLEN("_KERNEL_DEVICE=n") + DECIMAL_STR_MAX(int)];
+ const char *m2, *m3;
+
+ /* kernel */
+ xsprintf(m1, "_KERNEL_DEVICE=n%i", info->ifindex);
+ /* networkd */
+ m2 = strjoina("INTERFACE=", info->name);
+ /* udevd */
+ m3 = strjoina("DEVICE=", info->name);
+
+ (void)(
+ (r = sd_journal_add_match(j, m1, 0)) ||
+ (r = sd_journal_add_disjunction(j)) ||
+ (r = sd_journal_add_match(j, m2, 0)) ||
+ (r = sd_journal_add_disjunction(j)) ||
+ (r = sd_journal_add_match(j, m3, 0))
+ );
+ if (r < 0)
+ return log_error_errno(r, "Failed to add link matches: %m");
+ } else {
+ r = add_matches_for_unit(j, "systemd-networkd.service");
+ if (r < 0)
+ return log_error_errno(r, "Failed to add unit matches: %m");
+
+ r = add_matches_for_unit(j, "systemd-networkd-wait-online.service");
+ if (r < 0)
+ return log_error_errno(r, "Failed to add unit matches: %m");
+ }
+
+ return show_journal(
+ stdout,
+ j,
+ OUTPUT_SHORT,
+ 0,
+ 0,
+ arg_lines,
+ get_output_flags() | OUTPUT_BEGIN_NEWLINE,
+ NULL);
+}
+
static int link_status_one(
sd_netlink *rtnl,
sd_hwdb *hwdb,
@@ -1457,7 +1524,11 @@ static int link_status_one(
if (r < 0)
return r;
- return table_print(table, NULL);
+ r = table_print(table, NULL);
+ if (r < 0)
+ return r;
+
+ return show_logs(info);
}
static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
@@ -1520,7 +1591,11 @@ static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
if (r < 0)
return r;
- return table_print(table, NULL);
+ r = table_print(table, NULL);
+ if (r < 0)
+ return r;
+
+ return show_logs(NULL);
}
static int link_status(int argc, char *argv[], void *userdata) {
@@ -1946,6 +2021,8 @@ static int help(void) {
" --no-legend Do not show the headers and footers\n"
" -a --all Show status for all links\n"
" -s --stats Show detailed link statics\n"
+ " -l --full Do not ellipsize output\n"
+ " -n --lines=INTEGER Number of journal entries to show\n"
"\nSee the %s for details.\n"
, program_invocation_short_name
, ansi_highlight()
@@ -1971,6 +2048,8 @@ static int parse_argv(int argc, char *argv[]) {
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND },
{ "all", no_argument, NULL, 'a' },
{ "stats", no_argument, NULL, 's' },
+ { "full", no_argument, NULL, 'l' },
+ { "lines", required_argument, NULL, 'n' },
{}
};
@@ -1979,7 +2058,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "has", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "hasln:", options, NULL)) >= 0) {
switch (c) {
@@ -2005,6 +2084,16 @@ static int parse_argv(int argc, char *argv[]) {
arg_stats = true;
break;
+ case 'l':
+ arg_full = true;
+ break;
+
+ case 'n':
+ if (safe_atou(optarg, &arg_lines) < 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Failed to parse lines '%s'", optarg);
+ break;
+
case '?':
return -EINVAL;