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
1=== modified file 'checkbox/lib/fifo.py'
2--- checkbox/lib/fifo.py 2012-06-09 15:50:39 +0000
3+++ checkbox/lib/fifo.py 2013-04-19 21:23:27 +0000
4@@ -18,6 +18,7 @@
5 #
6 import os
7 import struct
8+import logging
9
10 from checkbox.contrib.bpickle import dumps, loads
11 from checkbox.lib.selector import Selector, SelectorIO
12@@ -36,7 +37,11 @@
13 self.close()
14
15 def close(self):
16- os.close(self.fileno)
17+ try:
18+ os.close(self.fileno)
19+ except OSError as e:
20+ logging.warning("Problem closing the fifo")
21+ logging.warning(e)
22
23 def wait_for(self, operation):
24 if self._timeout is not None:
25
26=== modified file 'debian/changelog'
27--- debian/changelog 2013-04-19 20:16:22 +0000
28+++ debian/changelog 2013-04-19 21:23:27 +0000
29@@ -10,6 +10,10 @@
30 * jobs/led.txt.in: Modified Jobs: led/power, led/wlan, led/wlan-disabled. New
31 jobs: led/power-blink-suspend, led/suspend, led/mute
32 jobs/keys.txt.in: modified keys/wireless
33+ * plugins/lock_prompt.py: added a lock release to cleanly clear lock on stop.
34+ plugins/persist_prompt.py: promoted save to run before lock release.
35+ checkbox/lib/fifo.py: trap OSError exception at close when the input/output
36+ fifo fds disappear before fifo.close() can get to them. (LP: #115561)
37
38 [ Brendan Donegan ]
39 * scripts/sources_test - modified script so that it takes sources list
40
41=== modified file 'plugins/lock_prompt.py'
42--- plugins/lock_prompt.py 2011-02-15 19:43:24 +0000
43+++ plugins/lock_prompt.py 2013-04-19 21:23:27 +0000
44@@ -20,7 +20,7 @@
45 import fcntl
46 import posixpath
47 import signal
48-
49+import logging
50 from time import time
51
52 from gettext import gettext as _
53@@ -40,21 +40,24 @@
54
55 # Timeout after which to show an error prompt.
56 timeout = Int(default=0)
57+ logger = logging.getLogger()
58
59 def register(self, manager):
60 super(LockPrompt, self).register(manager)
61
62 self._lock = None
63+ self._fd = None
64
65 self._manager.reactor.call_on(
66 "prompt-begin", self.prompt_begin, -1000)
67+ self._manager.reactor.call_on("stop", self.release, 1000)
68
69 def prompt_begin(self, interface):
70 directory = posixpath.dirname(self.filename)
71 safe_make_directory(directory)
72
73 # Try to lock the process
74- self._lock = GlobalLock(self.filename)
75+ self._lock = GlobalLock(self.filename, logger=self.logger)
76 try:
77 self._lock.acquire()
78 except LockAlreadyAcquired:
79@@ -67,12 +70,17 @@
80 def handler(signum, frame):
81 if not posixpath.exists(self.filename):
82 self._manager.reactor.stop_all()
83-
84+
85 signal.signal(signal.SIGIO, handler)
86- fd = os.open(directory, os.O_RDONLY)
87-
88- fcntl.fcntl(fd, fcntl.F_SETSIG, 0)
89- fcntl.fcntl(fd, fcntl.F_NOTIFY, fcntl.DN_DELETE|fcntl.DN_MULTISHOT)
90-
91+ self._fd = os.open(directory, os.O_RDONLY)
92+
93+ fcntl.fcntl(self._fd, fcntl.F_SETSIG, 0)
94+ fcntl.fcntl(self._fd, fcntl.F_NOTIFY, fcntl.DN_DELETE|fcntl.DN_MULTISHOT)
95+
96+ def release(self):
97+ # Properly release to the lock
98+ self._lock.release(skip_delete=True)
99+ os.close(self._fd)
100+ os.unlink(self.filename)
101
102 factory = LockPrompt
103
104=== modified file 'plugins/persist_info.py'
105--- plugins/persist_info.py 2012-06-20 20:33:09 +0000
106+++ plugins/persist_info.py 2013-04-19 21:23:27 +0000
107@@ -40,7 +40,7 @@
108 self._manager.reactor.call_on(rt, rh, -100)
109
110 # Save persist data last
111- self._manager.reactor.call_on("stop", self.save, 1000)
112+ self._manager.reactor.call_on("stop", self.save, 900)
113
114 #This should fire first thing during the gathering phase.
115 self._manager.reactor.call_on("gather", self.begin_gather, -900)

Subscribers

People subscribed via source and target branches