Merge lp:~bladernr/checkbox/1155619-fix-exit-io-error into lp:checkbox

Proposed by Jeff Lane 
Status: Merged
Approved by: Daniel Manrique
Approved revision: 2064
Merged at revision: 2064
Proposed branch: lp:~bladernr/checkbox/1155619-fix-exit-io-error
Merge into: lp:checkbox
Diff against target: 115 lines (+27/-10)
4 files modified
checkbox/lib/fifo.py (+6/-1)
debian/changelog (+4/-0)
plugins/lock_prompt.py (+16/-8)
plugins/persist_info.py (+1/-1)
To merge this branch: bzr merge lp:~bladernr/checkbox/1155619-fix-exit-io-error
Reviewer Review Type Date Requested Status
Daniel Manrique (community) Approve
Review via email: mp+159889@code.launchpad.net

Description of the change

First: Fixed the I/O Available message. We weren't properly releasing the lock, so I added bits to use the glock release function at shutdown.

This exposed a different issue where the input and output fifo file descriptors were coming back as invalid on close, because for some reason, those FDs were closed out before the close() function of fifo.py was called... so I just wrapped those to catch the exception and comment on it.

This all occurs RIGHT at shutdown so it's all just garbage collection.

To post a comment you must log in.
2064. By Jeff Lane 

rebased to make tarmac happy

Revision history for this message
Daniel Manrique (roadmr) wrote :

+1, thanks! Great work tracking this down.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'checkbox/lib/fifo.py'
--- checkbox/lib/fifo.py 2012-06-09 15:50:39 +0000
+++ checkbox/lib/fifo.py 2013-04-19 21:23:27 +0000
@@ -18,6 +18,7 @@
18#18#
19import os19import os
20import struct20import struct
21import logging
2122
22from checkbox.contrib.bpickle import dumps, loads23from checkbox.contrib.bpickle import dumps, loads
23from checkbox.lib.selector import Selector, SelectorIO24from checkbox.lib.selector import Selector, SelectorIO
@@ -36,7 +37,11 @@
36 self.close()37 self.close()
3738
38 def close(self):39 def close(self):
39 os.close(self.fileno)40 try:
41 os.close(self.fileno)
42 except OSError as e:
43 logging.warning("Problem closing the fifo")
44 logging.warning(e)
4045
41 def wait_for(self, operation):46 def wait_for(self, operation):
42 if self._timeout is not None:47 if self._timeout is not None:
4348
=== modified file 'debian/changelog'
--- debian/changelog 2013-04-19 20:16:22 +0000
+++ debian/changelog 2013-04-19 21:23:27 +0000
@@ -10,6 +10,10 @@
10 * jobs/led.txt.in: Modified Jobs: led/power, led/wlan, led/wlan-disabled. New10 * jobs/led.txt.in: Modified Jobs: led/power, led/wlan, led/wlan-disabled. New
11 jobs: led/power-blink-suspend, led/suspend, led/mute11 jobs: led/power-blink-suspend, led/suspend, led/mute
12 jobs/keys.txt.in: modified keys/wireless12 jobs/keys.txt.in: modified keys/wireless
13 * plugins/lock_prompt.py: added a lock release to cleanly clear lock on stop.
14 plugins/persist_prompt.py: promoted save to run before lock release.
15 checkbox/lib/fifo.py: trap OSError exception at close when the input/output
16 fifo fds disappear before fifo.close() can get to them. (LP: #115561)
1317
14 [ Brendan Donegan ]18 [ Brendan Donegan ]
15 * scripts/sources_test - modified script so that it takes sources list19 * scripts/sources_test - modified script so that it takes sources list
1620
=== modified file 'plugins/lock_prompt.py'
--- plugins/lock_prompt.py 2011-02-15 19:43:24 +0000
+++ plugins/lock_prompt.py 2013-04-19 21:23:27 +0000
@@ -20,7 +20,7 @@
20import fcntl20import fcntl
21import posixpath21import posixpath
22import signal22import signal
2323import logging
24from time import time24from time import time
2525
26from gettext import gettext as _26from gettext import gettext as _
@@ -40,21 +40,24 @@
4040
41 # Timeout after which to show an error prompt.41 # Timeout after which to show an error prompt.
42 timeout = Int(default=0)42 timeout = Int(default=0)
43 logger = logging.getLogger()
4344
44 def register(self, manager):45 def register(self, manager):
45 super(LockPrompt, self).register(manager)46 super(LockPrompt, self).register(manager)
4647
47 self._lock = None48 self._lock = None
49 self._fd = None
4850
49 self._manager.reactor.call_on(51 self._manager.reactor.call_on(
50 "prompt-begin", self.prompt_begin, -1000)52 "prompt-begin", self.prompt_begin, -1000)
53 self._manager.reactor.call_on("stop", self.release, 1000)
5154
52 def prompt_begin(self, interface):55 def prompt_begin(self, interface):
53 directory = posixpath.dirname(self.filename)56 directory = posixpath.dirname(self.filename)
54 safe_make_directory(directory)57 safe_make_directory(directory)
5558
56 # Try to lock the process59 # Try to lock the process
57 self._lock = GlobalLock(self.filename)60 self._lock = GlobalLock(self.filename, logger=self.logger)
58 try:61 try:
59 self._lock.acquire()62 self._lock.acquire()
60 except LockAlreadyAcquired:63 except LockAlreadyAcquired:
@@ -67,12 +70,17 @@
67 def handler(signum, frame):70 def handler(signum, frame):
68 if not posixpath.exists(self.filename):71 if not posixpath.exists(self.filename):
69 self._manager.reactor.stop_all()72 self._manager.reactor.stop_all()
7073
71 signal.signal(signal.SIGIO, handler)74 signal.signal(signal.SIGIO, handler)
72 fd = os.open(directory, os.O_RDONLY)75 self._fd = os.open(directory, os.O_RDONLY)
7376
74 fcntl.fcntl(fd, fcntl.F_SETSIG, 0)77 fcntl.fcntl(self._fd, fcntl.F_SETSIG, 0)
75 fcntl.fcntl(fd, fcntl.F_NOTIFY, fcntl.DN_DELETE|fcntl.DN_MULTISHOT)78 fcntl.fcntl(self._fd, fcntl.F_NOTIFY, fcntl.DN_DELETE|fcntl.DN_MULTISHOT)
7679
80 def release(self):
81 # Properly release to the lock
82 self._lock.release(skip_delete=True)
83 os.close(self._fd)
84 os.unlink(self.filename)
7785
78factory = LockPrompt86factory = LockPrompt
7987
=== modified file 'plugins/persist_info.py'
--- plugins/persist_info.py 2012-06-20 20:33:09 +0000
+++ plugins/persist_info.py 2013-04-19 21:23:27 +0000
@@ -40,7 +40,7 @@
40 self._manager.reactor.call_on(rt, rh, -100)40 self._manager.reactor.call_on(rt, rh, -100)
4141
42 # Save persist data last42 # Save persist data last
43 self._manager.reactor.call_on("stop", self.save, 1000)43 self._manager.reactor.call_on("stop", self.save, 900)
4444
45 #This should fire first thing during the gathering phase.45 #This should fire first thing during the gathering phase.
46 self._manager.reactor.call_on("gather", self.begin_gather, -900)46 self._manager.reactor.call_on("gather", self.begin_gather, -900)

Subscribers

People subscribed via source and target branches