+ if not was_mounted and path != os.path.realpath(path):
+ # If the specified path contains symlinks, it won't appear
+ # verbatim in mountinfo.
+ #
+ # It might seem like we should have called realpath() from
+ # the outset. But we can't: realpath() hangs (in lstat())
+ # if we call it on an unresponsive mount point, and this
+ # is an important and common scenario.
+ #
+ # By waiting until now to try realpath(), we avoid this
+ # problem in the most common cases, which are: (1) the
+ # specified path has no symlinks and is a mount point, in
+ # which case was_mounted==True and we can proceed without
+ # calling realpath(); and (2) the specified path is not a
+ # mount point (e.g., it was already unmounted by someone
+ # else, or it's a typo), and realpath() can determine that
+ # without hitting any other unresponsive mounts.
+ path = os.path.realpath(path)
+ continue
+ elif not mounted:
+ if was_mounted:
+ # This appears to avoid a race condition where we
+ # return control to the caller after running
+ # "fusermount -u -z" (see below), the caller (e.g.,
+ # arv-mount --replace) immediately tries to attach a
+ # new fuse mount at the same mount point, the
+ # lazy-unmount process unmounts that _new_ mount while
+ # it is being initialized, and the setup code waits
+ # forever for the new mount to be initialized.
+ time.sleep(1)