Bug 1058482

Summary: tmpwatch removes python multiprocessing sockets
Product: Red Hat Enterprise Linux 7 Reporter: Miloslav Trmač <mitr>
Component: pythonAssignee: Matej Stuchlik <mstuchli>
Status: CLOSED ERRATA QA Contact: Filip Holec <fholec>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.0CC: bkabrda, cstpierr, fholec, isenfeld, jberan, lnykryn, mstuchli, psplicha, systemd-maint-list
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: python-2.7.5-29.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 1058310 Environment:
Last Closed: 2015-11-19 12:42:08 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1058310    

Description Miloslav Trmač 2014-01-27 21:21:42 UTC
systemd maintainers: Please add an exclusion equivalent to attachment #867073 [details] to tmpfiles.d , which has replaced the tmpwatch cron.daily script in RHEL-7.

(For #678161 you wanted to move this to a more specific package, but every installation includes Python due to yum/dnf, so adding an extra file to the Python interpreter instead of adding it to the main tmp.conf would be pointless overhead IMHO; if you disagree, feel free to reassign.)

+++ This bug was initially created as a clone of Bug #1058310 +++

Description of problem:

The Python multiprocessing library (http://docs.python.org/2/library/multiprocessing.html) can open an ephemeral socket for interprocess communication based on a temporary file.  It creates these temp files in /tmp/pymp-XXXXXX.  However, the atomic temp file creation does not ever list the directory, so its atime is not updated.  However, the pymp-* directory is only generated once, when the program is started.

As a result, if a Python program runs for more than ten days (the default cleanup time for /tmp in /etc/cron.d/tmpwatch), creates sockets (e.g., with multiprocessing.connnection.Listener()), and has no open sockets when tmpwatch runs, the pymp-* directory will be removed, and the next time the Python program attempts to open a socket it will fail spectacularly.

Version-Release number of selected component (if applicable):

tmpwatch-2.9.16-4.el6.x86_64
python-2.6.6-51.el6.x86_64
python-libs-2.6.6-51.el6.x86_64

How reproducible:

Always.

Steps to Reproduce:

create-socket-and-sleep.py is attached.  Run:

./create-socket-and-sleep.py 864010 & sleep 864005; bash /etc/cron.daily/tmpwatch

This takes ten days to run, so if you want something quicker, you can run:

./create-socket-and-sleep.py 70 & sleep 65;/usr/sbin/tmpwatch -x /tmp/.X11-unix -x /tmp/.XIM-unix -x /tmp/.font-unix         -x /tmp/.ICE-unix -x /tmp/.Test-unix 1m /tmp

The tmpwatch command there is taken directly from the stock /etc/cron.daily/tmpwatch, with '240' (hours) changed to '1m' so that this can be run in a timely fashion.

Actual results:

% ./create-socket-and-sleep.py 70 & sleep 65;/usr/sbin/tmpwatch -x /tmp/.X11-unix -x /tmp/.XIM-unix -x /tmp/.font-unix         -x /tmp/.ICE-unix -x /tmp/.Test-unix 1m /tmp
[1] 7361
/tmp/pymp-oki8QE/listener-AA8c0N
Traceback (most recent call last):
  File "./create-socket-and-sleep.py", line 19, in <module>
    sys.exit(main())
  File "./create-socket-and-sleep.py", line 15, in main
    l = Listener()
  File "/usr/lib64/python2.6/multiprocessing/connection.py", line 106, in __init__
    self._listener = SocketListener(address, family, backlog)
  File "/usr/lib64/python2.6/multiprocessing/connection.py", line 227, in __init__
    self._socket.bind(address)
  File "<string>", line 1, in bind
socket.error: [Errno 2] No such file or directory
Traceback (most recent call last):
  File "/usr/lib64/python2.6/multiprocessing/util.py", line 235, in _run_finalizers
    finalizer()
  File "/usr/lib64/python2.6/multiprocessing/util.py", line 174, in __call__
    res = self._callback(*self._args, **self._kwargs)
  File "/usr/lib64/python2.6/shutil.py", line 204, in rmtree
    onerror(os.listdir, path, sys.exc_info())
  File "/usr/lib64/python2.6/shutil.py", line 202, in rmtree
    names = os.listdir(path)
OSError: [Errno 2] No such file or directory: '/tmp/pymp-oki8QE'

Expected results:

The file names of two temp files should be printed.

Additional info:

--- Additional comment from Chris St. Pierre on 2014-01-27 08:50:35 EST ---

A patch for /etc/cron.d/tmpwatch that fixes the issue is attached.

--- Additional comment from Miloslav Trmač on 2014-01-27 16:17:10 EST ---

Thanks for your report and the patch.

I'm not... thrilled... about the way multiprocessing uses the temporary directory, but we have a precedent in doing the same for bug #527425 .

Needs to be fixed for RHEL 7 first, though, to avoid a regression on update,

Comment 2 Lukáš Nykrýn 2014-01-31 11:52:43 UTC
I think that putting that drop-in into the package which really needs it is a nicer solution.

Comment 4 Bohuslav "Slavek" Kabrda 2015-04-27 12:25:00 UTC
The solution is straightforward here, dev_ack+

Comment 11 errata-xmlrpc 2015-11-19 12:42:08 UTC
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.

https://rhn.redhat.com/errata/RHSA-2015-2101.html