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

Faster Chown #557

Merged
merged 4 commits into from Mar 11, 2020
Merged

Faster Chown #557

merged 4 commits into from Mar 11, 2020

Conversation

kolyshkin
Copy link
Contributor

This makes use of pwalk.Walk() (introduced in opencontainers/selinux#89)
for recursive Chown, and also optimizes drivers/platformLChown() a bit, following the discussion at 2df72f3#r387867583

TODO:

  • benchmarks

@rhatdan @giuseppe PTAL

@kolyshkin
Copy link
Contributor Author

Forgot to git add new files, just a sec

This is mostly to get pkg/pwalk in.

See https://github.com/opencontainers/selinux/releases/tag/v1.4.0
for release notes

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This is a parallel Walk implementation and we're expecting some
speedup thanks to that.

Note that pwalk.Walk error handling is primitive; for one thing,
it never sends an error to the callpack, thus the error checking
code is no longer needed.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This is purely aesthetical -- in case we can't get struct stat_t,
return early. This improves readability and decreases the indentation.

No functional change. Please review this with --ignore-space-change.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This function is already called with the result from os.Lstat(),
so there's no need to do it again.

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

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

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

Copy link
Member

@giuseppe giuseppe left a comment

Choose a reason for hiding this comment

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

LGTM

@TomSweeneyRedHat
Copy link
Member

LGTM

@kolyshkin
Copy link
Contributor Author

Can anyone suggest a good benchmark setup so we can compare before and after?

@rhatdan rhatdan merged commit 9e26667 into containers:master Mar 11, 2020
@rhatdan
Copy link
Member

rhatdan commented Mar 11, 2020

Kolshkin, the use case is we are trying to accelerate is the time it takes to chown a container image.
I think creating a mounted image with different UserNamespace settings would be the classic case.

Create an image with a lot of files/directories in it, then create a container with a different user namespace and mount it. If you create this with a thread of 1 versus several, you would think the mount/chown would happen faster in the second version.

If we are dealing with overlay and metacopy=on, then it should be very fast, since files would not be being copied up.

@rhvgoyal
Copy link
Contributor

Curious to see how much improvement does it bring. Say run fedora image in a user namespace with and without these patches and how much is the improvement.

@kolyshkin
Copy link
Contributor Author

@rhvgoyal I'll run some benchmarks once time permits; for now you can take a look at opencontainers/selinux#85 and containers/common#82. I expect at least 1.5x improvement in speed for Chown(), maybe better since I also removed an extra lstat(2) call.

@giuseppe
Copy link
Member

A simple test would be something like the following:

# for i in {200..210}; do \time bin/podman run --uidmap 0:$i:2000 --rm fedora true; done

make sure you run it as root.

without the patch:

0.58user 0.85system 0:05.17elapsed 27%CPU (0avgtext+0avgdata 44924maxresident)k
544inputs+1240outputs (0major+24358minor)pagefaults 0swaps
0.68user 1.16system 0:09.60elapsed 19%CPU (0avgtext+0avgdata 47608maxresident)k
48inputs+1240outputs (0major+24972minor)pagefaults 0swaps
0.83user 1.49system 0:08.90elapsed 26%CPU (0avgtext+0avgdata 48252maxresident)k
8inputs+1240outputs (0major+25100minor)pagefaults 0swaps
0.95user 1.68system 0:09.80elapsed 26%CPU (0avgtext+0avgdata 46812maxresident)k
3976inputs+1256outputs (0major+24755minor)pagefaults 0swaps
1.21user 1.90system 0:11.44elapsed 27%CPU (0avgtext+0avgdata 48116maxresident)k
16inputs+1272outputs (0major+25190minor)pagefaults 0swaps
1.32user 2.08system 0:10.72elapsed 31%CPU (0avgtext+0avgdata 48716maxresident)k
40inputs+1272outputs (0major+25130minor)pagefaults 0swaps
1.58user 2.50system 0:11.78elapsed 34%CPU (0avgtext+0avgdata 48628maxresident)k
5040inputs+1272outputs (0major+25265minor)pagefaults 0swaps
1.58user 2.65system 0:12.69elapsed 33%CPU (0avgtext+0avgdata 46712maxresident)k
64inputs+1272outputs (0major+24692minor)pagefaults 0swaps
1.59user 2.85system 0:12.53elapsed 35%CPU (0avgtext+0avgdata 48256maxresident)k
64inputs+1272outputs (0major+25154minor)pagefaults 0swaps
1.92user 3.20system 0:11.43elapsed 44%CPU (0avgtext+0avgdata 48824maxresident)k
0inputs+1272outputs (0major+25327minor)pagefaults 0swaps
2.14user 3.45system 0:13.11elapsed 42%CPU (0avgtext+0avgdata 48596maxresident)k
72inputs+1272outputs (0major+25194minor)pagefaults 0swaps

and the patch:

0.39user 1.11system 0:07.80elapsed 19%CPU (0avgtext+0avgdata 38916maxresident)k
0inputs+880outputs (0major+22776minor)pagefaults 0swaps
0.51user 1.36system 0:05.72elapsed 32%CPU (0avgtext+0avgdata 45380maxresident)k
0inputs+880outputs (0major+24395minor)pagefaults 0swaps
0.68user 1.73system 0:06.13elapsed 39%CPU (0avgtext+0avgdata 45224maxresident)k
0inputs+888outputs (0major+24390minor)pagefaults 0swaps
0.85user 1.85system 0:08.31elapsed 32%CPU (0avgtext+0avgdata 45496maxresident)k
0inputs+880outputs (0major+24557minor)pagefaults 0swaps
1.04user 2.18system 0:06.11elapsed 52%CPU (0avgtext+0avgdata 47532maxresident)k
0inputs+880outputs (0major+25072minor)pagefaults 0swaps
1.11user 2.46system 0:08.23elapsed 43%CPU (0avgtext+0avgdata 47740maxresident)k
0inputs+888outputs (0major+25135minor)pagefaults 0swaps
1.37user 2.68system 0:09.21elapsed 43%CPU (0avgtext+0avgdata 47508maxresident)k
0inputs+888outputs (0major+25134minor)pagefaults 0swaps
1.52user 2.97system 0:10.61elapsed 42%CPU (0avgtext+0avgdata 46644maxresident)k
0inputs+880outputs (0major+24865minor)pagefaults 0swaps
1.60user 3.15system 0:09.39elapsed 50%CPU (0avgtext+0avgdata 47564maxresident)k
0inputs+880outputs (0major+25143minor)pagefaults 0swaps
1.79user 3.40system 0:09.77elapsed 53%CPU (0avgtext+0avgdata 47732maxresident)k
0inputs+888outputs (0major+25231minor)pagefaults 0swaps
2.77user 3.64system 0:11.76elapsed 54%CPU (0avgtext+0avgdata 87928maxresident)k
295728inputs+512outputs (894major+26706minor)pagefaults 0swaps

I'll investigate what is going on here, but it seems the time keeps increasing (not related to this patch).

@giuseppe
Copy link
Member

turned out to be an issue in Podman.

I've opened a PR to address it: containers/podman#5469

I've repeated the tests on top of the libpod fix.

without the patch:

0.16user 0.40system 0:06.74elapsed 8%CPU (0avgtext+0avgdata 37888maxresident)k
0inputs+904outputs (0major+22630minor)pagefaults 0swaps
1.05user 0.47system 0:06.56elapsed 23%CPU (0avgtext+0avgdata 79268maxresident)k
0inputs+528outputs (0major+24009minor)pagefaults 0swaps
1.10user 0.48system 0:07.35elapsed 21%CPU (0avgtext+0avgdata 78872maxresident)k
0inputs+528outputs (0major+23869minor)pagefaults 0swaps
0.17user 0.47system 0:04.45elapsed 18%CPU (0avgtext+0avgdata 38900maxresident)k
0inputs+904outputs (0major+22899minor)pagefaults 0swaps
0.16user 0.38system 0:05.76elapsed 9%CPU (0avgtext+0avgdata 37876maxresident)k
0inputs+608outputs (0major+15627minor)pagefaults 0swaps
1.03user 0.45system 0:06.39elapsed 23%CPU (0avgtext+0avgdata 79280maxresident)k
0inputs+528outputs (0major+23978minor)pagefaults 0swaps
0.16user 0.44system 0:04.41elapsed 13%CPU (0avgtext+0avgdata 37996maxresident)k
0inputs+904outputs (0major+22622minor)pagefaults 0swaps
0.18user 0.42system 0:04.75elapsed 12%CPU (0avgtext+0avgdata 38368maxresident)k
8inputs+904outputs (0major+22713minor)pagefaults 0swaps
0.14user 0.44system 0:06.58elapsed 9%CPU (0avgtext+0avgdata 38424maxresident)k
0inputs+904outputs (0major+22693minor)pagefaults 0swaps
1.02user 0.45system 0:05.32elapsed 27%CPU (0avgtext+0avgdata 80056maxresident)k
0inputs+528outputs (0major+24588minor)pagefaults 0swaps
0.17user 0.40system 0:04.23elapsed 13%CPU (0avgtext+0avgdata 38272maxresident)k
8inputs+904outputs (0major+22817minor)pagefaults 0swaps

and the patch:

0.19user 1.00system 0:04.59elapsed 26%CPU (0avgtext+0avgdata 39184maxresident)k
0inputs+888outputs (0major+22813minor)pagefaults 0swaps
1.12user 0.99system 0:05.10elapsed 41%CPU (0avgtext+0avgdata 80720maxresident)k
0inputs+512outputs (0major+25194minor)pagefaults 0swaps
0.21user 0.93system 0:04.39elapsed 26%CPU (0avgtext+0avgdata 38952maxresident)k
0inputs+888outputs (0major+22804minor)pagefaults 0swaps
1.08user 0.98system 0:05.03elapsed 41%CPU (0avgtext+0avgdata 80812maxresident)k
0inputs+512outputs (0major+25008minor)pagefaults 0swaps
0.23user 0.94system 0:03.94elapsed 29%CPU (0avgtext+0avgdata 39244maxresident)k
0inputs+880outputs (0major+22822minor)pagefaults 0swaps
1.04user 1.00system 0:06.94elapsed 29%CPU (0avgtext+0avgdata 79904maxresident)k
0inputs+512outputs (0major+24503minor)pagefaults 0swaps
1.07user 1.00system 0:05.32elapsed 38%CPU (0avgtext+0avgdata 80288maxresident)k
0inputs+512outputs (0major+24942minor)pagefaults 0swaps
0.23user 0.91system 0:03.00elapsed 37%CPU (0avgtext+0avgdata 38628maxresident)k
0inputs+888outputs (0major+23059minor)pagefaults 0swaps
0.24user 0.91system 0:04.17elapsed 27%CPU (0avgtext+0avgdata 39176maxresident)k
0inputs+880outputs (0major+22992minor)pagefaults 0swaps
0.22user 0.98system 0:05.23elapsed 23%CPU (0avgtext+0avgdata 38996maxresident)k
0inputs+880outputs (0major+22792minor)pagefaults 0swaps
0.20user 0.96system 0:05.45elapsed 21%CPU (0avgtext+0avgdata 39232maxresident)k
0inputs+888outputs (0major+22880minor)pagefaults 0swaps

@rhatdan
Copy link
Member

rhatdan commented Mar 12, 2020

You should really be clearing the file system cache between each run, to remove any optimizations by the kernel.

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

6 participants