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

etc/systemd/zfs-mount-generator: serialise, handle keylocation=http[s]:// #12138

Merged
merged 2 commits into from
Nov 30, 2021

Conversation

nabijaczleweli
Copy link
Contributor

@nabijaczleweli nabijaczleweli commented May 27, 2021

Description

The first patch serialises the generator, see message for measurements. No output changes.

The second patch adds keylocation=http[s]:// by pulling in network-online.target but otherwise loading normally.

The third patch I would like The Reviewer's opinion on: it's slightly shorter and matches what's logically happening slightly better, but it could also go wrong easier in future if we have to allocate in that block or some code moves around and makes tofree no longer append-only (which is a good quality to have). I've looked at it too much to have a meaningful opinion.

How Has This Been Tested?

The first patch produces identical output on my test set. If FREE_STATICS is true, it's valgrind-clean (save for libshare, but what can you do).

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Library ABI change (libzfs, libzfs_core, libnvpair, libuutil and libzfsbootenv)
  • Documentation (a change to man pages or other documentation)

Checklist:

  • My code follows the OpenZFS code style requirements.
  • I have updated the documentation accordingly.
  • I have read the contributing document.
  • I have added tests to cover my changes. – none apply
  • I have run the ZFS Test Suite with this change applied. – CI take my hand
  • All commit messages are properly formatted and contain Signed-off-by.

@tonynguien tonynguien added the Status: Code Review Needed Ready for review and testing label Jun 5, 2021
@tonynguien tonynguien requested a review from rlaager June 8, 2021 21:16
@tonynguien
Copy link
Contributor

@aerusso @InsanePrawn, would you be able to review these changes?

Copy link
Member

@rlaager rlaager left a comment

Choose a reason for hiding this comment

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

This seems fine to me.

Even though I was the one that asked about it, I'm quite surprised that serializing the generator is faster. I guess the fork() overhead is high. That's why it's important to profile, I guess. :)

I could go either way on the third commit. On the one hand, it feels a little weird to remove something from the list of things to free. But on the other hand, that seems to be happening because ownership is transferred.

Copy link
Contributor

@aerusso aerusso left a comment

Choose a reason for hiding this comment

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

Nice speedup! I especially like the reduction in nloc.

This is starting to become nontrivial enough that we should probably add tests for the generator. I don't think that's really a requirement for this MR, though.

@nabijaczleweli nabijaczleweli force-pushed the zomg-eleven branch 2 times, most recently from c4db117 to 59ffaae Compare June 9, 2021 10:24
@nabijaczleweli
Copy link
Contributor Author

nabijaczleweli commented Jun 9, 2021

@rlaager I did profile the first version before posting it, and it spent 70% of its time in fork() (on relatively idle Westmere with a lot of free RAM, this (likely, I haven't measured it directly this time, but it falls out of some other tests) skyrockets on my work laptop test environment (laptop CPU (8th-gen, but still; it's not running cold or fast), single-channel RAM, QEMU on HAX on Windows, horribly slow virtual memory)), and 5%ish in str(c?)spn() (i.e. strtok()), but to me the simplified state and lifetime management still vastly outweighed the potential benefits of throwing away the version I tested extensively and which was already ~20x faster.
It also doesn't really show up for Normal amounts of datasets, because it's already quite short, but I run ZFS-backed Docker/k8s on that VM, which is 900+ datasets on a good day, so I don't realistically expect this speedup to affect too many set-ups.

As for the escape handling, seeing as you haven't a strong opinion, I've consulted some friends (this was a mistake, never ask programmers about anything), and the consensus there seems to be that *(tofree++) = (void *)mountfile;+*(--tofree) = NULL; has less potential to go bad, and if it does, it will do so much harder and more obviously, which is preferable, so I've squashed it into the first commit (previous HEAD at zomg-eleven-v1, should it be needed).

@aerusso I can dump my test dataset into ZTS in a later PR if you want, but it's difficult to test this other than with diff -r to pre-generated output (since the correct testing procedure would be to inject the units into a VM image, boot it, and observe how it behaves from within and without; this is doable, but in a definite "nah bro" state from me for the foreseeable future), which is the absolute worst kind of test, especially in perpetua and across multiple tens of files, since any changes to the output format just work out to regenerating the data, which, y'know.

@InsanePrawn
Copy link
Contributor

InsanePrawn commented Jun 9, 2021

I can dump my test dataset into ZTS in a later PR if you want, but it's difficult to test this other than with diff -r to pre-generated output [...] which is the absolute worst kind of test, especially in perpetua and across multiple tens of files, since any changes to the output format just work out to regenerating the data, which, y'know.

historically (at least during my involvement), only columns were added, and the added properties were optional/user props -> default to -; so if you handle a missing column == -, a certain downwards compatibility is achieved.
Having some sanity tests that generate units from a basic list.cache file and verify that certain entries in the unit are set correctly does seem feasible and defo better than nothing to me?
If we wanted to, we could even test for this downwards compatibility.
[To be clear: i'm not saying support and test arbitrary amounts of missing columns, I'm thinking about testing known older versions of the cache file (or more precisely, the set of columns it had) that we expect to be compatible, e.g. 0.8, 2.0, etc.; if we ever decide to break compat, the tests should reflect this.]

Testing the cache-list generator itself is another open point afaik.

The wins for a relatively normal workload are rather slim:
	real	0.02119s/0.00985s=2.15029x
	user	0.02130s/0.00346s=6.15560x
	sys	0.03858s/0.00643s=6.00062x

	wall-total	0.014518s/0.005925s=2.45009x
	wall-init	0.014518s/0.002457s=5.90684x
	wall-real	0.014518s/0.003467s=4.18668x

But this is a big win on machines with a lot of datasets and expensive
forks.

For example, the gain on a VM on my work laptop with 900+ legacy-mount
Docker datasets, the original gains from the C rewrite were
only five-fold:
	real    0.516s/0.102s=5.05882x
	user    0.237s/0.143s=1.65734x
	sys     0.287s/0.100s=2.87x

And this serial variant gains this back there as well:
	real    0.102s/0.008s=12.75x
	user    0.143s/0.007s=20.42857
	sys     0.100s/0.001s=100x

	wall-total	0.09717s/0.00319s=30.40255x
	wall-init	0.00203s/0.00200s=1.015941x
	wall-real	0.09513s/0.00118s=80.02043x

For a total of
	real    0.516s/0.008s=64.5x
	user    0.237s/0.007s=33.85714x
	sys     0.287s/0.001s=287x

Suggested-by: Richard Laager <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
@nabijaczleweli
Copy link
Contributor Author

Rebased. AFAICT the review only points toward further expansion because both want* strings are effectively constant and there's a need_ flag for the network, so I don't think there's a blocker for this, and not allowing http[s]:// in the generator by default is kinda stinky and bit me a few weeks ago

Copy link
Member

@rlaager rlaager left a comment

Choose a reason for hiding this comment

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

I think @aerusso makes a good point. I left a comment with an alternate suggestion that I think makes this slightly simpler.

@nabijaczleweli nabijaczleweli force-pushed the zomg-eleven branch 2 times, most recently from 1060996 to 93b5eb9 Compare November 12, 2021 12:06
@nabijaczleweli
Copy link
Contributor Author

It did, and I've also applied it to RequiresMountsFor= below, since it's so much simpler

@nabijaczleweli
Copy link
Contributor Author

nabijaczleweli commented Nov 18, 2021

Week bump – CI passes and reviews addressed

@aerusso aerusso mentioned this pull request Nov 20, 2021
12 tasks
Copy link
Member

@rlaager rlaager left a comment

Choose a reason for hiding this comment

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

From my perspective, this is good to go. I did actually compile and run it. I get sane results on my system.

Copy link
Contributor

@tonynguien tonynguien left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@tonynguien
Copy link
Contributor

@nabijaczleweli We are ready to merge. Would you mind squashing the commits?

Also simplify RequiresMountsFor= handling

Ref: openzfs#11956
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
@nabijaczleweli
Copy link
Contributor Author

Done.

@tonynguien tonynguien added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Nov 30, 2021
@tonynguien tonynguien merged commit 4325de0 into openzfs:master Nov 30, 2021
nabijaczleweli added a commit to nabijaczleweli/zfs that referenced this pull request Mar 29, 2022
…]://

* etc/systemd/zfs-mount-generator: serialise

The wins for a relatively normal workload are rather slim:
	real	0.02119s/0.00985s=2.15029x
	user	0.02130s/0.00346s=6.15560x
	sys	0.03858s/0.00643s=6.00062x

	wall-total	0.014518s/0.005925s=2.45009x
	wall-init	0.014518s/0.002457s=5.90684x
	wall-real	0.014518s/0.003467s=4.18668x

But this is a big win on machines with a lot of datasets and expensive
forks.

For example, the gain on a VM on my work laptop with 900+ legacy-mount
Docker datasets, the original gains from the C rewrite were
only five-fold:
	real    0.516s/0.102s=5.05882x
	user    0.237s/0.143s=1.65734x
	sys     0.287s/0.100s=2.87x

And this serial variant gains this back there as well:
	real    0.102s/0.008s=12.75x
	user    0.143s/0.007s=20.42857
	sys     0.100s/0.001s=100x

	wall-total	0.09717s/0.00319s=30.40255x
	wall-init	0.00203s/0.00200s=1.015941x
	wall-real	0.09513s/0.00118s=80.02043x

For a total of
	real    0.516s/0.008s=64.5x
	user    0.237s/0.007s=33.85714x
	sys     0.287s/0.001s=287x

Suggested-by: Richard Laager <[email protected]>

* etc/systemd/zfs-mount-generator: pull in network for keylocation=https

Also simplify RequiresMountsFor= handling
Ref: openzfs#11956

Reviewed-by: Richard Laager <[email protected]>
Reviewed-by: Tony Nguyen <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Upstream-commit: 4325de0
Closes openzfs#12138
behlendorf pushed a commit that referenced this pull request Apr 1, 2022
…]://

* etc/systemd/zfs-mount-generator: serialise

The wins for a relatively normal workload are rather slim:
	real	0.02119s/0.00985s=2.15029x
	user	0.02130s/0.00346s=6.15560x
	sys	0.03858s/0.00643s=6.00062x

	wall-total	0.014518s/0.005925s=2.45009x
	wall-init	0.014518s/0.002457s=5.90684x
	wall-real	0.014518s/0.003467s=4.18668x

But this is a big win on machines with a lot of datasets and expensive
forks.

For example, the gain on a VM on my work laptop with 900+ legacy-mount
Docker datasets, the original gains from the C rewrite were
only five-fold:
	real    0.516s/0.102s=5.05882x
	user    0.237s/0.143s=1.65734x
	sys     0.287s/0.100s=2.87x

And this serial variant gains this back there as well:
	real    0.102s/0.008s=12.75x
	user    0.143s/0.007s=20.42857
	sys     0.100s/0.001s=100x

	wall-total	0.09717s/0.00319s=30.40255x
	wall-init	0.00203s/0.00200s=1.015941x
	wall-real	0.09513s/0.00118s=80.02043x

For a total of
	real    0.516s/0.008s=64.5x
	user    0.237s/0.007s=33.85714x
	sys     0.287s/0.001s=287x

Suggested-by: Richard Laager <[email protected]>

* etc/systemd/zfs-mount-generator: pull in network for keylocation=https

Also simplify RequiresMountsFor= handling
Ref: #11956

Reviewed-by: Richard Laager <[email protected]>
Reviewed-by: Tony Nguyen <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Upstream-commit: 4325de0
Closes #12138
nicman23 pushed a commit to nicman23/zfs that referenced this pull request Aug 22, 2022
…]://

* etc/systemd/zfs-mount-generator: serialise

The wins for a relatively normal workload are rather slim:
	real	0.02119s/0.00985s=2.15029x
	user	0.02130s/0.00346s=6.15560x
	sys	0.03858s/0.00643s=6.00062x

	wall-total	0.014518s/0.005925s=2.45009x
	wall-init	0.014518s/0.002457s=5.90684x
	wall-real	0.014518s/0.003467s=4.18668x

But this is a big win on machines with a lot of datasets and expensive
forks.

For example, the gain on a VM on my work laptop with 900+ legacy-mount
Docker datasets, the original gains from the C rewrite were
only five-fold:
	real    0.516s/0.102s=5.05882x
	user    0.237s/0.143s=1.65734x
	sys     0.287s/0.100s=2.87x

And this serial variant gains this back there as well:
	real    0.102s/0.008s=12.75x
	user    0.143s/0.007s=20.42857
	sys     0.100s/0.001s=100x

	wall-total	0.09717s/0.00319s=30.40255x
	wall-init	0.00203s/0.00200s=1.015941x
	wall-real	0.09513s/0.00118s=80.02043x

For a total of
	real    0.516s/0.008s=64.5x
	user    0.237s/0.007s=33.85714x
	sys     0.287s/0.001s=287x

Suggested-by: Richard Laager <[email protected]>

* etc/systemd/zfs-mount-generator: pull in network for keylocation=https

Also simplify RequiresMountsFor= handling
Ref: openzfs#11956

Reviewed-by: Richard Laager <[email protected]>
Reviewed-by: Tony Nguyen <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Closes openzfs#12138
nicman23 pushed a commit to nicman23/zfs that referenced this pull request Aug 22, 2022
…]://

* etc/systemd/zfs-mount-generator: serialise

The wins for a relatively normal workload are rather slim:
	real	0.02119s/0.00985s=2.15029x
	user	0.02130s/0.00346s=6.15560x
	sys	0.03858s/0.00643s=6.00062x

	wall-total	0.014518s/0.005925s=2.45009x
	wall-init	0.014518s/0.002457s=5.90684x
	wall-real	0.014518s/0.003467s=4.18668x

But this is a big win on machines with a lot of datasets and expensive
forks.

For example, the gain on a VM on my work laptop with 900+ legacy-mount
Docker datasets, the original gains from the C rewrite were
only five-fold:
	real    0.516s/0.102s=5.05882x
	user    0.237s/0.143s=1.65734x
	sys     0.287s/0.100s=2.87x

And this serial variant gains this back there as well:
	real    0.102s/0.008s=12.75x
	user    0.143s/0.007s=20.42857
	sys     0.100s/0.001s=100x

	wall-total	0.09717s/0.00319s=30.40255x
	wall-init	0.00203s/0.00200s=1.015941x
	wall-real	0.09513s/0.00118s=80.02043x

For a total of
	real    0.516s/0.008s=64.5x
	user    0.237s/0.007s=33.85714x
	sys     0.287s/0.001s=287x

Suggested-by: Richard Laager <[email protected]>

* etc/systemd/zfs-mount-generator: pull in network for keylocation=https

Also simplify RequiresMountsFor= handling
Ref: openzfs#11956

Reviewed-by: Richard Laager <[email protected]>
Reviewed-by: Tony Nguyen <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Closes openzfs#12138
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants