On Mi, 15.04.20 09:01, Daniel J Walsh (dwalsh(a)redhat.com) wrote:
> I didn't consider cases where systemd is not running because
Fedora
> hasn't supported booting without systemd in about a decade. But I
> guess the problem here is for containers where systemd is not running
> inside the container, but is running on the host system? I hadn't
> considered this scenario. What do Ubuntu containers do? I guess those
> are not all broken. :)
>
> _______________________________________________
> devel mailing list -- devel(a)lists.fedoraproject.org
> To unsubscribe send an email to devel-leave(a)lists.fedoraproject.org
> Fedora Code of Conduct:
>
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
> List Guidelines:
https://fedoraproject.org/wiki/Mailing_list_guidelines
> List Archives:
>
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org
We can change container engines (podman, Buildah, CRI-O) to handle this
but they need to have a location of a properly configured resolv.conf
file, somewhere on the system to be used without systemd.
My suggestion for those container managers: if /etc/resolv.conf is a
regular file, always use that as copy source. If it is a symlinkt to
/run/systemd/resolve/stub-resolv.conf or
/run/systemd/resolve/resolv.conf then use
/run/systemd/resolve/resolv.conf as copy source.
Yes, I mean that, even if /run/systemd/resolve/stub-resolv.conf is the
symlink destination use the file without "stub-" in the name as copy
source. Because that file always contains the literal upstream DNS
servers, and does not redirect DNS traffic to 127.0.0.53 like the file
with "-stub" in the name does. Since containers are typically run
inside their own network namespace it's wise to use the upstream DNS
servers directly, instead of trying to the DNS forwarder called
resolved on localhost that is likely not going to be there in a netns
container.
The algorithm above in C-ish pseudo-code:
for (;;) {
fd = open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC|O_NOFOLLOW);
if (fd >= 0)
break; /* success! it's a regular file */
if (errno != ELOOP)
break; /* failure! something unexpected */
/* It's a symlink */
r = readlink("/etc/resolv.conf", &dest);
if (r < 0) {
if (errno == EINVAL)
continue; /* Oh, it's not a symlink anymore?
somebody must just have replace
the file, let's try again */
/* failure! some unexpected error */
break;
}
/* Check where the symlink points. Check by absolute and by
relative paths, just in case. If this points to any of the
three files provided by systemd-resolved, use the one that
encodes upstream DNS info */
if (strcmp(dest, "/run/systemd/resolve/stub-resolv.conf") == 0 ||
strcmp(dest, "../run/systemd/resolve/stub-resolv.conf") == 0 ||
strcmp(dest, "/run/systemd/resolve/resolv.conf") == 0 ||
strcmp(dest, "../run/systemd/resolve/resolv.conf") == 0 ||
strcmp(dest, "/usr/lib/systemd/resolv.conf") == 0 ||
strcmp(dest, "../usr/lib/systemd/resolv.conf") == 0)) {
fd = open("/run/systemd/resolve/resolv.conf", O_RDONLY|O_CLOEXEC);
else
fd = open("/run/systemd/resolve/resolv.conf", O_RDONLY|O_CLOEXEC);
break;
}
You get the idea: use O_LOOP to check if it's a symlink and then use
readlink() to see if the file points to something managed by resolved.
Lennart
--
Lennart Poettering, Berlin