Commit 404935ed by rfkelly0

add default timeout to fuse.MountProcess.unmount, after which it will be forcibly terminated

parent 02ebf187
......@@ -380,6 +380,8 @@ class MountProcess(subprocess.Popen):
# just copy the relevant bits of the Popen interface. For now, this
# spawn-a-new-interpreter solution is the easiest to get up and running.
unmount_timeout = 5
def __init__(self,fs,path,fuse_opts={},nowait=False,**kwds):
self.path = path
if nowait or kwds.get("close_fds",False):
......@@ -402,11 +404,21 @@ class MountProcess(subprocess.Popen):
def unmount(self):
"""Cleanly unmount the FUSE filesystem, terminating this subprocess."""
if hasattr(self,"terminate"):
self.terminate()
else:
self.terminate()
tmr = threading.Timer(self.unmount_timeout,self.kill)
tmr.start()
self.wait()
tmr.cancel()
if not hasattr(subprocess.Popen,"terminate"):
def terminate(self):
"""Gracefully terminate the subprocess."""
os.kill(self.pid,signal.SIGTERM)
self.communicate()
if not hasattr(subprocess.Popen,"kill"):
def kill(self):
"""Forcibly terminate the subprocess."""
os.kill(self.pid,signal.SIGKILL)
@staticmethod
def _do_mount_nowait(data):
......@@ -443,7 +455,6 @@ class MountProcess(subprocess.Popen):
os.write(w,"E")
if __name__ == "__main__":
import os, os.path
from fs.tempfs import TempFS
......
......@@ -622,8 +622,12 @@ class ThreadingTestCases:
self.fs.copydir("a","copy of a",overwrite=True)
# This should error out since we're not overwriting
self.assertRaises(DestinationExistsError,self._runThreads,copydir,copydir)
# This should run to completion and give a valid state
self._runThreads(copydir_overwrite,copydir_overwrite)
# This should run to completion and give a valid state, unless
# files get locked when written to.
try:
self._runThreads(copydir_overwrite,copydir_overwrite)
except ResourceLockedError:
pass
self.assertTrue(self.fs.isdir("copy of a"))
self.assertTrue(self.fs.isdir("copy of a/b"))
self.assertEqual(self.fs.getcontents("copy of a/b/parrot.txt"),"pining for the fiords")
......
......@@ -112,7 +112,13 @@ class TestFUSE(unittest.TestCase,FSTestCases,ThreadingTestCases):
def tearDown(self):
self.mount_proc.unmount()
self.temp_fs.close()
try:
self.temp_fs.close()
except OSError:
# Sometimes FUSE hangs onto the mountpoint if mount_proc is
# forcibly killed. Shell out to fusermount to make sure.
fuse.unmount(self.mount_point)
self.temp_fs.close()
def check(self,p):
return self.mounted_fs.exists(p)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment