-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
os.path.ismount doesn't work for mounts the user doesn't have permission to see #46718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm not sure why this is, but ismount doesn't always work for me. It $ mount
...
/dev/sda1 on /media/windows type ntfs (ro,noexec,nosuid,nodev,user=ross)
redbeard.local:/home on /media/home type nfs
(rw,user=ross,noatime,rsize=65536,wsize=65536,retry=1,nfsvers=3,posix,intr,addr=192.168.1.67) $ python
Python 2.4.5 (#2, Mar 12 2008, 00:15:51)
[GCC 4.2.3 (Debian 4.2.3-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> ismount("/media/windows")
False
>>> ismount("/media/home")
True |
I cannot reproduce that; it works fine for me, with the same Python Can you please debug through ismount, and report which of the calls fail? The code of ismount reads def ismount(path):
"""Test whether a path is a mount point"""
try:
s1 = os.stat(path)
s2 = os.stat(join(path, '..'))
except os.error:
return False # It doesn't exist -- so not a mount point :-)
dev1 = s1.st_dev
dev2 = s2.st_dev
if dev1 != dev2:
return True # path/.. on a different device as path
ino1 = s1.st_ino
ino2 = s2.st_ino
if ino1 == ino2:
return True # path/.. is the same i-node as path
return False |
Aha. The contents of the mount point are only accessible by root: $ stat /media/windows/..
stat: cannot stat `/media/windows/..': Permission denied This falls into the except block, so false is returned. If ismount() used os.path.dirname() instead of appending "..", then this |
But it may change the function result if the argument is a symlink to |
Another problem of using os.path.dirname is that for /A/B, it will So here is a possible course of action for ismount: |
Confirm this problem exists in 2.7 as well. |
I found another case where the result of ismount() is misleading. I'm using a FUSE-based filesystem controlled by a python supervisor daemon. When the fuse daemon dies and you try to access the filesystem with os.stat() it returns: If the idea of ismount() is to show what paths are mountpoints, in this case it should return True, even if it's non-accessible (the fuse daemon died in this case, it might also happen for a stale NFS mount *not checked* ). |
This bug is still present and annoying. Symlinks will also work because they are checked/excluded before the part of the code where the patch is in. msg222528 is not related to the original bug and should be opened separately. |
Is there any more info needed to the issue or the patch? There is an issue in ansible depending on this fix: ansible/ansible-modules-core#2186 Also the current development version is affected (I manually checked 2.7, 3.0, 3.5, dev). |
Thanks for the patch, Robin. The patch needs a test case. See Lib/test/test_posixpath.py. The test coverage of ismount() is not high, so we need more tests. Also, I don't have much time to work on this right now, but Antoine's suggestion in msg71294 sounds good to me. Did you try it? |
Antoine's suggestion does not work, because "dirname" does not cover enough cases (for example trailing slash, possibly more). As suggested by him I now use realpath (instead of abspath). I can't come up with a symlink-situation that is broken with the old code, but realpath is what "ismount" actually means. I also added a testcase that resembles the issue, i.e. it fails with the old code and passes with the fix. I mock the "Permission denied" by raising a generic OSError. Mocking can not resemble every real-life situation but by simulating all issues reporting and then fixing them, one should get a solid test coverage. I also took the liberty of minor cleanup in/around the functions changed, i.e. remove unused imports and remove single-use variables to make the code easier to read. Attached the updated patch. |
any comments/updates on merging this? |
Any progress on merging this? Ansible integrated the patch posted here as a workaround of an issue this caused. So there was some external review of the fix. See |
Based on the review by SilentGhost I removed all refactoring-changes and only left the one line needed for the fix. |
What if use os.stat(dirname(path)) instead of os.lstat(parent)? - if isinstance(path, bytes):
- parent = join(path, b'..')
- else:
- parent = join(path, '..')
try:
- s2 = os.lstat(parent)
+ s2 = os.stat(dirname(path))
except OSError:
return False |
Ah, forget, this doesn't work with path like "./.". Agreed, using realpath() is the simplest solution. |
New changeset cbc78ca21977 by R David Murray in branch '3.5': New changeset db9126139969 by R David Murray in branch 'default': |
Thanks, Robin. The patch doesn't apply on 2.7. I'll leave this open to see if anyone wants to do the 2.7 port. |
New changeset dd0f1fa809c5 by R David Murray in branch 'default': |
David, issue2466_ismount_py2.7_port.patch does the py2.7 port. I also back port other ismount test cases not existing in py2.7. |
New changeset 75111791110b by R David Murray in branch '2.7': |
Thanks, Xiang. |
This is causing a test failure on the windows 8 bot. Can you fix it Xiang? Otherwise I'll have to revert. http://buildbot.python.org/all/builders/AMD64%20Windows8%202.7/builds/870 ====================================================================== Traceback (most recent call last):
File "D:\buildarea\2.7.bolen-windows8\build\lib\test\test_posixpath.py", line 110, in test_islink
os.symlink(test_support.TESTFN + "1", test_support.TESTFN + "2")
AttributeError: 'module' object has no attribute 'symlink' ====================================================================== Traceback (most recent call last):
File "D:\buildarea\2.7.bolen-windows8\build\lib\test\test_posixpath.py", line 221, in test_ismount_symlinks
os.unlink(ABSTFN)
WindowsError: [Error 2] The system cannot find the file specified: 'D:\\buildarea\\2.7.bolen-windows8\\build\\build\\test_python_2024/@test_2024_tmp' |
Oh, sorry. Upload bot_failure_fix.patch to fix this. |
New changeset 63799c310b69 by R David Murray in branch '2.7': |
Thanks, Xiang. Also thanks to SilentGhost, who noticed the buildbot failure I missed. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: