Autodetect systemd version in containers started by systemd-nspawn#4310
Autodetect systemd version in containers started by systemd-nspawn#4310evverx merged 6 commits intosystemd:masterfrom
Conversation
poettering
left a comment
There was a problem hiding this comment.
Looks pretty good, the only real issue I see is the missing check for lib64/ in addition to lib/...
(Thinking about this, we probably should also check /usr/lib and /usr/lib64, since Gentoo has a really strange usrmerge approach, where they manually move everything into /usr/lib without making /lib a symlink...)
src/basic/path-util.c
Outdated
| * is non-standard. False positives should be relatively rare. | ||
| */ | ||
|
|
||
| path = prefix_root(root, "lib/systemd/libsystemd-shared-*.so"); |
There was a problem hiding this comment.
I thought we always install systemd in /usr/lib, and libsystemd-shared also ends up in the non-arch-specific path. This is true for Fedora, Debian, Ubuntu. I don't see a Mageia systemd 231 package, but in 230, they are also using /usr/lib/systemd/. Is anyone using /usr/lib64/systemd/?
There was a problem hiding this comment.
arch also has [/usr]/lib/systmed/libsystemd-shared-231.so on amd64.
There was a problem hiding this comment.
Yeah, i think Gentoo again is doing things differently. Generally, lib64 is understood as the place to put libraries for 64bit if both 32bit and 64bit are to be supported. Except on Gentoo, where lib64 is understood as the place to place 64bit libraries, full stop.
Gentoo's scheme is borked, but if you want to cover that, you'd also have to check for lib64. Now I personally don't care about Gentoo I must say, so the patch is actually fine, but heh...
There was a problem hiding this comment.
I'll let somebody who is an actual Gentoo user submit a patch if necessary. I wouldn't even know how to test this patch against Gentoo. To anyone reading this: the table is at https://github.com/systemd/systemd/blob/master/src/basic/path-util.c#L834.
There was a problem hiding this comment.
./test-path-util /path/to/container...
There was a problem hiding this comment.
Gentoo installs libsystemd-shared in /usr/lib/systemd.
Due to a poor decision several years ago, /usr/lib is often a symlink to /usr/lib64 on Gentoo, but that should not matter in this context.
src/basic/path-util.c
Outdated
| if (r < 0) | ||
| return r; | ||
|
|
||
| endswith(path, "*.so")[0] = '\0'; /* truncate the glob part */ |
There was a problem hiding this comment.
i'd probably do that in two steps and add an assert here, just in case:
assert_se(c = endswith(path, "*.so"));
*c = 0;| unsigned i; | ||
|
|
||
| for (i = 0; i < ELEMENTSOF(versions); i++) { | ||
| r = systemd_installation_has_version(path, versions[i]); |
There was a problem hiding this comment.
hmm, given that s_i_h_v() returns a bool, I'd probably not reuse "r" here, but instead write:
for (…) {
bool b;
b = s_i_h_v(…);
…
}i.e.avoid the implicit bool → int case...
There was a problem hiding this comment.
It returns an int (one of 0, 1, -ENOMEM).
But what about patched BTW: the version detection mechanism doesn't work. For example, the control group namespaces were introduced in |
If you revert patches in released systemd, then you are on your own, and get to keep both pieces. If you backport the support, then you either have to use the env. var to override the check, or also patch the systemd on the host. I wouldn't worry about those cases too much, because the only problematic case would be a false positive, where we think systemd in the container has support, but for some reason it does not. But I think this could only happen if you do some rogue patching. |
…version This is a bit crude and only works for new systemd versions which have libsystemd-shared.
If we are going to use the env var to override the detection result anyway, there is not point in doing the detection, especially that it can fail.
The new function has 416 lines by itself! "return log_error_errno" is used to nicely reduce the volume of error handling code. A few minor issues are fixed on the way: - positive value was used as error value (EIO), causing systemd-nspawn to return success, even though it shouldn't. - In two places random values were used as error status, when the actual value was in an unusual place (etc_password_lock, notify_socket). Those are the only functional changes. There is another potential issue, which is marked with a comment, and left unresolved: the container can also return 133 by itself, causing a spurious reboot.
systemd-soon-to-be-released-232 is able to deal with the mixed hierarchy. So make an educated guess, and use the mixed hierarchy in that case. Tested by running the host with mixed hierarchy (i.e. simply using a recent kernel with systemd from git), and booting first a container with older systemd, and then one with a newer systemd. Fixes systemd#4008.
Well, I can patch both pieces of the
Well, this makes sense. But why not to mount the legacy hierarchy by default? This works always. (Yes, this breaks
But who cares? Well, I care. But I can live without it) |
If you have an old host system (B-distro if I understand correctly), then you get nothing. But that's expected. This patch is only about new B and old A. |
6c8f800 to
0fd9563
Compare
|
Pushed with the requested style fixes. I didn't add /lib64/ paths because I don't see any distro that would actually use them. But not it'd just be a question of adding lines to a nulstr, so it's a trivial patch that can be added on top if it turns out to be desired. |
Sorry, I mean
This combination doesn't work. Anyway, why not to mount the legacy hierarchy by default? |
| *c = '\0'; /* truncate the glob part */ | ||
|
|
||
| STRV_FOREACH(name, names) { | ||
| /* This is most likely to run only once, hence let's not optimize anything. */ |
There was a problem hiding this comment.
This loop means that if I have libsystemd-shared-232.so and libsystemd-shared-231.so, then this function will return true. I'd argue that this should be more conservative and either return true only when there is only one name, or all names satisfy the needed version.
There was a problem hiding this comment.
Well, if you just run make install over an existing directory, you can easily end up with multiple versions of the lib, so we should support that. OTOH, if you install a newer systemd and than an older one over that, I don't think we can have to support that.
There was a problem hiding this comment.
I agree with @keszybz. I think it's OK to assume that if people install multiple versions of the .so, they installed them in the same order as the versions indicate, and thus we can only look at the newest release.
I mean, upgrades are generally the norm, downgrades are the exception.
Seriously, what would the point of that be? If you don't like the mixed hierarchy, just force legacy hierarchy on the host. |
@keszybz , sure, I can force everything I want :-) We are talking about defaults. And I think the legacy hierarchy is the good default (it works always) I'm not against this PR. I just don't understand why do we choose this approach. |
|
Another problem: |
|
Full unified hierarchy requires an explicit command line switch, but the mixed one is started implicitly if the kernel supports it. I don't think we can do anything to make old systemd run in the full unified hierarchy, but at least it requires an explicit choice.
Because v2 is better than mixed, and mixed is better than v1 (more efficient, and the notifications work better). So we want to use v2 as much as possible, or at least mixed as long as we cannot make v2 the default. |
It doesn't require an explicit command line switch
am I missing something?
OK. So, why do we mount the
|
I mean And I don't understand why do we check the container's version on the mixed hierarchy and don't check version on the unified hierarchy. |
Current systemd version detection routine cannot detect systemd 230, only systmed >= 231. This means that we'll still use the legacy hierarchy in some cases where we wouldn't have too. If somebody figures out a nice way to detect systemd 230 this can be later improved.
|
Hm, it's more complicated than the list in #4310 (comment). Indeed, systemd-229 breaks when booted with full unified, but systemd-208 does not! I have a Fedora20 container here, and it's perfectly happy to boot with both tmpfs and cgroup2 mount on /sys/fs/cgroup. Nevertheless, I like your idea of mounting legacy hierarchy for systemd <= 229. I'll push a patch which purports to do that shortly. |
Oh, I didn't know. Thanks!
:-) @keszybz , thanks! |
|
Yeah, I had a similar idea too, but @poettering wasn't impressed ;) Let's leave that discussion for another PR. |
|
|
||
| static void test_systemd_installation_has_version(const char *path) { | ||
| int r; | ||
| const unsigned versions[] = {0, 231, atoi(PACKAGE_VERSION), 999}; |
There was a problem hiding this comment.
atoi(PACKAGE_VERSION)? yuck!
|
lgtm. Of course, I'd always prefer if we could somehow check for features rather than for version numbers (so that we can support backported patches), but I am not sure this is possible in this case. But maybe we can add some infrastructure for this for the future. Some scheme how the system in the container can declare the feature set it supports, or so.... |
|
so, should we merge this? @evverx anything else you wanted to test about this? |
|
@poettering , sorry for the delay. I'm testing now. I didn't see any regressions. But I should check |
|
@poettering |
|
Works fine. @keszybz , thanks! |
|
Thanks for testing! I think we're moving in the right direction, albeit step by step. |
No description provided.