diff options
author | Milan Broz | 2012-08-13 13:55:30 +0200 |
---|---|---|
committer | Karel Zak | 2012-08-13 15:54:57 +0200 |
commit | 4ceb601d21f9448f02e713a0860fd8007f3631b8 (patch) | |
tree | b805693c4fa0ae1c977f27d59ec32693cad90fdb /sys-utils/dmesg.c | |
parent | eject: return proper 0/1 from eject_cdrom() (diff) | |
download | kernel-qcow2-util-linux-4ceb601d21f9448f02e713a0860fd8007f3631b8.tar.gz kernel-qcow2-util-linux-4ceb601d21f9448f02e713a0860fd8007f3631b8.tar.xz kernel-qcow2-util-linux-4ceb601d21f9448f02e713a0860fd8007f3631b8.zip |
dmesg: fix kmsg read if read returns EPIPE
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@redhat.com>
Diffstat (limited to 'sys-utils/dmesg.c')
-rw-r--r-- | sys-utils/dmesg.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c index e92904f64..0ee03eeba 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; |