mailing list of musl libc
 help / color / mirror / Atom feed
* [musl] qemu-user and musl
@ 2020-10-28 23:50 Michael Forney
  2020-10-29  2:24 ` Érico Nogueira
  2020-10-29  3:11 ` Rich Felker
  0 siblings, 2 replies; 4+ messages in thread
From: Michael Forney @ 2020-10-28 23:50 UTC (permalink / raw)
  To: musl

Hi,

I'm trying to get various musl compatibility issues in qemu fixed
upstream. Here are the issues I've encountered:

1. To implement the timer_create syscall, qemu just translates
between host and target sigevent, then calls the libc timer_create.
For SIGEV_THREAD, both glibc and musl implement this using the
Linux-specific SIGEV_THREAD_ID. However, musl's timer_create does
not support SIGEV_THREAD_ID from the application, so it fails with
EINVAL. This means that any application using timers with SIGEV_THREAD
does not work with qemu-user running on musl.

This issue appears as a build time error due to the use of
glibc-internal _sigev_un._tid member during sigevent translation.
Most distributions patch this by introducing a `host_sigevent`
matching the glibc layout and translating to that instead of libc's
sigevent. For the reasons mentioned above, this does not actually
fix the problem.

I see there is a patch on the mailing list adding support for
SIGEV_THREAD_ID which looks ready to merge. Rich, since you're
working towards getting ready for the next musl release, do you
think this might make it in? That way, we could just patch qemu to
add

#ifndef sigev_notify_thread_id
#define sigev_notify_thread_id _sigev_un._tid
#endif

and replace _sigev_un._tid with sigev_notify_thread_id.

2. qemu uses long obsolete F_SHLCK and F_EXLCK in the translation
of struct flock between host and target, which musl does not define.
Most musl distributions patch qemu to define these constants itself
if they are missing, but seeing as these lock types are unsupported
by Linux since 2.2, I sent a patch to just drop them (you'll get
EINVAL either way).

3. qemu uses the following configure test to check for clock_adjtime:

#include <time.h>

int main(void)
{
	return clock_adjtime(0, 0);
}

However, musl declares clock_adjtime in sys/timex.h, as indicated
by the linux man page, while glibc only declares it in time.h (i.e.
it is not just a case of glibc implicitly including other headers).
So, including one or the other is not enough. A real application
will need both anyway for the clockid_t values and struct timex,
but this mismatch seems a bit strange and I'm not sure if it was
deliberate.

(of course, this is easy to fix by just adding an include of
<sys/timex.h> to the test, but I thought I'd mention it in case
there was anything actionable here)

4. Until recently qemu used the __SIGRTMIN and __SIGRTMAX macros
in its signal translation code. It looks like this was recently
refactored, and all that remains is a static assert:

QEMU_BUILD_BUG_ON(__SIGRTMAX + 1 != _NSIG);

I think the intention is to ensure that any possible value of
SIGRTMAX is smaller than _NSIG and will not index past past the end
of the host-to-target translation table. However, I think this is
a safe assumption and the assert can be dropped (or at least, wrapped
in #ifdef __SIGRTMAX).

Any suggestions for any of these proposed fixes are welcome.

-Michael

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [musl] qemu-user and musl
  2020-10-28 23:50 [musl] qemu-user and musl Michael Forney
@ 2020-10-29  2:24 ` Érico Nogueira
  2020-10-29  3:11 ` Rich Felker
  1 sibling, 0 replies; 4+ messages in thread
From: Érico Nogueira @ 2020-10-29  2:24 UTC (permalink / raw)
  To: musl, musl

On Wed Oct 28, 2020 at 1:50 PM -03, Michael Forney wrote:
> Hi,
>
> I'm trying to get various musl compatibility issues in qemu fixed
> upstream. Here are the issues I've encountered:

That's great!

Have you explored runtime differences between musl and glibc, as well?
We have a bug report [1] in Void for qemu-aarch64-static's behavior when
built with musl, where it seems unable to connect to the network.

From the bug report:

  # ip address
  netlink receive error Message too long (90)

I haven't investigated the issue yet, but since you were talking about
qemu, I thought it would be a good opportunity to mention it.

- [1] https://github.com/void-linux/void-packages/issues/23557

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [musl] qemu-user and musl
  2020-10-28 23:50 [musl] qemu-user and musl Michael Forney
  2020-10-29  2:24 ` Érico Nogueira
@ 2020-10-29  3:11 ` Rich Felker
  2020-10-29  7:37   ` Michael Forney
  1 sibling, 1 reply; 4+ messages in thread
From: Rich Felker @ 2020-10-29  3:11 UTC (permalink / raw)
  To: musl

On Wed, Oct 28, 2020 at 04:50:29PM -0700, Michael Forney wrote:
> Hi,
> 
> I'm trying to get various musl compatibility issues in qemu fixed
> upstream. Here are the issues I've encountered:

Thanks! This is a long-wanted goal!

> 1. To implement the timer_create syscall, qemu just translates
> between host and target sigevent, then calls the libc timer_create.
> For SIGEV_THREAD, both glibc and musl implement this using the
> Linux-specific SIGEV_THREAD_ID. However, musl's timer_create does
> not support SIGEV_THREAD_ID from the application, so it fails with
> EINVAL. This means that any application using timers with SIGEV_THREAD
> does not work with qemu-user running on musl.
> 
> This issue appears as a build time error due to the use of
> glibc-internal _sigev_un._tid member during sigevent translation.
> Most distributions patch this by introducing a `host_sigevent`
> matching the glibc layout and translating to that instead of libc's
> sigevent. For the reasons mentioned above, this does not actually
> fix the problem.
> 
> I see there is a patch on the mailing list adding support for
> SIGEV_THREAD_ID which looks ready to merge. Rich, since you're
> working towards getting ready for the next musl release, do you
> think this might make it in? That way, we could just patch qemu to
> add
> 
> #ifndef sigev_notify_thread_id
> #define sigev_notify_thread_id _sigev_un._tid
> #endif
> 
> and replace _sigev_un._tid with sigev_notify_thread_id.

I think that's okay, and I'm merging the patch now (thanks for
reminding me!), but I'm not sure if it will work still. The signal
number used as SIGTIMER is considered an implementation-reserved
internal signal by musl, and as such it can't be poked at by any of
the public signal API -- and even if it could be, poking at it would
break things.

Future musl will probably drop this signal entirley and implement
SIGEV_THREAD timers in userspace with a clock_nanosleep loop. It would
be a lot cleaner, but my only reservation is about whether it can be
made to work with Linux's wake-on-timer functionality that users might
want.

> 2. qemu uses long obsolete F_SHLCK and F_EXLCK in the translation
> of struct flock between host and target, which musl does not define.
> Most musl distributions patch qemu to define these constants itself
> if they are missing, but seeing as these lock types are unsupported
> by Linux since 2.2, I sent a patch to just drop them (you'll get
> EINVAL either way).

These are hideous legacy artifacts of ancient Linux's attempt to let
libc emulate BSD flock() on top of fcntl, which did not work. qemu
should just drop them. They're not working.

> 3. qemu uses the following configure test to check for clock_adjtime:
> 
> #include <time.h>
> 
> int main(void)
> {
> 	return clock_adjtime(0, 0);
> }
> 
> However, musl declares clock_adjtime in sys/timex.h, as indicated
> by the linux man page, while glibc only declares it in time.h (i.e.
> it is not just a case of glibc implicitly including other headers).
> So, including one or the other is not enough. A real application
> will need both anyway for the clockid_t values and struct timex,
> but this mismatch seems a bit strange and I'm not sure if it was
> deliberate.
> 
> (of course, this is easy to fix by just adding an include of
> <sys/timex.h> to the test, but I thought I'd mention it in case
> there was anything actionable here)

I think it should be left alone. clock_adjtime is not usable without
sys/timex.h anyway, and struct timex can't be exposed in time.h
(although I guess it could be exposed as an incomplete type only with
_GNU_SOURCE, but that might not even help). Applications should just
follow the documentation and use sys/timex.h.

> 4. Until recently qemu used the __SIGRTMIN and __SIGRTMAX macros
> in its signal translation code. It looks like this was recently
> refactored, and all that remains is a static assert:
> 
> QEMU_BUILD_BUG_ON(__SIGRTMAX + 1 != _NSIG);
> 
> I think the intention is to ensure that any possible value of
> SIGRTMAX is smaller than _NSIG and will not index past past the end
> of the host-to-target translation table. However, I think this is
> a safe assumption and the assert can be dropped (or at least, wrapped
> in #ifdef __SIGRTMAX).

That sounds correct to me.

Rich

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [musl] qemu-user and musl
  2020-10-29  3:11 ` Rich Felker
@ 2020-10-29  7:37   ` Michael Forney
  0 siblings, 0 replies; 4+ messages in thread
From: Michael Forney @ 2020-10-29  7:37 UTC (permalink / raw)
  To: musl

Rich Felker <dalias@libc.org> wrote:
> I think that's okay, and I'm merging the patch now (thanks for
> reminding me!), but I'm not sure if it will work still. The signal
> number used as SIGTIMER is considered an implementation-reserved
> internal signal by musl, and as such it can't be poked at by any of
> the public signal API -- and even if it could be, poking at it would
> break things.

Doesn't qemu's signal translating code solve this problem? As of
[0], it maps target signals starting at 32 to host signal SIGRTMIN
+ sig - 32 (previously, it just swapped __SIGRTMIN and __SIGRTMAX).
So the target libc's reserved signal maps to some free RT signal
on the host, and that's what ends up in the sigev_signo passed to
the host libc.

I wrote a simple test program that used SIGEV_THREAD, and it seemed
to work after applying James' patch.

[0] https://github.com/qemu/qemu/commit/6bc024e713fd35eb5fddbe16acd8dc92d27872a9

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-10-29  7:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-28 23:50 [musl] qemu-user and musl Michael Forney
2020-10-29  2:24 ` Érico Nogueira
2020-10-29  3:11 ` Rich Felker
2020-10-29  7:37   ` Michael Forney

mailing list of musl libc

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.vuxu.org/musl

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 musl musl/ http://inbox.vuxu.org/musl \
		musl@inbox.vuxu.org
	public-inbox-index musl

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.musl


code repositories for the project(s) associated with this inbox:

	https://git.vuxu.org/mirror/musl/

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git