re: Testing Emulation Syscalls

2023-08-01 Thread matthew green
have we considered checking in tiny binaries actually built for
the emulation and using them?

various methods discussed so far have their own advantages, but
this is the only way that tests actual binaries built for eg
linux and run with compat_linux.  anything else is limited in
it's ability to test, and may actually not find faults if the
test & emulation are both broken.


.mrg.


Re: Testing Emulation Syscalls

2023-08-01 Thread Martin Husemann
On Tue, Aug 01, 2023 at 12:43:50PM -0400, Theodore Preduta wrote:
> My understanding of the "without Linux dev tools and libs around" part
> is that each test case would be a separate (static Linux) binary that is
> just a main() that only directly calls syscalls.

Yes.

> And then I guess integration with the rest of ATF could be done through
> something like atf-sh-api(3), with status reporting done via exit codes
> (maybe stdout/strerr too? but that would require more tooling).

Right. We have lots of atf wrappers around other "binaries" that do the
real tests (usually called h_* for test helper binary).

Martin


Re: Testing Emulation Syscalls

2023-08-01 Thread Theodore Preduta
On 2023-08-01 12:15, Emmanuel Dreyfus wrote:
> On Tue, Aug 01, 2023 at 05:52:57PM +0200, Martin Husemann wrote:
>> Yes we are. But the question is if we can create (tiny) test binaries
>> just for this purpose, without Linux dev tools and libs around,
>> from within a standard build.sh run.
> 
> You could craft a NetBSD binary that abuses the ELFNAME2(linux,probe)
> test in src/sys/compat/linux/common/linux_exec_elf32.c so that the kernel
> think it is a Linux binary. Of course if you use a syscall that does
> not have the same number in NetBSD and Linux, you crash, hence I am 
> not sure it could be useful.

My understanding of the "without Linux dev tools and libs around" part
is that each test case would be a separate (static Linux) binary that is
just a main() that only directly calls syscalls.

And then I guess integration with the rest of ATF could be done through
something like atf-sh-api(3), with status reporting done via exit codes
(maybe stdout/strerr too? but that would require more tooling).

Theo(dore)



Re: Testing Emulation Syscalls

2023-08-01 Thread Emmanuel Dreyfus
On Tue, Aug 01, 2023 at 05:52:57PM +0200, Martin Husemann wrote:
> Yes we are. But the question is if we can create (tiny) test binaries
> just for this purpose, without Linux dev tools and libs around,
> from within a standard build.sh run.

You could craft a NetBSD binary that abuses the ELFNAME2(linux,probe)
test in src/sys/compat/linux/common/linux_exec_elf32.c so that the kernel
think it is a Linux binary. Of course if you use a syscall that does
not have the same number in NetBSD and Linux, you crash, hence I am 
not sure it could be useful.

-- 
Emmanuel Dreyfus
m...@netbsd.org


Re: Testing Emulation Syscalls

2023-08-01 Thread Martin Husemann
On Tue, Aug 01, 2023 at 11:48:21AM -0400, Theodore Preduta wrote:
> I don't think so.  If the binary starts under Linux emulation then the
> kernel will expect that the syscall arguments follow Linux's calling
> convention.  (Which I guess could be done, but, correct me if I'm wrong,
> are we not a native Linux binary at that point?)

Yes we are. But the question is if we can create (tiny) test binaries
just for this purpose, without Linux dev tools and libs around,
from within a standard build.sh run.

If we can, this would be a simple solution - but I bet it is not trivial
(at least for the first few examples).

Also this should scale to other emulations (theoretically).

Martin


Re: Testing Emulation Syscalls

2023-08-01 Thread Theodore Preduta
On 2023-08-01 07:04, Valery Ushakov wrote:
> On Tue, Aug 01, 2023 at 12:39:46 +0200, Martin Husemann wrote:
> 
>> On Tue, Aug 01, 2023 at 01:34:54PM +0300, Valery Ushakov wrote:
>>> As for testing emulated syscalls - can we solve this problem with a
>>> bit of elf branding to convince the kernel to start the binary under
>>> emulation directly?  Inventing a whole new backdoor API for that seems
>>> kinda an overkill.
>>
>> That is probably quite easy to do, but we have a toolchain problem then
>> (solvable too).
>>
>> We need build.sh to be able to produce the test binaries (including
>> any needed libs, which don't have to be "native" libs of the emulated
>> system).
> 
> For simple cases - can we get away with tiny'ish freestanding test
> programs that invoke the tested syscalls so that we don't have to pull
> a new cross-compilation setup out of thin air just for that?

I don't think so.  If the binary starts under Linux emulation then the
kernel will expect that the syscall arguments follow Linux's calling
convention.  (Which I guess could be done, but, correct me if I'm wrong,
are we not a native Linux binary at that point?)

Theo(dore)



Re: Testing Emulation Syscalls

2023-08-01 Thread Taylor R Campbell
> Date: Mon, 31 Jul 2023 22:29:29 +0100
> From: Robert Swindells 
> 
> Theodore Preduta   wrote:
> > This comes somewhat as a "part 2" to
> > https://mail-index.netbsd.org/tech-kern/2023/06/21/msg028926.html
> >
> > Given the responses to that thread, I decided to add native stubs
> > for epoll (the fact epoll is widespread alone justifies it, but it has
> > already had some negative side effects, see:
> > https://mail-index.netbsd.org/source-changes-d/2023/07/30/msg013999.html).
> 
> What is wrong with the suggestion in the thread on tech-userlevel@ to
> just rename the header so that userland won't find it when configuring
> packages?

It is necessary but not sufficient.

Autoconf and other things will check for the symbol in libc,
irrespective of whether there is a header file or a declaration in a
header file.

We need to remove the symbol in libc too.


Re: Testing Emulation Syscalls

2023-08-01 Thread Valery Ushakov
On Tue, Aug 01, 2023 at 12:39:46 +0200, Martin Husemann wrote:

> On Tue, Aug 01, 2023 at 01:34:54PM +0300, Valery Ushakov wrote:
> > As for testing emulated syscalls - can we solve this problem with a
> > bit of elf branding to convince the kernel to start the binary under
> > emulation directly?  Inventing a whole new backdoor API for that seems
> > kinda an overkill.
> 
> That is probably quite easy to do, but we have a toolchain problem then
> (solvable too).
> 
> We need build.sh to be able to produce the test binaries (including
> any needed libs, which don't have to be "native" libs of the emulated
> system).

For simple cases - can we get away with tiny'ish freestanding test
programs that invoke the tested syscalls so that we don't have to pull
a new cross-compilation setup out of thin air just for that?  Testing
something like lwp-related calls probably requires a real linux
libpthread anyway, not a gum-and-toothpicks effigy.

-uwe


Re: Testing Emulation Syscalls

2023-08-01 Thread Martin Husemann
On Tue, Aug 01, 2023 at 01:34:54PM +0300, Valery Ushakov wrote:
> As for testing emulated syscalls - can we solve this problem with a
> bit of elf branding to convince the kernel to start the binary under
> emulation directly?  Inventing a whole new backdoor API for that seems
> kinda an overkill.

That is probably quite easy to do, but we have a toolchain problem then
(solvable too).

We need build.sh to be able to produce the test binaries (including
any needed libs, which don't have to be "native" libs of the emulated
system).

Martin


Re: Testing Emulation Syscalls

2023-08-01 Thread Valery Ushakov
On Tue, Aug 01, 2023 at 08:16:50 +0200, Martin Husemann wrote:

> On Mon, Jul 31, 2023 at 05:03:48PM -0400, Theodore Preduta wrote:
> > One idea (mentioned in the original thread) would be to introduce a
> > syscall along the lines of
> > 
> > int emul_syscall(const char *emul_name, int number, ...)
> > 
> > which executes a single syscall.  The flaw with this idea is that state
> > may need to be stored across syscalls in struct linux_emuldata, but I
> > don't know how this interface could accommodate this.
> > 
> > Another idea would be to introduce a syscall along the lines of
> > 
> > int setemul(const char *emul_name)
> > 
> > which would switch the syscall table dynamically so that the test case
> > could be run under emulation (preserving emuldata state) and then switch
> > back to report the result.  (And then individual syscalls would be
> > called via __syscall(2).)
> 
> I think this would be quite tricky for the test code in userland.
> 
> But what about a variant of the initial suggestion:
> 
> // returns an integer descriptor
> int open_emul(const char *emulname);
> 
> // invokes a syscall under an open emulation
> int emul_syscall(int emul, int number, ...);
> 
> // frees all state for the emulation, returns 0 or -1
> int close_emul(int emul);
> 
> IMO this still is far better than exposing native syscalls that we do
> not really need/want.

I'd rather we don't expose epoll(2) as a native syscall at least not
just yet, given what pkgsrc folks are telling us.  It's not like we
have pressing need to use it in our own code in base.  And for third
party software it creates confusion as was pointed out.

As for testing emulated syscalls - can we solve this problem with a
bit of elf branding to convince the kernel to start the binary under
emulation directly?  Inventing a whole new backdoor API for that seems
kinda an overkill.

-uwe


Re: Testing Emulation Syscalls

2023-08-01 Thread Martin Husemann
On Mon, Jul 31, 2023 at 05:03:48PM -0400, Theodore Preduta wrote:
> One idea (mentioned in the original thread) would be to introduce a
> syscall along the lines of
> 
>   int emul_syscall(const char *emul_name, int number, ...)
> 
> which executes a single syscall.  The flaw with this idea is that state
> may need to be stored across syscalls in struct linux_emuldata, but I
> don't know how this interface could accommodate this.
> 
> Another idea would be to introduce a syscall along the lines of
> 
>   int setemul(const char *emul_name)
> 
> which would switch the syscall table dynamically so that the test case
> could be run under emulation (preserving emuldata state) and then switch
> back to report the result.  (And then individual syscalls would be
> called via __syscall(2).)

I think this would be quite tricky for the test code in userland.

But what about a variant of the initial suggestion:

// returns an integer descriptor
int open_emul(const char *emulname);

// invokes a syscall under an open emulation
int emul_syscall(int emul, int number, ...);

// frees all state for the emulation, returns 0 or -1
int close_emul(int emul);

IMO this still is far better than exposing native syscalls that we do
not really need/want.

Martin
P.S.: independent of this, the "make kqueue work across forks" is a good
idea, independent of the epoll syscall.