smart_status: move channel write outside lock to avoid deadlock

The smartStatusOutput.done channel is read from a goroutine that
locks smartStatusOutput.lock.  If the goroutine that writes to
smartStatusOutput.done is holding smartStatusOutput.lock it can
lead to an AB-BA deadlock.  Call stopActionTableTick from outside
the lock.

Fixes: 143558785
Test: none
Change-Id: I93a10ef9ff16c3953a1c5ccb102b024158358fe4
This commit is contained in:
Colin Cross 2019-10-29 15:22:04 -07:00
parent 765fe7a501
commit 8cc19911b1
1 changed files with 7 additions and 2 deletions

View File

@ -170,6 +170,13 @@ func (s *smartStatusOutput) FinishAction(result status.ActionResult, counts stat
} }
func (s *smartStatusOutput) Flush() { func (s *smartStatusOutput) Flush() {
if s.tableMode {
// Stop the action table tick outside of the lock to avoid lock ordering issues between s.done and
// s.lock, the goroutine in startActionTableTick can get blocked on the lock and be unable to read
// from the channel.
s.stopActionTableTick()
}
s.lock.Lock() s.lock.Lock()
defer s.lock.Unlock() defer s.lock.Unlock()
@ -180,8 +187,6 @@ func (s *smartStatusOutput) Flush() {
s.runningActions = nil s.runningActions = nil
if s.tableMode { if s.tableMode {
s.stopActionTableTick()
// Update the table after clearing runningActions to clear it // Update the table after clearing runningActions to clear it
s.actionTable() s.actionTable()