patch. Testing it now.

On 16 December 2014 at 09:22, Marc Leeman <marc.lee...@gmail.com> wrote:
> Just to let you know that the current version upstream is not enough
> to solve the problem. I copied their version in the jessie release,
> backported it to wheezy and tried it.
>
> After less than 24h, the system is stuck again, The problem can be traced to:
>
>     @wrap_exceptions
>     def threads(self):
>
> Where there is still an open that does not close properly:
>
> 2014-12-16 09:21:21,185 - com.barco.mgs.TeamMgrM56094 - INFO - start -
> Received request to start a team sid T10621 - wid W90616
> 2014-12-16 09:21:21,185 - com.barco.mgs.TeamMgrM56094 - ERROR - start
> - ['  File "/usr/lib/pymodules/python2.7/Mgs2/Team/TeamMgr.py", line
> 831, in start\n    limit = status.cpu_percent\n', '  File
> "/usr/lib/pymodules/python2.7/Mgs2/SystemStatusBase.py", line 346, in
> cpu_percent\n', '  File
> "/usr/lib/pymodules/python2.7/Mgs2/SystemStatusBase.py", line 349, in
> get_cpu_percent\n', '  File
> "/usr/lib/python2.7/dist-packages/psutil/__init__.py", line 1509, in
> cpu_percent\n    _last_cpu_times = cpu_times()\n', '  File
> "/usr/lib/python2.7/dist-packages/psutil/__init__.py", line 1439, in
> cpu_times\n    return _psplatform.cpu_times()\n', '  File
> "/usr/lib/python2.7/dist-packages/psutil/_pslinux.py", line 215, in
> cpu_times\n    with open(\'/proc/stat\', \'rb\') as f:\n']
> 2014-12-16 09:21:21,186 - com.barco.mgs.TeamMgrM56094 - ERROR - start
> - [Errno 24] Too many open files: '/proc/stat'
> 2014-12-16 09:21:21,186 - com.barco.mgs.TeamMgrM56094 - ERROR - start
> - Error during worker creation [Errno 24] Too many open files:
> '/proc/stat'
>
>
>
> <...snip...>
> rtsp_mgs. 26609 29136        root  txt   unknown
>    /proc/26609/task/29136/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29136        root NOFD
>    /proc/26609/task/29136/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29144        root  cwd   unknown
>    /proc/26609/task/29144/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29144        root  rtd   unknown
>    /proc/26609/task/29144/root (readlink: Permission denied)
> rtsp_mgs. 26609 29144        root  txt   unknown
>    /proc/26609/task/29144/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29144        root NOFD
>    /proc/26609/task/29144/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29147        root  cwd   unknown
>    /proc/26609/task/29147/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29147        root  rtd   unknown
>    /proc/26609/task/29147/root (readlink: Permission denied)
> rtsp_mgs. 26609 29147        root  txt   unknown
>    /proc/26609/task/29147/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29147        root NOFD
>    /proc/26609/task/29147/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29148        root  cwd   unknown
>    /proc/26609/task/29148/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29148        root  rtd   unknown
>    /proc/26609/task/29148/root (readlink: Permission denied)
> rtsp_mgs. 26609 29148        root  txt   unknown
>    /proc/26609/task/29148/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29148        root NOFD
>    /proc/26609/task/29148/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29149        root  cwd   unknown
>    /proc/26609/task/29149/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29149        root  rtd   unknown
>    /proc/26609/task/29149/root (readlink: Permission denied)
> rtsp_mgs. 26609 29149        root  txt   unknown
>    /proc/26609/task/29149/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29149        root NOFD
>    /proc/26609/task/29149/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29152        root  cwd   unknown
>    /proc/26609/task/29152/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29152        root  rtd   unknown
>    /proc/26609/task/29152/root (readlink: Permission denied)
> rtsp_mgs. 26609 29152        root  txt   unknown
>    /proc/26609/task/29152/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29152        root NOFD
>    /proc/26609/task/29152/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29153        root  cwd   unknown
>    /proc/26609/task/29153/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29153        root  rtd   unknown
>    /proc/26609/task/29153/root (readlink: Permission denied)
> rtsp_mgs. 26609 29153        root  txt   unknown
>    /proc/26609/task/29153/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29153        root NOFD
>    /proc/26609/task/29153/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29155        root  cwd   unknown
>    /proc/26609/task/29155/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29155        root  rtd   unknown
>    /proc/26609/task/29155/root (readlink: Permission denied)
> rtsp_mgs. 26609 29155        root  txt   unknown
>    /proc/26609/task/29155/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29155        root NOFD
>    /proc/26609/task/29155/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29157        root  cwd   unknown
>    /proc/26609/task/29157/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29157        root  rtd   unknown
>    /proc/26609/task/29157/root (readlink: Permission denied)
> rtsp_mgs. 26609 29157        root  txt   unknown
>    /proc/26609/task/29157/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29157        root NOFD
>    /proc/26609/task/29157/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29161        root  cwd   unknown
>    /proc/26609/task/29161/cwd (readlink: Permission denied)
> rtsp_mgs. 26609 29161        root  rtd   unknown
>    /proc/26609/task/29161/root (readlink: Permission denied)
> rtsp_mgs. 26609 29161        root  txt   unknown
>    /proc/26609/task/29161/exe (readlink: Permission denied)
> rtsp_mgs. 26609 29161        root NOFD
>    /proc/26609/task/29161/fd (opendir: Permission denied)
> rtsp_mgs. 26609 29165        root  cwd   unknown
>    /proc/26609/task/29165/cwd (readlink: Permission denied)
> <...snip...>
>
> On 8 December 2014 at 17:33, Sandro Tosi <mo...@debian.org> wrote:
>> control: forward -1 https://github.com/giampaolo/psutil/issues/556
>>
>> On Mon, Dec 8, 2014 at 4:28 PM, Marc Leeman <marc.lee...@gmail.com> wrote:
>>>> it seems those were addressed in
>>>> https://github.com/giampaolo/psutil/commit/3760d9593524e553e9e012c6b63cd802e3b25a46
>>>> but it was not released in the last upstream version - asked upstream
>>>> for clarification on when they will be released.
>>>
>>> I don't think the commit solves all the problems: when looking at the
>>> commit, I still see a lot of returns in a try block, while the file
>>> handle is only closed in the finally block. This means that the
>>> control flow returns before closing. It does seem to solve some open
>>> file handles when something fails in the try.
>>>
>>> The problem here popped up after a weekend and there were no errors to
>>> be seen during operation before hitting the file handle limit.
>>
>> yup agreed, reported upstream as referred above.
>>
>> Regards,
>> --
>> Sandro Tosi (aka morph, morpheus, matrixhasu)
>> My website: http://matrixhasu.altervista.org/
>> Me at Debian: http://wiki.debian.org/SandroTosi
Description: A lot of filehandles are left dangling when threads go missing
 .
 python-psutil (2.1.1-1+barco4) unstable; urgency=low
 .
   * more filehandles were not close properly in psutil
Author: Marc Leeman <marc.lee...@barco.com>

---
Bug-Debian: http://bugs.debian.org/772543
Last-Update: 2014-12-16

Index: python-psutil-2.1.1/psutil/_pslinux.py
===================================================================
--- python-psutil-2.1.1.orig/psutil/_pslinux.py	2014-12-16 09:04:44.000000000 +0000
+++ python-psutil-2.1.1/psutil/_pslinux.py	2014-12-16 09:08:37.692699822 +0000
@@ -669,16 +669,20 @@
         self.pid = pid
         self._name = None
 
+    def __py3_name(self):
+    	with open("/proc/%s/stat" % (self.pid), "rt", encoding=DEFAULT_ENCODING) as f:
+            return f.read().split(' ')[1].replace('(', '').replace(')', '')
+
+    def __py2_name(self):
+    	with open("/proc/%s/stat" % (self.pid), "rt") as f:
+            return f.read().split(' ')[1].replace('(', '').replace(')', '')
+
     @wrap_exceptions
     def name(self):
-        fname = "/proc/%s/stat" % self.pid
         if PY3:
-            f = open(fname, "rt", encoding=DEFAULT_ENCODING)
+            return self.__py3_name()
         else:
-            f = open(fname, "rt")
-        with f:
-            # XXX - gets changed later and probably needs refactoring
-            return f.read().split(' ')[1].replace('(', '').replace(')', '')
+            return self.__py2_name()
 
     def exe(self):
         try:
@@ -707,16 +711,20 @@
             exe = exe[:-10]
         return exe
 
+    def __py3_cmdline(self):
+    	with open("/proc/%s/cmdline" % (self.pid), "rt", encoding=DEFAULT_ENCODING) as f:
+            return [x for x in f.read().split('\x00') if x]
+
+    def __py2_cmdline(self):
+    	with open("/proc/%s/cmdline" % (self.pid), "rt") as f:
+            return [x for x in f.read().split('\x00') if x]
+
     @wrap_exceptions
     def cmdline(self):
-        fname = "/proc/%s/cmdline" % self.pid
         if PY3:
-            f = open(fname, "rt", encoding=DEFAULT_ENCODING)
+            return self.__py3_cmdline()
         else:
-            f = open(fname, "rt")
-        with f:
-            # return the args as a list
-            return [x for x in f.read().split('\x00') if x]
+            return self.__py2_cmdline()
 
     @wrap_exceptions
     def terminal(self):
@@ -820,73 +828,65 @@
             Fields are explained in 'man proc'; here is an updated (Apr 2012)
             version: http://goo.gl/fmebo
             """
-            f = None
             try:
-                f = open("/proc/%s/smaps" % self.pid, "rt")
-                first_line = f.readline()
-                current_block = [first_line]
-
-                def get_blocks():
-                    data = {}
-                    for line in f:
-                        fields = line.split(None, 5)
-                        if not fields[0].endswith(':'):
-                            # new block section
-                            yield (current_block.pop(), data)
-                            current_block.append(line)
-                        else:
-                            try:
-                                data[fields[0]] = int(fields[1]) * 1024
-                            except ValueError:
-                                if fields[0].startswith('VmFlags:'):
-                                    # see issue #369
-                                    continue
-                                else:
-                                    raise ValueError("don't know how to inte"
-                                                     "rpret line %r" % line)
-                    yield (current_block.pop(), data)
-
-                if first_line:  # smaps file can be empty
-                    for header, data in get_blocks():
-                        hfields = header.split(None, 5)
-                        try:
-                            addr, perms, offset, dev, inode, path = hfields
-                        except ValueError:
-                            addr, perms, offset, dev, inode, path = \
-                                hfields + ['']
-                        if not path:
-                            path = '[anon]'
-                        else:
-                            path = path.strip()
-                        yield (addr, perms, path,
-                               data['Rss:'],
-                               data.get('Size:', 0),
-                               data.get('Pss:', 0),
-                               data.get('Shared_Clean:', 0),
-                               data.get('Shared_Dirty:', 0),
-                               data.get('Private_Clean:', 0),
-                               data.get('Private_Dirty:', 0),
-                               data.get('Referenced:', 0),
-                               data.get('Anonymous:', 0),
-                               data.get('Swap:', 0))
-                f.close()
-            except EnvironmentError as err:
-                # XXX - Can't use wrap_exceptions decorator as we're
-                # returning a generator;  this probably needs some
-                # refactoring in order to avoid this code duplication.
-                if f is not None:
-                    f.close()
-                if err.errno in (errno.ENOENT, errno.ESRCH):
-                    raise NoSuchProcess(self.pid, self._name)
-                if err.errno in (errno.EPERM, errno.EACCES):
-                    raise AccessDenied(self.pid, self._name)
-                raise
-            except:
-                if f is not None:
-                    f.close()
-                raise
-            f.close()
-
+	    	with open("/proc/%s/smaps" % self.pid, "rt") as f:
+			first_line = f.readline()
+			current_block = [first_line]
+
+			def get_blocks():
+			    data = {}
+			    for line in f:
+				fields = line.split(None, 5)
+				if not fields[0].endswith(':'):
+				    # new block section
+				    yield (current_block.pop(), data)
+				    current_block.append(line)
+				else:
+				    try:
+					data[fields[0]] = int(fields[1]) * 1024
+				    except ValueError:
+					if fields[0].startswith('VmFlags:'):
+					    # see issue #369
+					    continue
+					else:
+					    raise ValueError("don't know how to inte"
+							     "rpret line %r" % line)
+			    yield (current_block.pop(), data)
+
+			if first_line:  # smaps file can be empty
+			    for header, data in get_blocks():
+				hfields = header.split(None, 5)
+				try:
+				    addr, perms, offset, dev, inode, path = hfields
+				except ValueError:
+				    addr, perms, offset, dev, inode, path = \
+					hfields + ['']
+				if not path:
+				    path = '[anon]'
+				else:
+				    path = path.strip()
+				yield (addr, perms, path,
+				       data['Rss:'],
+				       data.get('Size:', 0),
+				       data.get('Pss:', 0),
+				       data.get('Shared_Clean:', 0),
+				       data.get('Shared_Dirty:', 0),
+				       data.get('Private_Clean:', 0),
+				       data.get('Private_Dirty:', 0),
+				       data.get('Referenced:', 0),
+				       data.get('Anonymous:', 0),
+				       data.get('Swap:', 0))
+	    except EnvironmentError as err:
+		# XXX - Can't use wrap_exceptions decorator as we're
+		# returning a generator;  this probably needs some
+		# refactoring in order to avoid this code duplication.
+		if err.errno in (errno.ENOENT, errno.ESRCH):
+		    raise NoSuchProcess(self.pid, self._name)
+		if err.errno in (errno.EPERM, errno.EACCES):
+		    raise AccessDenied(self.pid, self._name)
+		raise
+	    except:
+		raise
     else:
         def memory_maps(self):
             msg = "couldn't find /proc/%s/smaps; kernel < 2.6.14 or "  \
@@ -934,7 +934,8 @@
         hit_enoent = False
         for thread_id in thread_ids:
             try:
-                f = open("/proc/%s/task/%s/stat" % (self.pid, thread_id), 'rb')
+                with open("/proc/%s/task/%s/stat" % (self.pid, thread_id), 'rb') as f:
+                	st = f.read().strip()
             except EnvironmentError as err:
                 if err.errno == errno.ENOENT:
                     # no such file or directory; it means thread
@@ -942,8 +943,6 @@
                     hit_enoent = True
                     continue
                 raise
-            with f:
-                st = f.read().strip()
             # ignore the first two values ("pid (exe)")
             st = st[st.find(b')') + 2:]
             values = st.split(b' ')

Reply via email to