The /dev/kmsg can return EPIPE if current record has beed modified while reading. For init_kmsg, it cause switch to DMESG_METHOD_SYSLOG (which is not expected) and later it can truncate output. Signed-off-by: Milan Broz <mbroz@xxxxxxxxxx> --- sys-utils/dmesg.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c index e92904f..0ee03ee 100644 --- a/sys-utils/dmesg.c +++ b/sys-utils/dmesg.c @@ -851,6 +851,19 @@ static void print_buffer(struct dmesg_control *ctl, print_record(ctl, &rec); } +static ssize_t read_kmsg_one(struct dmesg_control *ctl) +{ + ssize_t size; + + /* kmsg returns EPIPE if record was modified while reading */ + do { + size = read(ctl->kmsg, ctl->kmsg_buf, + sizeof(ctl->kmsg_buf) - 1); + } while (size < 0 && errno == EPIPE); + + return size; +} + static int init_kmsg(struct dmesg_control *ctl) { int mode = O_RDONLY; @@ -877,8 +890,7 @@ static int init_kmsg(struct dmesg_control *ctl) * Let's try to read the first record. The record is later processed in * read_kmsg(). */ - ctl->kmsg_first_read = read(ctl->kmsg, ctl->kmsg_buf, - sizeof(ctl->kmsg_buf) - 1); + ctl->kmsg_first_read = read_kmsg_one(ctl); if (ctl->kmsg_first_read < 0) { close(ctl->kmsg); ctl->kmsg = -1; @@ -996,7 +1008,7 @@ static int read_kmsg(struct dmesg_control *ctl) ctl->kmsg_buf, (size_t) sz) == 0) print_record(ctl, &rec); - sz = read(ctl->kmsg, ctl->kmsg_buf, sizeof(ctl->kmsg_buf) - 1); + sz = read_kmsg_one(ctl); } return 0; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html