Skip to content
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

mountinfo: add MountedFast #100

Merged
merged 7 commits into from Feb 3, 2022
Merged

mountinfo: add MountedFast #100

merged 7 commits into from Feb 3, 2022

Conversation

kolyshkin
Copy link
Collaborator

This is a carry of #97 -- mostly the same code, arranged slightly differently. I have also cleaned up tests a bit.

@manugupt1 PTAL

Instead of copy/pasting the code to check individual mountedBy*
implementations, add a list and a loop to check them.

The only special thing is, we have to check if the name of the function
being tested is "mountedByStat", to skip erroring out on bind mounts.
Otherwise the code is the same.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Comment on lines 92 to 97
if sure {
return mounted, err
}
Copy link
Contributor

@manugupt1 manugupt1 Jan 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I slightly prefer having this check as (even when we have tests) as an extra check.

if sure && err == nil 

Can this change be made?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

Also, I just realized that if normalizePath returns an error, it does not make sense to continue with parsing mountinfo, so this code needs to be changed anyway.

Will fix.

@manugupt1
Copy link
Contributor

One nit and this looks awesome! thanks!

@kolyshkin
Copy link
Collaborator Author

Should we maybe rename this to FastMounted()? @thaJeztah WDYT?

@manugupt1
Copy link
Contributor

Should we maybe rename this to FastMounted()? @thaJeztah WDYT?

I like MountedFast better because it reads as MountedByFastMethods to me; just like MountedByOpenAt2 and MountedByStat in the rest of the code base.

@kolyshkin kolyshkin force-pushed the mounted-fast branch 2 times, most recently from bd6e12a to 7cca805 Compare January 17, 2022 21:02
@kolyshkin
Copy link
Collaborator Author

@thaJeztah @cpuguy83 PTAL

@thaJeztah
Copy link
Member

Should we maybe rename this to FastMounted()? @thaJeztah WDYT?

I like MountedFast better because it reads as MountedByFastMethods to me; just like MountedByOpenAt2 and MountedByStat in the rest of the code base.

I agree; let's stick with MountedXXX

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left some comments/suggestions

mountinfo/mounted_linux.go Outdated Show resolved Hide resolved
mountinfo/mounted_linux.go Show resolved Hide resolved
}
} else {
if openat2Supported {
if mounted != exp {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is becoming quite complex; could we remove the local exp variable, and instead use tc.isMount ? (I had to scroll up to learn what exp was)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines 319 to 320
// Check the public MountedFast() function as a whole.
mounted, sure, err := MountedFast(m)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also see my other comment about this test becoming quite complex; wondering if we should just move this to a separate (TestMountedFast) test. There will be some boilerplating / code duplication, but perhaps it's a good trade-off compared to the complexity we're ending up into now. i.e. using subtests normally avoids having to include the function name in the t.Errorf, but because we're now combining so many we have to do it again.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about it, too, but decided against it, since test setup/cleanup is complex and I'd rather not duplicate it.

We can move mountedFast checks into a function maybe; let me see.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this looks better. Updated.

mountinfo/mounted_linux_test.go Outdated Show resolved Hide resolved
@kolyshkin
Copy link
Collaborator Author

@manugupt1 @thaJeztah PTAL 🙏🏻

mountinfo/mounted_linux.go Outdated Show resolved Hide resolved
@thaJeztah
Copy link
Member

looks good to me after @manugupt1's suggestion above has been looked at

kolyshkin and others added 6 commits February 2, 2022 20:28
Fixes: dbd468b
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
MountedFast is a method of detecting a mount point without reading
mountinfo from procfs. A caller can only trust the result if no error
and sure == true are returned. Otherwise, other methods (e.g. parsing
/proc/mounts) have to be used. If unsure, use Mounted instead (which
uses MountedFast, but falls back to parsing mountinfo if needed).

If a non-existent path is specified, an appropriate error (rather than
"not mounted") is returned. In case the caller is not interested in this
particular error, it should be handled separately using e.g.
errors.Is(err, os.ErrNotExist).

This function is only available on Linux. The implementation mostly
relies on openat2(2) syscall, available since Linux kernel v5.6.
On older kernels, this uses stat(2) syscall which can reliably
detect normal (but not bind) mounts.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1. Do not compare booleans to false and true.

2. Since there are only two values, no sense in printing the actual value.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
For clarity.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Test both MountedFast and Mounted.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
@kolyshkin
Copy link
Collaborator Author

@thaJeztah @moby/moby-maintainers PTAL

@kolyshkin
Copy link
Collaborator Author

One thing I failed to document is shadowed mounts.

For example, if /mnt/one is a mount point, but later sysadmin does mount /dev/sda /mnt, the /mnt/one path becomes shadowed by the new mount. The shadowed mount is still visible from mountinfo, but it is impossible to access it (for example, to unmount).

MounedFast returns ENOENT for such shadowed mounts, since the path is inaccessible. Mounted used to return "true" for such mounts, but since commit dbd468b it also returns ENOENT.

I am failing to describe all this in a nice yet compact way.

In any case, this can be done later.

Copy link
Contributor

@manugupt1 manugupt1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for doing this in such a nice way and helping me. I learnt a lot from you.

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

we can further improve documentation in follow ups if we see a need 👍

@thaJeztah thaJeztah merged commit d01e595 into moby:main Feb 3, 2022
@manugupt1
Copy link
Contributor

manugupt1 commented Feb 3, 2022

@kolyshkin @thaJeztah
Would you be able to cut a release for Mountinfo for with this change?

Thanks

@thaJeztah
Copy link
Member

Yes, I wanted to prose doing so.

Needed to check again in which order things had to be released (as the mountinfo and mount packages have a dependency on each other)

@kolyshkin
Copy link
Collaborator Author

@kolyshkin
Copy link
Collaborator Author

(as the mountinfo and mount packages have a dependency on each other)

Only mount depends on mountinfo, but not vice versa.

AFAIK we don't need to do anything; updating the mount's go.mod to require mountinfo/v.0.6.0 is highly optional (but makes sense to do before its next release, of course).

@thaJeztah
Copy link
Member

Yes, it's good to update them, so that projects that use them are using the same version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants