2018-10-19 15:45:15 +00:00
|
|
|
project(
|
2019-02-15 15:36:30 +00:00
|
|
|
'toolbox',
|
build: Ensure binaries built on Fedora 33 run on Fedoras 32 & 31
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
2020-08-20 23:06:09 +00:00
|
|
|
'c',
|
2021-02-23 18:57:04 +00:00
|
|
|
version: '0.0.99.1',
|
2018-10-19 15:45:15 +00:00
|
|
|
license: 'ASL 2.0',
|
|
|
|
meson_version: '>= 0.40.0',
|
|
|
|
)
|
|
|
|
|
build: Ensure binaries built on Fedora 33 run on Fedoras 32 & 31
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
2020-08-20 23:06:09 +00:00
|
|
|
cc = meson.get_compiler('c')
|
|
|
|
add_project_arguments('-pthread', language: 'c')
|
|
|
|
add_project_link_arguments('-pthread', language: 'c')
|
|
|
|
|
2020-05-13 21:34:00 +00:00
|
|
|
go = find_program('go')
|
2019-02-28 17:07:24 +00:00
|
|
|
go_md2man = find_program('go-md2man')
|
2019-04-10 12:03:15 +00:00
|
|
|
shellcheck = find_program('shellcheck', required: false)
|
2019-02-28 17:07:24 +00:00
|
|
|
|
2019-04-24 17:36:36 +00:00
|
|
|
profiledir = get_option('profile_dir')
|
|
|
|
|
Give access to removable devices and other temporary mounts
Currently, when udisks is configured to use /run/media instead of
/media, on most operating systems, the /run/media directory is created
by udisks itself when the first mount is handled [1]. This causes
problems when creating the toolbox container, if nothing has been
mounted after the current boot, because a missing directory cannot be
bind mounted.
Fedora Silverblue is a significant exception to the above, where
rpm-ostree takes care of creating /run/media with systemd-tmpfiles [2]
during boot.
The correct long-term solution is to get udisks to create /run/media
during boot with systemd-tmpfiles by installing a snippet in
tmpfiles.d [3, 4]. Until that happens, and is widely deployed, the
toolbox needs to provide the snippet itself to make things work on
the majority of operating systems.
Note that, in case udisks is configured to use /media instead of
/run/media, then this will create an unused /run/media directory. This
is probably fine because /run/media is the default setting for udisks.
Moreover, an unused directory is way better than not being able to
access mount points from a toolbox container or having 'podman create'
fail due to a missing directory.
Based on 4a2a15f2eb3a6b810fcf9b699272fcc9a7871c6e and as suggested by
Daniel J Walsh.
[1] UDisks commit aa02e5fc53efdeaf
https://github.com/storaged-project/udisks/commit/aa02e5fc53efdeaf
[2] rpm-ostree commit 958dfa435e4e4a3e
https://github.com/projectatomic/rpm-ostree/commit/958dfa435e4e4a3e
[3] https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html
[4] https://github.com/storaged-project/udisks/pull/641
https://github.com/debarshiray/toolbox/issues/3
2019-03-12 17:45:19 +00:00
|
|
|
systemd_dep = dependency('systemd')
|
|
|
|
tmpfilesdir = systemd_dep.get_pkgconfig_variable('tmpfilesdir')
|
|
|
|
|
2019-04-10 12:03:15 +00:00
|
|
|
toolbox = files('toolbox')
|
|
|
|
|
|
|
|
if shellcheck.found()
|
|
|
|
test('shellcheck', shellcheck, args: [toolbox])
|
|
|
|
endif
|
|
|
|
|
2019-04-25 19:16:30 +00:00
|
|
|
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
|
|
|
|
|
2020-07-23 15:17:38 +00:00
|
|
|
install_subdir(
|
|
|
|
'test',
|
|
|
|
install_dir: join_paths(get_option('datadir'), meson.project_name())
|
|
|
|
)
|
|
|
|
|
Give access to removable devices and other temporary mounts
Currently, when udisks is configured to use /run/media instead of
/media, on most operating systems, the /run/media directory is created
by udisks itself when the first mount is handled [1]. This causes
problems when creating the toolbox container, if nothing has been
mounted after the current boot, because a missing directory cannot be
bind mounted.
Fedora Silverblue is a significant exception to the above, where
rpm-ostree takes care of creating /run/media with systemd-tmpfiles [2]
during boot.
The correct long-term solution is to get udisks to create /run/media
during boot with systemd-tmpfiles by installing a snippet in
tmpfiles.d [3, 4]. Until that happens, and is widely deployed, the
toolbox needs to provide the snippet itself to make things work on
the majority of operating systems.
Note that, in case udisks is configured to use /media instead of
/run/media, then this will create an unused /run/media directory. This
is probably fine because /run/media is the default setting for udisks.
Moreover, an unused directory is way better than not being able to
access mount points from a toolbox container or having 'podman create'
fail due to a missing directory.
Based on 4a2a15f2eb3a6b810fcf9b699272fcc9a7871c6e and as suggested by
Daniel J Walsh.
[1] UDisks commit aa02e5fc53efdeaf
https://github.com/storaged-project/udisks/commit/aa02e5fc53efdeaf
[2] rpm-ostree commit 958dfa435e4e4a3e
https://github.com/projectatomic/rpm-ostree/commit/958dfa435e4e4a3e
[3] https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html
[4] https://github.com/storaged-project/udisks/pull/641
https://github.com/debarshiray/toolbox/issues/3
2019-03-12 17:45:19 +00:00
|
|
|
subdir('data')
|
2019-02-28 17:07:24 +00:00
|
|
|
subdir('doc')
|
2019-04-24 17:36:36 +00:00
|
|
|
subdir('profile.d')
|
2020-05-08 11:29:18 +00:00
|
|
|
subdir('src')
|