Closed stapelberg closed 4 years ago
This might be almost certainly is due to commit 37a067378ed4f7ae85a07e4a13b615d7e0ca9312, after which our dracut patch is no longer effective.
Also, commit 19f342071283f4d78353bdbac8d6849809927f93 might result in the /init binary in the initrd not being able to locate shared libraries anymore. Perhaps we should build systemd with a full rpath as an exception.
This is confirmed fixed as of git commit 64e935dabc767cc06a15cc14d5002692f78d5227
Running into this again, this time with the Linux 5.4.6 initramfs, which is not bootable when generated on my laptop running distri.
Looks like the issue is that systemd requested /ro/glibc-amd64-2.27-3/out/lib/ld-linux-x86-64.so.2 as interpreter, but dracut only copied glibc-amd64-2.27-1’s ld-linux file.
This is a non-issue when using distri pack as there is only one version of glibc in the environment.
I think we need to patch dracut to explicitly read the interpreter ELF section and copy that file instead of using ldd, which doesn’t print what we want here:
% ldd init | grep ld-linux
/ro/glibc-amd64-2.27-3/out/lib/ld-linux-x86-64.so.2 => /ro/glibc-amd64-2.27-1/out/lib/ld-linux-x86-64.so.2 (0x00007f1c2a17e000)
Proof-of-concept for reading the ELF interpreter programmatically:
char *read_elf_interp(const char *filename) {
char *res = NULL;
int fd = open(filename, O_RDONLY, 0);
if (fd < 0) {
err(EXIT_FAILURE, "open %s", filename);
}
Elf *e = elf_begin(fd, ELF_C_READ, NULL);
if (e == NULL) {
errx(EXIT_FAILURE, "elf_begin: %s", elf_errmsg(-1));
}
if (elf_kind(e) != ELF_K_ELF) {
goto out;
}
GElf_Ehdr ehdr;
if (gelf_getehdr(e, &ehdr) == NULL) {
goto out;
}
for (int i = 0; i < ehdr.e_phnum; i++) {
GElf_Phdr mem;
GElf_Phdr *phdr = gelf_getphdr(e, i, &mem);
if (phdr->p_type != PT_INTERP) {
continue;
}
size_t maxsize;
char *filedata = elf_rawfile(e, &maxsize);
if (filedata == NULL || phdr->p_offset >= maxsize) {
continue;
}
res = strdup(filedata + phdr->p_offset);
break;
}
out:
elf_end(e);
close(fd);
return res;
}
The initrd generated by
distri pack
works fine, but when I try to create a new one, that results in a non-booting system. Deserves a closer look.