This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Document that os.path.ismount() returns true for nested btrfs subvolumes
Type: enhancement Stage:
Components: Documentation, Library (Lib) Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, eike, eryksun, jstasiak, serhiy.storchaka
Priority: normal Keywords:

Created on 2019-06-19 10:10 by eike, last changed 2022-04-11 14:59 by admin.

Messages (7)
msg346035 - (view) Author: Eike Fokken (eike) Date: 2019-06-19 10:10
Lets say, we have a btrfs partion with subvolumes @, mounted at /
and home, which was created directly inside @, such that after mounting @, it can be found at /home.

Then 
os.path.ismount("/home") returns True
I would not have expected that, because the program findmnt from the util-linux software package doesn't list it if I run
findmnt -A

I think that the two programs should agree on whether it's a mount point or not but am unsure whether findmnt or os.path.ismount should be altered because I don't know a definite definition of a mountpoint.


Note that I agree with the current behaviour for explicitely mounted subvolumes. An example would be if I have the subvolume @ mounted at / and a subvolume @home created at the toplevel of the btrfs filesystem which is then mounted at /home.
Here findmnt and os.path.ismount agree that this is a mount point.
msg346060 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-06-19 15:57
What does the mountpoint command returns?
msg346063 - (view) Author: Eike Fokken (eike) Date: 2019-06-19 17:22
mountpoint /nested_subvolume returns
/nested_subvolume is not a mountpoint

mountpoint /explicitely_mounted_subvolume returns
/explicitely_mounted_subvolume is a mountpoint

so agrees with findmnt.
msg346068 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-06-19 18:14
os.path.ismount() uses the same simple algorithm as a portable version of mountpoint. But mountpoint (and findmnt) from util-linux uses Linux specific methods (reads /proc/mounts or something like). See also issue29707.
msg346111 - (view) Author: Eike Fokken (eike) Date: 2019-06-20 09:18
I read the other issue, thanks.

What do you mean by "portable version of mountpoint"? Is there a portable version of mountpoint or was it more a figure of speech?

Concerning the issue itself:

What are the priorities with the behaviour of ismount?
Is it more important to be consistent with the system it is run on or is it more important that every python instance on every system would return the same values?

I see merits for both, I'm just curious what the python developers value more.

In case it is the later I propose to change the docs on ismount again to include that it disagrees with Linux on nested btrfs subvolumes.

If you like I can make a pull request for that.
My favourite solution would be to have agreement with linux on this but at the moment I have no idea how that could be implemented without resorting to Linux native utilities.
msg367028 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2020-04-22 17:15
> What do you mean by "portable version of mountpoint"?

posixpath.ismount is based on a portable method to detect a mountpoint in Unix systems, since POSIX lacks a portable function for this. The implementation is simple. A symlink is never a mountpoint. Otherwise compare the lstat of the path and its parent directory. It's a mountpoint if the st_dev fields are different. If not, it's a mountpoint if the st_ino fields are the same (e.g. "/").

The portable method may fail in particular cases. For instance, a bind mount in the Linux kernel (not bindfs) doesn't create a new device. For example, given "/opt" is bound to "opt" in the current directory on the same filesystem, ismount returns a false negative:


    >>> posixpath.ismount('opt')
    False

But it's a mountpoint according to the "/proc/self/mountinfo" table:

    >>> os.system('mountpoint opt')
    opt is a mountpoint
    0

The above false negative is documented, so a precedent exists to simply document the false positive with a btrfs subvolume. Developers can make of it what they will. If it matters to not count this case as a mountpoint, a script will have to implement its own platform-specific solution (e.g. use subprocess to call `mountpoint`).
msg368336 - (view) Author: Eike Fokken (eike) Date: 2020-05-07 13:10
Ok,
this is my proposal for the documentation. I hope you like it.

Is this the correct place to post it or can I make a direct pull request?
old:
.. function:: ismount(path)

   Return ``True`` if pathname *path* is a :dfn:`mount point`: a point in a file
   system where a different file system has been mounted.  The function checks
   whether *path*'s parent, :file:`path/..`, is on a different device than *path*,
   or whether :file:`path/..` and *path* point to the same i-node on the same
   device --- this should detect mount points for all Unix and POSIX variants.


new:
.. function:: ismount(path)

   Return ``True`` if pathname *path* is a :dfn:`mount point`: a point in a file
   system where a different file system has been mounted.  The function checks
   whether *path*'s parent, :file:`path/..`, is on a different device than *path*,
   or whether :file:`path/..` and *path* point to the same i-node on the same
   device --- this should detect mount points for all Unix and POSIX variants.
   Note that in Linux not all mountpoints as recognized by the kernel are found this way.
   An example are bind-mounts.
   Also some directories return ``True`` although Linux doesn't recognize them as mount points.
   An example are nested subvolumes in the Btrfs filesystem
History
Date User Action Args
2022-04-11 14:59:16adminsetgithub: 81520
2021-03-27 18:50:39eryksunsetnosy: + docs@python
title: os.path.ismount returns true on nested btrfs subvolumes -> Document that os.path.ismount() returns true for nested btrfs subvolumes
assignee: docs@python
versions: + Python 3.10, - Python 3.7
components: + Documentation
type: behavior -> enhancement
2020-05-07 13:10:10eikesetmessages: + msg368336
2020-04-22 17:15:33eryksunsetnosy: + eryksun

messages: + msg367028
versions: + Python 3.8, Python 3.9
2020-04-22 08:12:28jstasiaksetnosy: + jstasiak
2019-06-20 09:18:40eikesetmessages: + msg346111
2019-06-19 18:14:33serhiy.storchakasetmessages: + msg346068
2019-06-19 17:22:24eikesetmessages: + msg346063
2019-06-19 15:57:40serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg346060
2019-06-19 10:10:42eikecreate