6ad9c63180
The /usr/bin/toolbox binary is not only used to interact with toolbox containers and images from the host. It's also used as the entry point of the containers by bind mounting the binary from the host into the container. This means that the /usr/bin/toolbox binary on the host must also work inside the container, even if they have different operating systems. In the past, this worked perfectly well with the POSIX shell implementation because it got intepreted by whichever /bin/sh was available. The Go implementation also mostly worked so far because it's largely statically linked, with the notable exception of the standard C library. However, recently glibc-2.32, which is used by Fedora 33 onwards, added a new version of the pthread_sigmask symbol [1] as part of the libpthread removal project: $ objdump -T /usr/bin/toolbox | grep GLIBC_2.32 0000000000000000 DO *UND* 0000000000000000 GLIBC_2.32 pthread_sigmask This means that /usr/bin/toolbox binaries built against glibc-2.32 on newer Fedoras pick up the latest version of the symbol and fail to run against older glibcs in older Fedoras. One way to fix this is to disable the use of any C code from Go by using the CGO_ENABLED environment variable [2]. However, this can negatively impact packages like "os/user" [3] and "net" [4], where the more featureful glibc APIs will be replaced by more limited equivalents written only in Go. Instead, since glibc uses symbol versioning, it's better to tell the Go toolchain to avoid linking against any symbols from glibc-2.32. This was accomplished by a few linker tricks: * The GNU ld linker's --wrap flag was used when building the Go code to divert pthread_sigmask invocations from Go to another function called __wrap_pthread_sigmask. * A static library was added to provide this __wrap_pthread_sigmask function, which forwards calls to the actual pthread_sigmask API in glibc. This library itself was not linked with --wrap, and specifies the latest permissible version of the pthread_sigmask symbol from glibc for each architecture. Currently, the list of architectures covers the ones that Fedora builds for. * The Go cmd/link linker was switched to external mode [5]. This ensures that the final object file containing all the Go code gets linked to the standard C library and the wrapper static library by the GNU ld linker for the --wrap flag to kick in. Based on ideas from Ondřej Míchal. [1] glibc commit c6663fee4340291c https://sourceware.org/git/?p=glibc.git;a=commit;h=c6663fee4340291c [2] https://golang.org/cmd/cgo/ [3] https://golang.org/pkg/os/user/ [4] https://golang.org/pkg/net/ [5] https://golang.org/src/cmd/cgo/doc.go https://github.com/containers/toolbox/issues/529
44 lines
993 B
Meson
44 lines
993 B
Meson
project(
|
|
'toolbox',
|
|
'c',
|
|
version: '0.0.93',
|
|
license: 'ASL 2.0',
|
|
meson_version: '>= 0.40.0',
|
|
)
|
|
|
|
cc = meson.get_compiler('c')
|
|
add_project_arguments('-pthread', language: 'c')
|
|
add_project_link_arguments('-pthread', language: 'c')
|
|
|
|
go = find_program('go')
|
|
go_md2man = find_program('go-md2man')
|
|
shellcheck = find_program('shellcheck', required: false)
|
|
|
|
profiledir = get_option('profile_dir')
|
|
|
|
systemd_dep = dependency('systemd')
|
|
tmpfilesdir = systemd_dep.get_pkgconfig_variable('tmpfilesdir')
|
|
|
|
toolbox = files('toolbox')
|
|
|
|
if shellcheck.found()
|
|
test('shellcheck', shellcheck, args: [toolbox])
|
|
endif
|
|
|
|
bash_completion = dependency('bash-completion', required: false)
|
|
if bash_completion.found()
|
|
install_data(
|
|
'completion/bash/toolbox',
|
|
install_dir: bash_completion.get_pkgconfig_variable('completionsdir')
|
|
)
|
|
endif
|
|
|
|
install_subdir(
|
|
'test',
|
|
install_dir: join_paths(get_option('datadir'), meson.project_name())
|
|
)
|
|
|
|
subdir('data')
|
|
subdir('doc')
|
|
subdir('profile.d')
|
|
subdir('src')
|