|
|
1abbee |
From 1c33de9e1370bc56e10f3b5306e27c8aa6a18873 Mon Sep 17 00:00:00 2001
|
|
|
1abbee |
From: Michal Sekletar <msekleta@redhat.com>
|
|
|
1abbee |
Date: Mon, 1 Feb 2016 10:44:58 +0100
|
|
|
1abbee |
Subject: [PATCH] journalctl: make "journalctl /dev/sda" work
|
|
|
1abbee |
|
|
|
1abbee |
Currently when journalctl is called with path to block device node we
|
|
|
1abbee |
add following match _KERNEL_DEVICE=b$MAJOR:$MINOR.
|
|
|
1abbee |
|
|
|
1abbee |
That is not sufficient to actually obtain logs about the disk because
|
|
|
1abbee |
dev_printk() kernel helper puts to /dev/kmsg information about the
|
|
|
1abbee |
device in following format, +$SUBSYSTEM:$ADDRESS,
|
|
|
1abbee |
e.g. "+pci:pci:0000:00:14.0".
|
|
|
1abbee |
|
|
|
1abbee |
Now we will walk upward the syspath and add match for every device in
|
|
|
1abbee |
format produced by dev_printk() as well as match for its device node if
|
|
|
1abbee |
it exists.
|
|
|
1abbee |
|
|
|
1abbee |
Cherry-picked from: 795ab08f783e78e85f1493879f13ac44cb113b00
|
|
|
1abbee |
Resolves: #947636
|
|
|
1abbee |
---
|
|
|
1abbee |
Makefile.am | 3 +-
|
|
|
23b3cf |
src/journal/journalctl.c | 118 +++++++++++++++++++++++++++++++--------
|
|
|
1abbee |
2 files changed, 97 insertions(+), 24 deletions(-)
|
|
|
1abbee |
|
|
|
1abbee |
diff --git a/Makefile.am b/Makefile.am
|
|
|
181b3f |
index 2645f66bc..255937643 100644
|
|
|
1abbee |
--- a/Makefile.am
|
|
|
1abbee |
+++ b/Makefile.am
|
|
|
1abbee |
@@ -4245,7 +4245,8 @@ journalctl_LDADD = \
|
|
|
1abbee |
libsystemd-journal-internal.la \
|
|
|
1abbee |
libsystemd-internal.la \
|
|
|
1abbee |
libsystemd-logs.la \
|
|
|
1abbee |
- libsystemd-shared.la
|
|
|
1abbee |
+ libsystemd-shared.la \
|
|
|
1abbee |
+ libudev-core.la
|
|
|
1abbee |
|
|
|
1abbee |
if HAVE_ACL
|
|
|
1abbee |
journalctl_LDADD += \
|
|
|
1abbee |
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
|
|
|
181b3f |
index 836d7d214..3db1cd24e 100644
|
|
|
1abbee |
--- a/src/journal/journalctl.c
|
|
|
1abbee |
+++ b/src/journal/journalctl.c
|
|
|
1abbee |
@@ -63,6 +63,8 @@
|
|
|
1abbee |
#include "mkdir.h"
|
|
|
1abbee |
#include "bus-util.h"
|
|
|
1abbee |
#include "bus-error.h"
|
|
|
1abbee |
+#include "udev.h"
|
|
|
1abbee |
+#include "udev-util.h"
|
|
|
1abbee |
|
|
|
1abbee |
#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
|
|
|
1abbee |
|
|
|
1abbee |
@@ -134,6 +136,80 @@ typedef struct boot_id_t {
|
|
|
1abbee |
LIST_FIELDS(struct boot_id_t, boot_list);
|
|
|
1abbee |
} boot_id_t;
|
|
|
1abbee |
|
|
|
1abbee |
+static int add_matches_for_device(sd_journal *j, const char *devpath) {
|
|
|
1abbee |
+ int r;
|
|
|
1abbee |
+ _cleanup_udev_unref_ struct udev *udev = NULL;
|
|
|
1abbee |
+ _cleanup_udev_device_unref_ struct udev_device *device = NULL;
|
|
|
1abbee |
+ struct udev_device *d = NULL;
|
|
|
1abbee |
+ struct stat st;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert(j);
|
|
|
1abbee |
+ assert(devpath);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (!path_startswith(devpath, "/dev/")) {
|
|
|
1abbee |
+ log_error("Devpath does not start with /dev/");
|
|
|
1abbee |
+ return -EINVAL;
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ udev = udev_new();
|
|
|
1abbee |
+ if (!udev)
|
|
|
1abbee |
+ return log_oom();
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = stat(devpath, &st);
|
|
|
1abbee |
+ if (r < 0)
|
|
|
1abbee |
+ log_error_errno(errno, "Couldn't stat file: %m");
|
|
|
1abbee |
+
|
|
|
1abbee |
+ d = device = udev_device_new_from_devnum(udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
|
|
|
1abbee |
+ if (!device)
|
|
|
1abbee |
+ return log_error_errno(errno, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
|
|
|
1abbee |
+
|
|
|
1abbee |
+ while (d) {
|
|
|
1abbee |
+ _cleanup_free_ char *match = NULL;
|
|
|
1abbee |
+ const char *subsys, *sysname, *devnode;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ subsys = udev_device_get_subsystem(d);
|
|
|
1abbee |
+ if (!subsys) {
|
|
|
1abbee |
+ d = udev_device_get_parent(d);
|
|
|
1abbee |
+ continue;
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ sysname = udev_device_get_sysname(d);
|
|
|
1abbee |
+ if (!sysname) {
|
|
|
1abbee |
+ d = udev_device_get_parent(d);
|
|
|
1abbee |
+ continue;
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ match = strjoin("_KERNEL_DEVICE=+", subsys, ":", sysname, NULL);
|
|
|
1abbee |
+ if (!match)
|
|
|
1abbee |
+ return log_oom();
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = sd_journal_add_match(j, match, 0);
|
|
|
1abbee |
+ if (r < 0)
|
|
|
1abbee |
+ return log_error_errno(r, "Failed to add match: %m");
|
|
|
1abbee |
+
|
|
|
1abbee |
+ devnode = udev_device_get_devnode(d);
|
|
|
1abbee |
+ if (devnode) {
|
|
|
1abbee |
+ _cleanup_free_ char *match1 = NULL;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = stat(devnode, &st);
|
|
|
1abbee |
+ if (r < 0)
|
|
|
1abbee |
+ return log_error_errno(r, "Failed to stat() device node \"%s\": %m", devnode);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = asprintf(&match1, "_KERNEL_DEVICE=%c%u:%u", S_ISBLK(st.st_mode) ? 'b' : 'c', major(st.st_rdev), minor(st.st_rdev));
|
|
|
1abbee |
+ if (r < 0)
|
|
|
1abbee |
+ return log_oom();
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = sd_journal_add_match(j, match1, 0);
|
|
|
1abbee |
+ if (r < 0)
|
|
|
1abbee |
+ return log_error_errno(r, "Failed to add match: %m");
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ d = udev_device_get_parent(d);
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ return 0;
|
|
|
1abbee |
+}
|
|
|
1abbee |
+
|
|
|
1abbee |
static void pager_open_if_enabled(void) {
|
|
|
1abbee |
|
|
|
1abbee |
if (arg_no_pager)
|
|
|
1abbee |
@@ -788,13 +864,12 @@ static int add_matches(sd_journal *j, char **args) {
|
|
|
1abbee |
have_term = false;
|
|
|
1abbee |
|
|
|
1abbee |
} else if (path_is_absolute(*i)) {
|
|
|
1abbee |
- _cleanup_free_ char *p, *t = NULL, *t2 = NULL;
|
|
|
1abbee |
+ _cleanup_free_ char *p, *t = NULL, *t2 = NULL, *interpreter = NULL;
|
|
|
1abbee |
const char *path;
|
|
|
1abbee |
- _cleanup_free_ char *interpreter = NULL;
|
|
|
1abbee |
struct stat st;
|
|
|
1abbee |
|
|
|
1abbee |
p = canonicalize_file_name(*i);
|
|
|
1abbee |
- path = p ? p : *i;
|
|
|
1abbee |
+ path = p ?: *i;
|
|
|
1abbee |
|
|
|
1abbee |
if (stat(path, &st) < 0)
|
|
|
1abbee |
return log_error_errno(errno, "Couldn't stat file: %m");
|
|
|
1abbee |
@@ -808,40 +883,37 @@ static int add_matches(sd_journal *j, char **args) {
|
|
|
1abbee |
return log_oom();
|
|
|
1abbee |
|
|
|
1abbee |
t = strappend("_COMM=", comm);
|
|
|
1abbee |
+ if (!t)
|
|
|
1abbee |
+ return log_oom();
|
|
|
1abbee |
|
|
|
1abbee |
/* Append _EXE only if the interpreter is not a link.
|
|
|
1abbee |
Otherwise, it might be outdated often. */
|
|
|
1abbee |
- if (lstat(interpreter, &st) == 0 &&
|
|
|
1abbee |
- !S_ISLNK(st.st_mode)) {
|
|
|
1abbee |
+ if (lstat(interpreter, &st) == 0 && !S_ISLNK(st.st_mode)) {
|
|
|
1abbee |
t2 = strappend("_EXE=", interpreter);
|
|
|
1abbee |
if (!t2)
|
|
|
1abbee |
return log_oom();
|
|
|
1abbee |
}
|
|
|
1abbee |
- } else
|
|
|
1abbee |
+ } else {
|
|
|
1abbee |
t = strappend("_EXE=", path);
|
|
|
1abbee |
- } else if (S_ISCHR(st.st_mode)) {
|
|
|
1abbee |
- if (asprintf(&t, "_KERNEL_DEVICE=c%u:%u",
|
|
|
1abbee |
- major(st.st_rdev),
|
|
|
1abbee |
- minor(st.st_rdev)) < 0)
|
|
|
1abbee |
- return -ENOMEM;
|
|
|
1abbee |
- } else if (S_ISBLK(st.st_mode)) {
|
|
|
1abbee |
- if (asprintf(&t, "_KERNEL_DEVICE=b%u:%u",
|
|
|
1abbee |
- major(st.st_rdev),
|
|
|
1abbee |
- minor(st.st_rdev)) < 0)
|
|
|
1abbee |
- return -ENOMEM;
|
|
|
1abbee |
+ if (!t)
|
|
|
1abbee |
+ return log_oom();
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = sd_journal_add_match(j, t, 0);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (r >=0 && t2)
|
|
|
1abbee |
+ r = sd_journal_add_match(j, t2, 0);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
|
|
|
1abbee |
+ r = add_matches_for_device(j, path);
|
|
|
1abbee |
+ if (r < 0)
|
|
|
1abbee |
+ return r;
|
|
|
1abbee |
} else {
|
|
|
1abbee |
log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
|
|
|
1abbee |
return -EINVAL;
|
|
|
1abbee |
}
|
|
|
1abbee |
|
|
|
1abbee |
- if (!t)
|
|
|
1abbee |
- return log_oom();
|
|
|
1abbee |
-
|
|
|
1abbee |
- r = sd_journal_add_match(j, t, 0);
|
|
|
1abbee |
- if (t2)
|
|
|
1abbee |
- r = sd_journal_add_match(j, t2, 0);
|
|
|
1abbee |
have_term = true;
|
|
|
1abbee |
-
|
|
|
1abbee |
} else {
|
|
|
1abbee |
r = sd_journal_add_match(j, *i, 0);
|
|
|
1abbee |
have_term = true;
|