Description of problem:
In the customer's environment, iscsid is reporting a single blank emerg line at connection failure.
Dec 15 18:47:29 hostname kern.info: kernel: connection50:0: detected conn error (1011)
Dec 15 18:47:29 hostname daemon.emerg: iscsid:
^^^^^^^^^^^^^^^^^ emerg level and blank message
Dec 15 18:47:29 hostname daemon.warning: iscsid: Kernel reported iSCSI connection 86:0 error (1011 - ISCSI_ERR_CONN_FAILED: iSCSI connection failed) state (3)
journalctl --all --this-boot --no-pager -o verbose:
Thu 2016-12-15 18:47:29.942853 JST <omitted>
As a note, the custom rsyslog.conf being used can be found at https://paste.fedoraproject.org/530840/. We assumed that this was not the cause of the issue as the message was found in journalctl as well. Additionally I am unable to reproduce with the custom .conf.
Version-Release number of selected component (if applicable):
Only reproducible in customer environment.
Have not been able to reproduce this locally.
Single blank emerg message
No blank message
The blank emergency message appears to be do to a bug in log_enqueue() from usr/log.c .
The iscsid logging code in usr/log.c uses a share memory area like a modified circular buffer. Unlike a simple circular buffer, the tail pointer points to the beginning of the last message, not the end. And messages are not split when wrapping to the beginning of the circular buffer area. If a message is too big to fit at the end, the whole thing is placed at the beginning and a blank area which should be skipped is left at the end of the buffer area.
But if the buffer is empty with the head pointer (and tail pointer) near the end of the buffer, inserting a message too big to fit in the end of the memory area will cause a extra blank entry to be created. Since the blank entry will normally be all-zeros in memory, this will get treated like a emergency priority (priority 0) message with an empty message string.
The problem is how log_enqueue does not move the head pointer in this case with a previously empty buffer. The tail pointer is moved to the beginning of the buffer area and the log entry put in the beginning of the buffer area. But since the head pointer wasn't moved to match, log_dequeue interprets the state as there being 2 messages: 1 message where the head pointer is pointing to, then the other message where the tail is pointing to. The unintended entry at the head pointer then creates the blank emergency message when it is pushed to syslog.
Created attachment 1242519 [details]
unit test creating the issue in the log.c code
I've attached a tarball with code which can recreate the unintended entry. It contains an unmodified copy of log.c from the iscsi code, wraps it, and then makes calls which will put the logging code in the bad state. It will report an error when it dequeues the bad entry which has a prio of 0.
Created attachment 1242525 [details]
Patch: reset head pointer when moving the tail pointer for an empty buffer
The attached patch should fix the issue. If setting the tail pointer to the start of the buffer from there not being enough space, the head pointer and lastmsg varable should also be set to the start of the buffer if the buffer was empty. This avoid the head pointer being left pointing to an empty, invalid entry and avoids a stale lastmsg being scribbled to which could potentially be beyond the end of the buffer area.
No regression found with iscsi-initiator-utils-184.108.40.2064-2.el7
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.
For information on the advisory, and where to find the updated
files, follow the link below.
If the solution does not work for you, open a new bug report.