<bits/syscall.h>: Use an arch-independent system call list on Linux

Message ID 088c5f84-0665-4a49-6d2a-fe3402a227b4@redhat.com
State New
Headers show

Commit Message

Florian Weimer April 5, 2017, 7:40 p.m.
Downstream, we have the problem that we need to deliver our glibc 
packages before the kernel team finishes backporting system calls.  This 
means that the final glibc build before a release does not contain all 
the SYS_* macros supported by the kernel headers.

I would have liked to address this by phasing out the SYS_* macros, but 
this suggestion was not received favorably during a previous discussion.

An ideal solution would generate the SYS_* macros when the glibc 
development package is installed, based on the already-installed kernel 
headers.  Our RPM version does not support delayed script execution, so 
there is significant risk that we end up with a dependency loop, due to 
which the generation step could fail.

So I'm proposing the attached patch as an alternative.  It uses a list 
of system call names and generates a <bits/syscall.h> file from that 
which has items of the form

#ifdef __NR_write
# define SYS_write __NR_write
#endif

The idea is to define only those SYS_ macros which actually exist in the 
kernel headers as __NR_ macros.  Therefore, we only need a single system 
call list across all architectures, and the generated header file is no 
longer architecture-specific, either.  The -dM-based macro extraction 
remains as a (much simplified) test case.  It fails if the kernel 
headers contain __NR_ macros not currently listed in the glibc source tree.

I think the increased predictability of glibc builds might be worth it 
upstream as well.  The cost is that we now have to update the list 
periodically, but that can be done when the kernel version embedded in 
scripts/build-many-glibcs.py is increased.

The included list of system call names is based on the currently 
building build-many-glibcs.py targets (that is, hppa and coldfire are 
missing).  We can easily adjust it once we get more buildable architectures.

Comments?

Thanks,
Florian

Comments

Andreas Schwab April 6, 2017, 8 a.m. | #1
On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:

> Downstream, we have the problem that we need to deliver our glibc packages
> before the kernel team finishes backporting system calls.  This means that
> the final glibc build before a release does not contain all the SYS_*
> macros supported by the kernel headers.

Why can't you just patch the kernel headers package?  With the uapi
separation the kernel headers are pretty much independent of the kernel.

Andreas.
Florian Weimer April 6, 2017, 8:52 a.m. | #2
On 04/06/2017 10:00 AM, Andreas Schwab wrote:
> On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> Downstream, we have the problem that we need to deliver our glibc packages
>> before the kernel team finishes backporting system calls.  This means that
>> the final glibc build before a release does not contain all the SYS_*
>> macros supported by the kernel headers.
>
> Why can't you just patch the kernel headers package?

Wasn't this rejected on this list because that would lead to a namespace 
violation?

> With the uapi
> separation the kernel headers are pretty much independent of the kernel.

The system call list is generated in an architecture-specific manner.  I 
looked into this, most architectures use some construct which is rather 
impenetrable.  It's also very brittle in the sense that you can easily 
change the userspace ABI by accident, and nothing in the kernel build 
will tell you that you just did.  It's also unclear how to convince 
kernel maintainers to accept such a change (and think you'll have to 
convince each architecture maintainer).

If the SYS_ macros come from the kernel side, we'd need some sort of 
two-way handshake anyway (glibc tells the kernel that it's prepared to 
accept SYS_ macros, the kernel tells glibc it has defined SYS_ macros, 
and which point glibc does not do its own thing with the SYS_ macros). 
So an incremental conversion looks possible.

I think that if we really need both sets of macros, the __NR_ and SYS_ 
macros should come from the same source.  But that seems to be difficult 
to achieve.

Thanks,
Florian
Andreas Schwab April 6, 2017, 9:03 a.m. | #3
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> On 04/06/2017 10:00 AM, Andreas Schwab wrote:
>> On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>
>>> Downstream, we have the problem that we need to deliver our glibc packages
>>> before the kernel team finishes backporting system calls.  This means that
>>> the final glibc build before a release does not contain all the SYS_*
>>> macros supported by the kernel headers.
>>
>> Why can't you just patch the kernel headers package?
>
> Wasn't this rejected on this list because that would lead to a namespace
> violation?

I don't understand.  The kernel uapi headers fully respect namespace,
at least those used by glibc.

> The system call list is generated in an architecture-specific manner.

Sure, but the commits that add the syscalls are easily separable.  All
you need is to update the files underneath asm/unistd.h, which are
pretty regular.

> I looked into this, most architectures use some construct which is
> rather impenetrable.  It's also very brittle in the sense that you can
> easily change the userspace ABI by accident, and nothing in the kernel
> build will tell you that you just did.

You only need to patch the kernel headers package, which is hopefully
separate from the kernel.

Andreas.
Florian Weimer April 6, 2017, 9:47 a.m. | #4
On 04/06/2017 11:03 AM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> On 04/06/2017 10:00 AM, Andreas Schwab wrote:
>>> On Apr 05 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>>> Downstream, we have the problem that we need to deliver our glibc packages
>>>> before the kernel team finishes backporting system calls.  This means that
>>>> the final glibc build before a release does not contain all the SYS_*
>>>> macros supported by the kernel headers.
>>>
>>> Why can't you just patch the kernel headers package?
>>
>> Wasn't this rejected on this list because that would lead to a namespace
>> violation?
>
> I don't understand.  The kernel uapi headers fully respect namespace,
> at least those used by glibc.

I think the argument was that __NR_* should come from the kernel, and 
SYS_* should come from glibc, and that the kernel has no business 
defining SYS_* macros, purely based on namespace concerns.

>> The system call list is generated in an architecture-specific manner.
>
> Sure, but the commits that add the syscalls are easily separable.  All
> you need is to update the files underneath asm/unistd.h, which are
> pretty regular.

Not sure if we are talking about the same thing.  Our kernel-headers 
package comes from the kernel sources, 3.10 era.  Maybe you have 
frozen/explicit <asm/unistd.h> header in the sources.  We don't, we only 
have what upstream offers, which is … quite dynamic and heavily 
automated on some architectures.

>> I looked into this, most architectures use some construct which is
>> rather impenetrable.  It's also very brittle in the sense that you can
>> easily change the userspace ABI by accident, and nothing in the kernel
>> build will tell you that you just did.
>
> You only need to patch the kernel headers package, which is hopefully
> separate from the kernel.

Well, I see how this can simplify things.  This is not the case for us. 
I don't know the rationale behind the tight integration with the kernel 
package.  I'll ask around.

Anyway, I think for those who don't have separately maintained uapi 
headers (because they are building from upstream kernel sources), I 
think the relaxing of the build order requirement my proposed patch 
provides is still valuable.

Thanks,
Florian
Andreas Schwab April 6, 2017, 10:07 a.m. | #5
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> I think the argument was that __NR_* should come from the kernel, and
> SYS_* should come from glibc, and that the kernel has no business defining
> SYS_* macros, purely based on namespace concerns.

I don't know why you are talking about SYS_.  All that the kernel
defines are __NR_.  The SYS_ defines are pure glibc stuff.

> Not sure if we are talking about the same thing.  Our kernel-headers
> package comes from the kernel sources, 3.10 era.

Consider splitting it out, they are really independent.  Then you can
update the kernel headers without touching the kernel.

Andreas.
Florian Weimer April 6, 2017, 10:12 a.m. | #6
On 04/06/2017 12:07 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> I think the argument was that __NR_* should come from the kernel, and
>> SYS_* should come from glibc, and that the kernel has no business defining
>> SYS_* macros, purely based on namespace concerns.
>
> I don't know why you are talking about SYS_.  All that the kernel
> defines are __NR_.  The SYS_ defines are pure glibc stuff.

The separation is what causes problems because there is no way to tell 
the C preprocessor to export all __NR_* macros as SYS_* macros, too.

As a result, current glibc has this elaborate dance at built where it 
runs “gcc -E -dM” (with varying additional parameters to get the 
lib/libx32/lib64 variants).  I want to get rid of that because it means 
that if you upgrade the kernel headers after building glibc, the SYS_* 
and __NR_* macros drift apart.

>> Not sure if we are talking about the same thing.  Our kernel-headers
>> package comes from the kernel sources, 3.10 era.
>
> Consider splitting it out, they are really independent.  Then you can
> update the kernel headers without touching the kernel.

But I'd still have the issue that the kernel headers contain only the 
__NR_* macros, not the SYS_* macros.

If you think that SYS_* macros should remain glibc business, then I 
think the patch I posted is the right approach to simplify independent 
kernel header updates (whether they come from a separate package, or 
directly from the upstream sources).

Thanks,
Florian
Andreas Schwab April 6, 2017, 12:29 p.m. | #7
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> As a result, current glibc has this elaborate dance at built where it runs
> “gcc -E -dM” (with varying additional parameters to get the
> lib/libx32/lib64 variants).  I want to get rid of that because it means
> that if you upgrade the kernel headers after building glibc, the SYS_* and
> __NR_* macros drift apart.

You have to rebuild glibc anyway if new syscalls come along, so there
isn't much difference.

Andreas.
Florian Weimer April 6, 2017, 12:32 p.m. | #8
On 04/06/2017 02:29 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> As a result, current glibc has this elaborate dance at built where it runs
>> “gcc -E -dM” (with varying additional parameters to get the
>> lib/libx32/lib64 variants).  I want to get rid of that because it means
>> that if you upgrade the kernel headers after building glibc, the SYS_* and
>> __NR_* macros drift apart.
>
> You have to rebuild glibc anyway if new syscalls come along, so there
> isn't much difference.

Yes, but if glibc carries an explicit list, we can schedule the glibc 
rebuild before the kernel build.  If we do that with a recent enough 
upstream kernel, we do not even need to know at that point which system 
calls will actually backported.  The required SYS_* macros will simply 
appear if the kernel headers add the __NR_* macro.

Thanks,
Florian
Andreas Schwab April 6, 2017, 12:49 p.m. | #9
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> Yes, but if glibc carries an explicit list, we can schedule the glibc
> rebuild before the kernel build.

You can do the same with an updated kernel headers package.

Andreas.
Florian Weimer April 6, 2017, 1:24 p.m. | #10
On 04/06/2017 02:49 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> Yes, but if glibc carries an explicit list, we can schedule the glibc
>> rebuild before the kernel build.
>
> You can do the same with an updated kernel headers package.

But the uapi kernel headers aren't separate upstream, and until they 
are, the proposed new approach to SYS_* generation may be superior.

Unless everyone else but us generates their own separate kernel-headers 
package, that is. :-/

Thanks,
Florian
Andreas Schwab April 6, 2017, 1:44 p.m. | #11
On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:

> But the uapi kernel headers aren't separate upstream, and until they are,
> the proposed new approach to SYS_* generation may be superior.
>
> Unless everyone else but us generates their own separate kernel-headers
> package, that is. :-/

Here is a script that does that.  It basically just runs make
headers_install_all, and the result is put in a tarball.

https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1

Andreas.
Florian Weimer April 6, 2017, 2:22 p.m. | #12
On 04/06/2017 03:44 PM, Andreas Schwab wrote:
> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>
>> But the uapi kernel headers aren't separate upstream, and until they are,
>> the proposed new approach to SYS_* generation may be superior.
>>
>> Unless everyone else but us generates their own separate kernel-headers
>> package, that is. :-/
>
> Here is a script that does that.  It basically just runs make
> headers_install_all, and the result is put in a tarball.
>
> https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1

Thanks, I will take that under consideration.

Further comments from anyone else?

Florian
Dmitry V. Levin April 6, 2017, 2:37 p.m. | #13
On Thu, Apr 06, 2017 at 04:22:40PM +0200, Florian Weimer wrote:
> On 04/06/2017 03:44 PM, Andreas Schwab wrote:
> > On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
> >
> >> But the uapi kernel headers aren't separate upstream, and until they are,
> >> the proposed new approach to SYS_* generation may be superior.
> >>
> >> Unless everyone else but us generates their own separate kernel-headers
> >> package, that is. :-/
> >
> > Here is a script that does that.  It basically just runs make
> > headers_install_all, and the result is put in a tarball.
> >
> > https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1
> 
> Thanks, I will take that under consideration.
> 
> Further comments from anyone else?

We also build kernel headers separately from the kernel, see
http://git.altlinux.org/gears/g/..git?p=glibc-kernheaders.git;a=blob;f=glibc-kernheaders.spec
Florian Weimer April 21, 2017, 10:06 a.m. | #14
On 04/06/2017 04:37 PM, Dmitry V. Levin wrote:
> On Thu, Apr 06, 2017 at 04:22:40PM +0200, Florian Weimer wrote:
>> On 04/06/2017 03:44 PM, Andreas Schwab wrote:
>>> On Apr 06 2017, Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>>> But the uapi kernel headers aren't separate upstream, and until they are,
>>>> the proposed new approach to SYS_* generation may be superior.
>>>>
>>>> Unless everyone else but us generates their own separate kernel-headers
>>>> package, that is. :-/
>>>
>>> Here is a script that does that.  It basically just runs make
>>> headers_install_all, and the result is put in a tarball.
>>>
>>> https://build.opensuse.org/package/view_file/Base:System/linux-glibc-devel/install_all.sh?expand=1
>>
>> Thanks, I will take that under consideration.
>>
>> Further comments from anyone else?
> 
> We also build kernel headers separately from the kernel, see
> http://git.altlinux.org/gears/g/..git?p=glibc-kernheaders.git;a=blob;f=glibc-kernheaders.spec

Do you (and other distributions) build applications against these 
headers as well, or are those only used for building glibc itself?

Thanks,
Florian
Andreas Schwab April 21, 2017, 12:26 p.m. | #15
On Apr 21 2017, Florian Weimer <fweimer@redhat.com> wrote:

> Do you (and other distributions) build applications against these headers
> as well, or are those only used for building glibc itself?

These are the kernel UAPI headers, so of course they are used by
everything.

Andreas.
Florian Weimer April 21, 2017, 12:37 p.m. | #16
On 04/21/2017 02:26 PM, Andreas Schwab wrote:
> On Apr 21 2017, Florian Weimer <fweimer@redhat.com> wrote:
> 
>> Do you (and other distributions) build applications against these headers
>> as well, or are those only used for building glibc itself?
> 
> These are the kernel UAPI headers, so of course they are used by
> everything.

Do you rebase the UAPI headers to the latest kernel release even after a 
release of the distribution, as part of regular maintenance?

If not, how do you get SYS_ macros for the system calls you backport 
into your stable kernel?

Thanks,
Florian
Carlos O'Donell April 21, 2017, 3:16 p.m. | #17
On 04/21/2017 08:26 AM, Andreas Schwab wrote:
> On Apr 21 2017, Florian Weimer <fweimer@redhat.com> wrote:
> 
>> Do you (and other distributions) build applications against these headers
>> as well, or are those only used for building glibc itself?
> 
> These are the kernel UAPI headers, so of course they are used by
> everything.

TLDR; This introduces changes which can break developer applications,
and the only benefit is to glibc.

The benefit to rebasing the kernel UAPI headers is that glibc will have 
an accurate list of SYS_ macros.

The disbenefit of the new kernel UAPI headers package is that application 
developers building applications must bear potentially new integration 
costs and header conflicts with their own headers (assume glibc does 
better header inclusion testing, and I have some patches for that).

My opinion is that the upstream kernel UAPI headers continue to change
without good management of the changes. I have seen at least 3 changes
which break header inclusion ordering and that would have caused application
build problems. None of the authors of those changes came to talk to us
about adding the right guards in glibc to prevent breakage. Worse there
have been discussions about deleting existing guards, that change would
break header inclusion order in one of the two directions, just to 
simplify libc-compat.h in the kernel (avoiding needing any libc-specific
knowledge). This does not seem conservative enough to me.

Are these problems passed on for the users to fix in those distributions
that track upstream kernel headers?

In the future I will continue to build my own builds with kernel master to
try catch all such changes, and add more tests to glibc to catch them too.
Andreas Schwab April 21, 2017, 6:02 p.m. | #18
On Apr 21 2017, Carlos O'Donell <carlos@redhat.com> wrote:

> TLDR; This introduces changes which can break developer applications,
> and the only benefit is to glibc.

I don't understand.  You cannot build anything without the kernel UAPI
headers.

Andreas.
Florian Weimer April 21, 2017, 6:46 p.m. | #19
* Andreas Schwab:

> On Apr 21 2017, Carlos O'Donell <carlos@redhat.com> wrote:
>
>> TLDR; This introduces changes which can break developer applications,
>> and the only benefit is to glibc.
>
> I don't understand.  You cannot build anything without the kernel UAPI
> headers.

I think we have to freeze the kernel headers along a distribution
release branch, and update them only insofar we backport things to
this distribution release branch.

My proposal aims to avoid a build order depedency between the
backports landing in the distribution kernel, and a glibc rebuild.
For point releases, glibc and kernel may be developed on different
schedules, and if the glibc build uses my proposed patch, it can use
the upstream system call list as a superset of what's going to be
backportable for the next point release.
Andreas Schwab April 21, 2017, 7:07 p.m. | #20
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> My proposal aims to avoid a build order depedency between the
> backports landing in the distribution kernel, and a glibc rebuild.

What do you gain over a UAPI headers update in line with the glibc
rebuild?

Andreas.
Florian Weimer April 21, 2017, 7:15 p.m. | #21
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> My proposal aims to avoid a build order depedency between the
>> backports landing in the distribution kernel, and a glibc rebuild.
>
> What do you gain over a UAPI headers update in line with the glibc
> rebuild?

We don't have to maintain a kernel package ourselves, or align our
delivery schedule with the kernel team.
Andreas Schwab April 21, 2017, 7:34 p.m. | #22
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> * Andreas Schwab:
>
>> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>>
>>> My proposal aims to avoid a build order depedency between the
>>> backports landing in the distribution kernel, and a glibc rebuild.
>>
>> What do you gain over a UAPI headers update in line with the glibc
>> rebuild?
>
> We don't have to maintain a kernel package ourselves, or align our
> delivery schedule with the kernel team.

The kernel UAPI package is independent of the kernel.

Andreas.
Florian Weimer April 21, 2017, 7:37 p.m. | #23
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> * Andreas Schwab:
>>
>>> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>>>
>>>> My proposal aims to avoid a build order depedency between the
>>>> backports landing in the distribution kernel, and a glibc rebuild.
>>>
>>> What do you gain over a UAPI headers update in line with the glibc
>>> rebuild?
>>
>> We don't have to maintain a kernel package ourselves, or align our
>> delivery schedule with the kernel team.
>
> The kernel UAPI package is independent of the kernel.

Well, yes, but that's another kernel package to maintain.

And we don't want to push an UAPI headers update in a point release,
so we wouldn't want to replace the other UAPI header package anyway.
The latter would still be used to build applications.
Andreas Schwab April 21, 2017, 7:40 p.m. | #24
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> And we don't want to push an UAPI headers update in a point release,
> so we wouldn't want to replace the other UAPI header package anyway.

Don't do that then.

Andreas.
Florian Weimer April 21, 2017, 7:57 p.m. | #25
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> And we don't want to push an UAPI headers update in a point release,
>> so we wouldn't want to replace the other UAPI header package anyway.
>
> Don't do that then.

What do you propose, then?  Build a custom UAPI header package with
the most recent upstream system call list, but otherwise with the
contents for the kernel version for the distribution release branch?

The downside is that you get SYS_ macros for system calls which are
not implemented in the distribution kernel.  (Quite a few, arguably
broken, applications use #ifdefs instead of run-time checking.)
Andreas Schwab April 22, 2017, 9:38 a.m. | #26
On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> The downside is that you get SYS_ macros for system calls which are
> not implemented in the distribution kernel. 

I don't understand.  Didn't you say the system call has been backported?

Andreas.
Florian Weimer April 22, 2017, 11:59 a.m. | #27
* Andreas Schwab:

> On Apr 21 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> The downside is that you get SYS_ macros for system calls which are
>> not implemented in the distribution kernel. 
>
> I don't understand.  Didn't you say the system call has been backported?

Yes, we seem to have a misunderstanding.  If I understand you, you say
some distributions are doing this on a stable branch:

  * Backport a system call to the actual kernel package.
  * Backport the system call addition to the kernel headers package.
    (changing the UAPI headers used by glibc and applications).
  * Rebuild glibc to generate the SYS_ macro list.

This does not work for some distributions because the order is like
this:

  * Rebuild glibc for a point release.
  * Backport a system call to the actual kernel package.
 (* Backport the system call addition to the kernel headers package.)

Whether the last step happens or not is immaterial in this context.
You won't get the SYS_ macro with this build order.

What could work is this:

 (* Backport system calls to the kernel package.)
  * Rebase the kernel headers package to the latest upstream version
    (changing the UAPI headers used by glibc and applications).
 (* Backport more system calls to the kernel package.)
  * Rebuild glibc to generate SYS_ macro list.
 (* Backport even more system calls to the kernel package.)

This way, the glibc build would provide a full SYS_ macro list,
assuming that the kernel backporting does not overtake upstream (which
seems unlikely).  However, some of the SYS_ macros will not work
because the distribution kernel will lake the correspondign __NR_
macros.
Andreas Schwab April 22, 2017, 1:45 p.m. | #28
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> This does not work for some distributions because the order is like
> this:
>
>   * Rebuild glibc for a point release.
>   * Backport a system call to the actual kernel package.
>  (* Backport the system call addition to the kernel headers package.)
>
> Whether the last step happens or not is immaterial in this context.
> You won't get the SYS_ macro with this build order.

Which your patch won't rectify.

> What could work is this:
>
>  (* Backport system calls to the kernel package.)
>   * Rebase the kernel headers package to the latest upstream version
>     (changing the UAPI headers used by glibc and applications).
>  (* Backport more system calls to the kernel package.)
>   * Rebuild glibc to generate SYS_ macro list.
>  (* Backport even more system calls to the kernel package.)
>
> This way, the glibc build would provide a full SYS_ macro list,
> assuming that the kernel backporting does not overtake upstream (which
> seems unlikely).  However, some of the SYS_ macros will not work
> because the distribution kernel will lake the correspondign __NR_
> macros.

In which way does the macro not work?

Andreas.
Florian Weimer April 22, 2017, 2:22 p.m. | #29
* Andreas Schwab:

> On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> This does not work for some distributions because the order is like
>> this:
>>
>>   * Rebuild glibc for a point release.
>>   * Backport a system call to the actual kernel package.
>>  (* Backport the system call addition to the kernel headers package.)
>>
>> Whether the last step happens or not is immaterial in this context.
>> You won't get the SYS_ macro with this build order.
>
> Which your patch won't rectify.

It does, if we pick up the upstream (rc) system call list at the time
we build glibc for the point release.  At that point, we have all
potential system calls to backport.

>> What could work is this:
>>
>>  (* Backport system calls to the kernel package.)
>>   * Rebase the kernel headers package to the latest upstream version
>>     (changing the UAPI headers used by glibc and applications).
>>  (* Backport more system calls to the kernel package.)
>>   * Rebuild glibc to generate SYS_ macro list.
>>  (* Backport even more system calls to the kernel package.)
>>
>> This way, the glibc build would provide a full SYS_ macro list,
>> assuming that the kernel backporting does not overtake upstream (which
>> seems unlikely).  However, some of the SYS_ macros will not work
>> because the distribution kernel will lake the correspondign __NR_
>> macros.
>
> In which way does the macro not work?

I was mistaken.  As described, it will work.  But if we only backport
the the system call additions to the UAPI headers used by the
applications, this

#ifdef SYS_getrandom
  return syscall (SYS_getrandom, buf, len, 0);
#else
  errno = ENOSYS;
  return -1;
#endif

could fail with an error that __NR_getrandom is undefined.

I was confused because I find the notion to rebase to the upstream
kernel headers in a point release a bit preposterous.
Andreas Schwab April 22, 2017, 3:08 p.m. | #30
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> I was mistaken.  As described, it will work.  But if we only backport
> the the system call additions to the UAPI headers used by the
> applications, this
>
> #ifdef SYS_getrandom
>   return syscall (SYS_getrandom, buf, len, 0);
> #else
>   errno = ENOSYS;
>   return -1;
> #endif
>
> could fail with an error that __NR_getrandom is undefined.

Why?  That's defined by the UAPI headers.

Andreas.
Florian Weimer April 22, 2017, 3:27 p.m. | #31
* Andreas Schwab:

> On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> I was mistaken.  As described, it will work.  But if we only backport
>> the the system call additions to the UAPI headers used by the
>> applications, this
>>
>> #ifdef SYS_getrandom
>>   return syscall (SYS_getrandom, buf, len, 0);
>> #else
>>   errno = ENOSYS;
>>   return -1;
>> #endif
>>
>> could fail with an error that __NR_getrandom is undefined.
>
> Why?  That's defined by the UAPI headers.

I meant: If we do not rebase the UAPI headers (but backport changes as
needed), while still building glibc against the current upstream
headers (to get a complete SYS_ macro list before the backporting
happens).
Andreas Schwab April 22, 2017, 3:37 p.m. | #32
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> I meant: If we do not rebase the UAPI headers (but backport changes as
> needed), while still building glibc against the current upstream
> headers (to get a complete SYS_ macro list before the backporting
> happens).

Why would you want to build a package against something that isn't part
of the distribution?

Andreas.
Florian Weimer April 22, 2017, 3:51 p.m. | #33
* Andreas Schwab:

> On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:
>
>> I meant: If we do not rebase the UAPI headers (but backport changes as
>> needed), while still building glibc against the current upstream
>> headers (to get a complete SYS_ macro list before the backporting
>> happens).
>
> Why would you want to build a package against something that isn't part
> of the distribution?

I don't follow.  It would be an internal build dependency, like LLVM
for Mesa (in some distributions).  It would be shipped like any other
build dependency.

I have these two constraints:

a) I need to build glibc before the kernel backporting finishes.
b) I can't rebase UAPI headers to the latest upstream.

I'm under the impression you are suggesting to build glibc against a
special set of UAPI headers which aren't used by the application.
That will lead to the too aggressive SYS_ macro generation.
Andreas Schwab April 22, 2017, 5:27 p.m. | #34
On Apr 22 2017, Florian Weimer <fw@deneb.enyo.de> wrote:

> I have these two constraints:
>
> a) I need to build glibc before the kernel backporting finishes.
> b) I can't rebase UAPI headers to the latest upstream.

Just add the patches you need and you are done.

Andreas.
Dmitry V. Levin April 23, 2017, 12:35 a.m. | #35
On Fri, Apr 21, 2017 at 11:16:26AM -0400, Carlos O'Donell wrote:
> My opinion is that the upstream kernel UAPI headers continue to change
> without good management of the changes. I have seen at least 3 changes
> which break header inclusion ordering and that would have caused application
> build problems. None of the authors of those changes came to talk to us
> about adding the right guards in glibc to prevent breakage. Worse there
> have been discussions about deleting existing guards, that change would
> break header inclusion order in one of the two directions, just to 
> simplify libc-compat.h in the kernel (avoiding needing any libc-specific
> knowledge). This does not seem conservative enough to me.

Unfortunately, there seems to be no good working synchronization mechanism
proposed yet.  The procedure described in
https://sourceware.org/glibc/wiki/Synchronizing_Headers has severe
problems on the kernel side.  Even with headers that were synchronized
several years ago we have unsolved inclusion issues like this:

$ gcc -xc -c -o/dev/null - <<EOF
#include <linux/in.h>
#include <netinet/in.h>
#include <linux/in6.h> 
EOF

or this:

$ gcc -xc -c -o/dev/null - <<EOF
#include <linux/xattr.h>
#include <netinet/in.h>
#include <linux/in6.h> 
EOF

See also https://sourceware.org/ml/libc-alpha/2017-04/msg00157.html

It's hard to expect that kernel folks would be adding new guards
if already added guards are so fragile.
Carlos O'Donell Aug. 24, 2017, 2:35 p.m. | #36
On 04/21/2017 02:46 PM, Florian Weimer wrote:
> * Andreas Schwab:
> 
>> On Apr 21 2017, Carlos O'Donell <carlos@redhat.com> wrote:
>>
>>> TLDR; This introduces changes which can break developer applications,
>>> and the only benefit is to glibc.
>>
>> I don't understand.  You cannot build anything without the kernel UAPI
>> headers.
> 
> I think we have to freeze the kernel headers along a distribution
> release branch, and update them only insofar we backport things to
> this distribution release branch.
> 
> My proposal aims to avoid a build order depedency between the
> backports landing in the distribution kernel, and a glibc rebuild.
> For point releases, glibc and kernel may be developed on different
> schedules, and if the glibc build uses my proposed patch, it can use
> the upstream system call list as a superset of what's going to be
> backportable for the next point release.
 
We never reached consensus on this thread.

I'm including Joseph here because he often does the Linux upstream
updates and will have an opinion here on this dependency.

Patch is here:
https://sourceware.org/ml/libc-alpha/2017-04/msg00082.html

Restating the problem:
=====================

The current glibc builds have a dependency on recent kernel headers
in order to generate an updated bits/syscall.h.

This means downstream distributions need a frozen kernel headers
package *before* glibc can be built.

In many downstream distributions this is not the case, glibc is built
and frozen for a release, and then the kernel is finally built. This
means that new syscalls may not appear in bits/syscall.h unless glibc
is rebuilt with the newer kernel's headers.

In theory the UAPI headers from the latest GA kernel could be used and
that would solve this problem, but now you are *forcing* downstream
distributions to adopt these new UAPI headers, and any consequences they
bring.

Alternatively you could patch old UAPI headers with the backported
syscalls, but the distro might not know exactly what will bi included in
the kernel release until after glibc is built. Again a coordination and
compilation ordering problem.

In order to give flexibility to downstream distributions *and* decouple
the glibc build from the kernel's syscall list, the patch proposes the
following:

- That glibc maintain an arch-independent syscall list.

- That glibc use that list to generate bits/syscall.h.

This releases downstream distros from having to use the latest UAPI
headers, and still gives them the flexibility to build glibc before
the kernel or kernel headers are built.

Consensus
=========

This issue has come up again in the downstream distributions that
I support.

Andreas,

My summary of your position is this:

* Patch the kernel headers package first, then build glibc, and you
  won't have this problem.

This position presupposes:

* A kernel to create the kernel headers package, but such a kernel
  may not be ready when you freeze glibc early for distro testing.

or

* Use the upstream kernel. Which may break other things with poorly
  tested UAPI header changes.

Your suggestion, while being valid, excludes other downstream
development models. The only thing that really matters here is
that we can generate bits/syscall.h without needing to have all
the other kernel stuff ready.

Florian,

Your position is this:

* Having glibc contain a syscall list decouples glibc's syscall.h
  generation from the kernel. This means distributions can more flexibly
  adopt build orders, and updates that meet their requirements.

Andreas, Florian,

Do we have any strong technical objection to this patch?

For example, is this duplication of a syscall list mean that we need to
keep it up to date in glibc? Yes, just like we keep all the other kernel
stuff up to date when we update from released kernels.

In fact I believe this list will be one day replaced with a unified
linux syscall data file that we can use to generate the syscall wrappers
from, and which other packages will also use [1].

In summary:

Andreas: Do you have a sustained opposition to decoupling glibc from the
         need to have an updated kernel headers in order to generate an
         updated bits/syscall.h?

Pro: Allows downstream distributions the flexibility to order their builds
     as they need to. Doesn't require them to use upstream linux kernel
     headers.

Cons: Glibc has to maintain a global list of syscalls, along with all the
      other kernel pieces it maintains.

Comments?
Joseph Myers Aug. 24, 2017, 3:15 p.m. | #37
I do not object to bounding the SYS_* API exported by glibc to a set of 
system calls known to that glibc version.

I do object to having a test we know will fail when someone builds glibc 
with a newer set of kernel headers than that version of glibc.  That is, I 
think the test should allow extra __NR_* if the kernel headers have a 
newer (major.minor) version number than the kernel version listed in 
syscall-names.list.  That way, the test is still effective in development 
as long as people update the kernel number when adding syscalls to the 
file or doing other new-kernel-version updates, without causing spurious 
failures for people building past release versions / branches of glibc.

I'd expect LC_ALL=C to have to be set when running the various awk scripts 
(at least those depending in any way on the ordering of the syscall list).
Carlos O'Donell Aug. 24, 2017, 4:08 p.m. | #38
On 08/24/2017 11:15 AM, Joseph Myers wrote:
> I do not object to bounding the SYS_* API exported by glibc to a set of 
> system calls known to that glibc version.

Thanks for your input.

> I do object to having a test we know will fail when someone builds glibc 
> with a newer set of kernel headers than that version of glibc.  That is, I 
> think the test should allow extra __NR_* if the kernel headers have a 
> newer (major.minor) version number than the kernel version listed in 
> syscall-names.list.  That way, the test is still effective in development 
> as long as people update the kernel number when adding syscalls to the 
> file or doing other new-kernel-version updates, without causing spurious 
> failures for people building past release versions / branches of glibc.

This is a valuable comment. I agree, that sounds like a good position.

> I'd expect LC_ALL=C to have to be set when running the various awk scripts 
> (at least those depending in any way on the ordering of the syscall list).

OK.

I am interested in hearing Andreas' position, and if my clarification
made our distro position clearer, and if he objects to the change.
Florian Weimer Aug. 24, 2017, 6:48 p.m. | #39
* Joseph Myers:

> I do not object to bounding the SYS_* API exported by glibc to a set of 
> system calls known to that glibc version.
>
> I do object to having a test we know will fail when someone builds glibc 
> with a newer set of kernel headers than that version of glibc.  That is, I 
> think the test should allow extra __NR_* if the kernel headers have a 
> newer (major.minor) version number than the kernel version listed in 
> syscall-names.list.  That way, the test is still effective in development 
> as long as people update the kernel number when adding syscalls to the 
> file or doing other new-kernel-version updates, without causing spurious 
> failures for people building past release versions / branches of glibc.

Hmm.  The way the patch currently works, a missing built-in system
call name is actually a user-visible bug because they won't get the
SYS_* macro they expect (based on the kernel headers).  This is why I
made it a test failure.

If we don't want that, I need to resurrect the old magic list
generation and use its results to augment the built-in list.  The test
can remain as-is, but it will no longer fail.

A compromise would be to assume that for mixed-mode architectures
(e.g., i386/x86-64/x32), the set of missing system calls is the same
across all architectures, then we could still leave out the
complicated list generation logic.

> I'd expect LC_ALL=C to have to be set when running the various awk scripts 
> (at least those depending in any way on the ordering of the syscall list).

Right, that needs to be fixed.
Joseph Myers Aug. 24, 2017, 8:28 p.m. | #40
On Thu, 24 Aug 2017, Florian Weimer wrote:

> * Joseph Myers:
> 
> > I do not object to bounding the SYS_* API exported by glibc to a set of 
> > system calls known to that glibc version.
> >
> > I do object to having a test we know will fail when someone builds glibc 
> > with a newer set of kernel headers than that version of glibc.  That is, I 
> > think the test should allow extra __NR_* if the kernel headers have a 
> > newer (major.minor) version number than the kernel version listed in 
> > syscall-names.list.  That way, the test is still effective in development 
> > as long as people update the kernel number when adding syscalls to the 
> > file or doing other new-kernel-version updates, without causing spurious 
> > failures for people building past release versions / branches of glibc.
> 
> Hmm.  The way the patch currently works, a missing built-in system
> call name is actually a user-visible bug because they won't get the
> SYS_* macro they expect (based on the kernel headers).  This is why I
> made it a test failure.

I don't see it as a user-visible bug - I see it as a deliberate change of 
the SYS_* API from "what's in the kernel headers with which glibc was 
built" to "what syscalls the glibc source tree knows about that are also 
in the kernel headers with which glibc is used".

> If we don't want that, I need to resurrect the old magic list
> generation and use its results to augment the built-in list.  The test
> can remain as-is, but it will no longer fail.

I think a key benefit of the patch is that it gets rid of that magic list 
generation.

Patch

<bits/syscall.h>: Use an arch-independent system call list on Linux

This commit changes the way the list of SYS_* system call macros
is created on Linux.  glibc now contains a list of all known system
calls, and the generated <bits/syscall.h> file defines the SYS_
macro only if the correspnding __NR_ macro is defined by the kernel
headers.

As a result, there glibc does not have to be rebuilt to pick up
system calls if the glibc sources already know about them.  This
means that glibc can be built with older kernel headers, and if
the installed kernel headers are upgraded afterwards, additional
SYS_ macros become available as long as glibc has a record for
those system calls.

2017-04-05  Florian Weimer  <fweimer@redhat.com>

	Store supported list of SYS_* system calls in the source tree.
	* sysdeps/unix/sysv/linux/Makefile (bits/syscall.h): Generate from
	list file.
	[$(subdir) = misc] (tests): Add tst-syscall-list.
	[$(subdir) = misc] (tests-special): Add tst-syscall-list.out
	[$(subdir) = misc] (tst-syscall-list-macros.list)
	(tst-syscall-list-nr.list, tst-syscall-list-sys.list): Helper
	targets for new tst-syscall-list test.
	(tst-syscall-list.out): Run test script tst-syscall-list.sh.
	* sysdeps/unix/sysv/linux/syscall-names.list: New file.
	* sysdeps/unix/sysv/linux/gen-syscall-h.awk: Likewise.
	* sysdeps/unix/sysv/linux/filter-nr-syscalls.awk: Likewise.
	* sysdeps/unix/sysv/linux/tst-syscall-list.sh: Likewise.

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 1872cdb..5573c4e 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -45,75 +45,46 @@  sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 tests += tst-clone tst-clone2 tst-fanotify tst-personality tst-quota \
 	 tst-sync_file_range test-errno-linux
 
-# Generate the list of SYS_* macros for the system calls (__NR_* macros).
+# Generate the list of SYS_* macros for the system calls (__NR_*
+# macros).  The file syscall-names.list contains all possible system
+# call names, and the generated header file produces SYS_* macros for
+# the __NR_* macros which are actually defined.
 
-# If there is more than one syscall list for different architecture
-# variants, the CPU/Makefile defines abi-variants to be a list of names
-# for those variants (e.g. 32 64), and, for each variant, defines
-# abi-$(variant)-options to be compiler options to cause <asm/unistd.h>
-# to define the desired list of syscalls and abi-$(variant)-condition to
-# be the condition for those options to use in a C #if condition.
-# abi-includes may be defined to a list of headers to include
-# in the generated header, if the default does not suffice.
-#
-# The generated header is compiled with `-ffreestanding' to avoid any
-# circular dependencies against the installed implementation headers.
-# Such a dependency would require the implementation header to be
-# installed before the generated header could be built (See bug 15711).
-# In current practice the generated header dependencies do not include
-# any of the implementation headers removed by the use of `-ffreestanding'.
-
-$(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/syscall.h
+generated += bits/syscall.h
+$(objpfx)bits/syscall.h: \
+  ../sysdeps/unix/sysv/linux/gen-syscall-h.awk \
+  ../sysdeps/unix/sysv/linux/syscall-names.list
 	$(make-target-directory)
-	{ \
-	 echo '/* Generated at libc build time from kernel syscall list.  */';\
-	 echo ''; \
-	 echo '#ifndef _SYSCALL_H'; \
-	 echo '# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."'; \
-	 echo '#endif'; \
-	 echo ''; \
-	 $(foreach h,$(abi-includes), echo '#include <$(h)>';) \
-	 echo ''; \
-	 $(if $(abi-variants), \
-	 $(foreach v,$(abi-variants),\
-	 $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
-	       -x c $(sysincludes) $< $(abi-$(v)-options) \
-	       -D_LIBC -dM | \
-	 sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
-	 LC_ALL=C sort > $(@:.d=.h).new$(v); \
-	 $(if $(abi-$(v)-condition),\
-	 echo '#if $(abi-$(v)-condition)';) \
-	 cat $(@:.d=.h).new$(v); \
-	 $(if $(abi-$(v)-condition),echo '#endif';) \
-	 rm -f $(@:.d=.h).new$(v); \
-	 ), \
-	 $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \
-	       -x c $(sysincludes) $< \
-	       -D_LIBC -dM | \
-	 sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \
-	 LC_ALL=C sort;) \
-	} > $(@:.d=.h).new
-	mv -f $(@:.d=.h).new $(@:.d=.h)
-ifdef abi-variants
-ifneq (,$(objpfx))
-	sed $(sed-remove-objpfx) \
-	 $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) > $(@:.h=.d)-t3
-else
-	cat $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) \
-	 > $(@:.h=.d)-t3
-endif
-	rm -f $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v))
-	mv -f $(@:.h=.d)-t3 $(@:.h=.d)
-else
-	mv -f $(@:.h=.d)-t $(@:.h=.d)
-endif
+	$(AWK) -f $^ > $@-tmp
+	$(move-if-change) $@-tmp $@
 
-ifndef no_deps
-# Get the generated list of dependencies (probably /usr/include/asm/unistd.h).
--include $(objpfx)bits/syscall.d
-endif
-generated += bits/syscall.h bits/syscall.d
-endif
+# All macros defined by <sys/syscall.h>.  Include <bits/syscall.h>
+# explicitly because <sys/sycall.h> skips it if _LIBC is defined.
+$(objpfx)tst-syscall-list-macros.list: \
+  $(objpfx)bits/syscall.h ../sysdeps/unix/sysv/linux/sys/syscall.h
+	printf '#include <sys/syscall.h>\n#include <bits/syscall.h>\n' | \
+	  $(CC) -E -o $@-tmp $(CFLAGS) $(CPPFLAGS) -x c - -dM
+	$(move-if-change) $@-tmp $@
+
+# __NR_* system call names.  Used by the test below.
+$(objpfx)tst-syscall-list-nr.list: \
+  ../sysdeps/unix/sysv/linux/filter-nr-syscalls.awk \
+  $(objpfx)tst-syscall-list-macros.list
+	$(AWK) -f $^ > $@-tmp
+	$(move-if-change) $@-tmp $@
+
+# SYS_* system call names.  Used by the test below.
+$(objpfx)tst-syscall-list-sys.list: $(objpfx)tst-syscall-list-macros.list
+	$(AWK) '/^#define SYS_/ { print substr($$2, 5) }' $< > $@-tmp
+	$(move-if-change) $@-tmp $@
+
+tests-special += $(objpfx)tst-syscall-list.out
+$(objpfx)tst-syscall-list.out: \
+  ../sysdeps/unix/sysv/linux/tst-syscall-list.sh \
+  $(objpfx)tst-syscall-list-nr.list $(objpfx)tst-syscall-list-sys.list
+	$(BASH) $^ > $@; $(evaluate-test)
+
+endif # $(subdir) == misc
 
 ifeq ($(subdir),time)
 sysdep_headers += sys/timex.h bits/timex.h
diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
new file mode 100644
index 0000000..15b052a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk
@@ -0,0 +1,35 @@ 
+# Filter preprocessor __NR_* macros and extract system call names.
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# Skip reserved system calls.
+/^#define __NR_(unused|reserved)[0-9]+ / {
+    next;
+}
+
+# Skip pseudo-system calls which describe ranges.
+/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / {
+    next;
+}
+/^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / {
+    next;
+}
+
+# Print the remaining _NR_* macros as system call names.
+/^#define __NR_/ {
+    print substr($2, 6);
+}
diff --git a/sysdeps/unix/sysv/linux/gen-syscall-h.awk b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
new file mode 100644
index 0000000..0a27b3c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/gen-syscall-h.awk
@@ -0,0 +1,75 @@ 
+# Generate SYS_* macros from a list in a text file.
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# Emit a conditional definition for SYS_NAME.
+function emit(name) {
+    print "#ifdef __NR_" name;
+    print "# define SYS_" name " __NR_" name;
+    print "#endif";
+    print "";
+}
+
+# Bail out with an error.
+function fatal(message) {
+    print FILENAME ":" FNR ": " message > "/dev/stderr";
+    exit 1;
+}
+
+BEGIN {
+    name = "";
+    kernel = "";
+}
+
+# Skip empty lines and comments.
+/^\s*(|#.*)$/ {
+    next;
+}
+
+# Kernel version.  Used for documentation purposes only.
+/^kernel [0-9.]+$/ {
+    if (kernel != "") {
+        fatal("duplicate kernel directive");
+    }
+    kernel = $2;
+    print "/* Generated at libc build time from syscall list.  */";
+    print "/* The system call list corresponds to kernel " kernel ".  */";
+    print "";
+    print "#ifndef _SYSCALL_H"
+    print "# error \"Never use <bits/syscall.h> directly; include <sys/syscall.h> instead.\"";
+    print "#endif";
+    print "";
+    next;
+}
+
+# If there is just one word, it is a system call.
+/^[a-zA-Z_][a-zA-Z0-9_]+$/ {
+    if (kernel == "") {
+        fatal("expected kernel directive before this line");
+    }
+    if ($1 <= name) {
+        fatal("name " name " violates ordering");
+    }
+    emit($1);
+    name = $1;
+    next;
+}
+
+# The rest has to be syntax errors.
+// {
+    fatal("unrecognized syntax");
+}
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
new file mode 100644
index 0000000..9a47755
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -0,0 +1,594 @@ 
+# List of all known Linux system calls.
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# This file contains the list of system call names names.  It has to
+# remain in alphabetica order.  Lines which start with # are treated
+# as comments.  This file can list all potential system calls.  The
+# names are only used if the installed kernel headers also provide
+# them.
+
+# The list of system calls is current as of Linux 4.10.
+kernel 4.10
+
+FAST_atomic_update
+FAST_cmpxchg
+FAST_cmpxchg64
+_llseek
+_newselect
+_sysctl
+accept
+accept4
+access
+acct
+add_key
+adjtimex
+afs_syscall
+alarm
+arch_prctl
+arm_fadvise64_64
+arm_sync_file_range
+atomic_barrier
+atomic_cmpxchg_32
+bdflush
+bind
+bpf
+break
+brk
+cachectl
+cacheflush
+capget
+capset
+chdir
+chmod
+chown
+chown32
+chroot
+clock_adjtime
+clock_getres
+clock_gettime
+clock_nanosleep
+clock_settime
+clone
+clone2
+close
+cmpxchg_badaddr
+connect
+copy_file_range
+creat
+create_module
+delete_module
+dipc
+dup
+dup2
+dup3
+epoll_create
+epoll_create1
+epoll_ctl
+epoll_ctl_old
+epoll_pwait
+epoll_wait
+epoll_wait_old
+eventfd
+eventfd2
+exec_with_loader
+execv
+execve
+execveat
+exit
+exit_group
+faccessat
+fadvise64
+fadvise64_64
+fallocate
+fanotify_init
+fanotify_mark
+fchdir
+fchmod
+fchmodat
+fchown
+fchown32
+fchownat
+fcntl
+fcntl64
+fdatasync
+fgetxattr
+finit_module
+flistxattr
+flock
+fork
+fremovexattr
+fsetxattr
+fstat
+fstat64
+fstatat64
+fstatfs
+fstatfs64
+fsync
+ftime
+ftruncate
+ftruncate64
+futex
+futimesat
+get_kernel_syms
+get_mempolicy
+get_robust_list
+get_thread_area
+getcpu
+getcwd
+getdents
+getdents64
+getdomainname
+getdtablesize
+getegid
+getegid32
+geteuid
+geteuid32
+getgid
+getgid32
+getgroups
+getgroups32
+gethostname
+getitimer
+getpagesize
+getpeername
+getpgid
+getpgrp
+getpid
+getpmsg
+getppid
+getpriority
+getrandom
+getresgid
+getresgid32
+getresuid
+getresuid32
+getrlimit
+getrusage
+getsid
+getsockname
+getsockopt
+gettid
+gettimeofday
+getuid
+getuid32
+getunwind
+getxattr
+getxgid
+getxpid
+getxuid
+gtty
+idle
+init_module
+inotify_add_watch
+inotify_init
+inotify_init1
+inotify_rm_watch
+io_cancel
+io_destroy
+io_getevents
+io_setup
+io_submit
+ioctl
+ioperm
+iopl
+ioprio_get
+ioprio_set
+ipc
+kcmp
+kern_features
+kexec_file_load
+kexec_load
+keyctl
+kill
+lchown
+lchown32
+lgetxattr
+link
+linkat
+listen
+listxattr
+llistxattr
+llseek
+lock
+lookup_dcookie
+lremovexattr
+lseek
+lsetxattr
+lstat
+lstat64
+madvise
+mbind
+membarrier
+memfd_create
+memory_ordering
+migrate_pages
+mincore
+mkdir
+mkdirat
+mknod
+mknodat
+mlock
+mlock2
+mlockall
+mmap
+mmap2
+modify_ldt
+mount
+move_pages
+mprotect
+mpx
+mq_getsetattr
+mq_notify
+mq_open
+mq_timedreceive
+mq_timedsend
+mq_unlink
+mremap
+msgctl
+msgget
+msgrcv
+msgsnd
+msync
+multiplexer
+munlock
+munlockall
+munmap
+name_to_handle_at
+nanosleep
+newfstatat
+nfsservctl
+ni_syscall
+nice
+old_adjtimex
+oldfstat
+oldlstat
+oldolduname
+oldstat
+oldumount
+olduname
+open
+open_by_handle_at
+openat
+osf_adjtime
+osf_afs_syscall
+osf_alt_plock
+osf_alt_setsid
+osf_alt_sigpending
+osf_asynch_daemon
+osf_audcntl
+osf_audgen
+osf_chflags
+osf_execve
+osf_exportfs
+osf_fchflags
+osf_fdatasync
+osf_fpathconf
+osf_fstat
+osf_fstatfs
+osf_fstatfs64
+osf_fuser
+osf_getaddressconf
+osf_getdirentries
+osf_getdomainname
+osf_getfh
+osf_getfsstat
+osf_gethostid
+osf_getitimer
+osf_getlogin
+osf_getmnt
+osf_getrusage
+osf_getsysinfo
+osf_gettimeofday
+osf_kloadcall
+osf_kmodcall
+osf_lstat
+osf_memcntl
+osf_mincore
+osf_mount
+osf_mremap
+osf_msfs_syscall
+osf_msleep
+osf_mvalid
+osf_mwakeup
+osf_naccept
+osf_nfssvc
+osf_ngetpeername
+osf_ngetsockname
+osf_nrecvfrom
+osf_nrecvmsg
+osf_nsendmsg
+osf_ntp_adjtime
+osf_ntp_gettime
+osf_old_creat
+osf_old_fstat
+osf_old_getpgrp
+osf_old_killpg
+osf_old_lstat
+osf_old_open
+osf_old_sigaction
+osf_old_sigblock
+osf_old_sigreturn
+osf_old_sigsetmask
+osf_old_sigvec
+osf_old_stat
+osf_old_vadvise
+osf_old_vtrace
+osf_old_wait
+osf_oldquota
+osf_pathconf
+osf_pid_block
+osf_pid_unblock
+osf_plock
+osf_priocntlset
+osf_profil
+osf_proplist_syscall
+osf_reboot
+osf_revoke
+osf_sbrk
+osf_security
+osf_select
+osf_set_program_attributes
+osf_set_speculative
+osf_sethostid
+osf_setitimer
+osf_setlogin
+osf_setsysinfo
+osf_settimeofday
+osf_shmat
+osf_signal
+osf_sigprocmask
+osf_sigsendset
+osf_sigstack
+osf_sigwaitprim
+osf_sstk
+osf_stat
+osf_statfs
+osf_statfs64
+osf_subsys_info
+osf_swapctl
+osf_swapon
+osf_syscall
+osf_sysinfo
+osf_table
+osf_uadmin
+osf_usleep_thread
+osf_uswitch
+osf_utc_adjtime
+osf_utc_gettime
+osf_utimes
+osf_utsname
+osf_wait4
+osf_waitid
+pause
+pciconfig_iobase
+pciconfig_read
+pciconfig_write
+perf_event_open
+perfctr
+perfmonctl
+personality
+pipe
+pipe2
+pivot_root
+pkey_alloc
+pkey_free
+pkey_mprotect
+poll
+ppoll
+prctl
+pread64
+preadv
+preadv2
+prlimit64
+process_vm_readv
+process_vm_writev
+prof
+profil
+pselect6
+ptrace
+putpmsg
+pwrite64
+pwritev
+pwritev2
+query_module
+quotactl
+read
+readahead
+readdir
+readlink
+readlinkat
+readv
+reboot
+recv
+recvfrom
+recvmmsg
+recvmsg
+remap_file_pages
+removexattr
+rename
+renameat
+renameat2
+request_key
+restart_syscall
+rmdir
+rt_sigaction
+rt_sigpending
+rt_sigprocmask
+rt_sigqueueinfo
+rt_sigreturn
+rt_sigsuspend
+rt_sigtimedwait
+rt_tgsigqueueinfo
+rtas
+s390_pci_mmio_read
+s390_pci_mmio_write
+s390_runtime_instr
+sched_get_affinity
+sched_get_priority_max
+sched_get_priority_min
+sched_getaffinity
+sched_getattr
+sched_getparam
+sched_getscheduler
+sched_rr_get_interval
+sched_set_affinity
+sched_setaffinity
+sched_setattr
+sched_setparam
+sched_setscheduler
+sched_yield
+seccomp
+security
+select
+semctl
+semget
+semop
+semtimedop
+send
+sendfile
+sendfile64
+sendmmsg
+sendmsg
+sendto
+set_mempolicy
+set_robust_list
+set_thread_area
+set_tid_address
+setdomainname
+setfsgid
+setfsgid32
+setfsuid
+setfsuid32
+setgid
+setgid32
+setgroups
+setgroups32
+sethae
+sethostname
+setitimer
+setns
+setpgid
+setpgrp
+setpriority
+setregid
+setregid32
+setresgid
+setresgid32
+setresuid
+setresuid32
+setreuid
+setreuid32
+setrlimit
+setsid
+setsockopt
+settimeofday
+setuid
+setuid32
+setxattr
+sgetmask
+shmat
+shmctl
+shmdt
+shmget
+shutdown
+sigaction
+sigaltstack
+signal
+signalfd
+signalfd4
+sigpending
+sigprocmask
+sigreturn
+sigsuspend
+socket
+socketcall
+socketpair
+splice
+spu_create
+spu_run
+ssetmask
+stat
+stat64
+statfs
+statfs64
+stime
+stty
+subpage_prot
+swapcontext
+swapoff
+swapon
+switch_endian
+symlink
+symlinkat
+sync
+sync_file_range
+sync_file_range2
+syncfs
+sys_debug_setcontext
+sys_epoll_create
+sys_epoll_ctl
+sys_epoll_wait
+syscall
+sysfs
+sysinfo
+syslog
+sysmips
+tee
+tgkill
+time
+timer_create
+timer_delete
+timer_getoverrun
+timer_gettime
+timer_settime
+timerfd
+timerfd_create
+timerfd_gettime
+timerfd_settime
+times
+tkill
+truncate
+truncate64
+tuxcall
+ugetrlimit
+ulimit
+umask
+umount
+umount2
+uname
+unlink
+unlinkat
+unshare
+uselib
+userfaultfd
+ustat
+utime
+utimensat
+utimes
+utrap_install
+vfork
+vhangup
+vm86
+vm86old
+vmsplice
+vserver
+wait4
+waitid
+waitpid
+write
+writev
diff --git a/sysdeps/unix/sysv/linux/tst-syscall-list.sh b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
new file mode 100644
index 0000000..f48b7cd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-syscall-list.sh
@@ -0,0 +1,72 @@ 
+#!/bin/bash
+# Consistency checks for the system call list
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+export LC_ALL=C
+set -e
+set -o pipefail
+
+if test $# != 2 ; then
+    echo "error: wrong number of arguments: $#"
+    exit 1
+fi
+
+list_nr="$1"
+list_sys="$2"
+
+errors=0
+
+# Use getpid as a system call which is expected to be always defined.
+# alpha uses getxpid instead, so it is permitted as an alternative.
+if ! grep -E -q '^getx?pid$' -- "$list_nr" ; then
+    echo "error: __NR_getpid not defined"
+    errors=1
+fi
+if ! grep -E -q '^getx?pid$' -- "$list_sys" ; then
+    echo "error: SYS_getpid not defined"
+    errors=1
+fi
+
+comm_1="$(mktemp)"
+comm_2="$(mktemp)"
+comm_result="$(mktemp)"
+cleanup () {
+    rm -f -- "$comm_1" "$comm_2" "$comm_result"
+}
+trap cleanup 0
+
+sort -o "$comm_1" -- "$list_nr"
+sort -o "$comm_2" -- "$list_sys"
+
+# Check for missing SYS_* macros.
+comm --check-order -2 -3 -- "$comm_1" "$comm_2" > "$comm_result"
+if test -s "$comm_result"; then
+    echo "error: These system calls need to be added to syscall-names.list:"
+    cat -- "$comm_result"
+    errors=1
+fi
+
+# Check for additional SYS_* macros.
+comm --check-order -1 -3 -- "$comm_1" "$comm_2" > "$comm_result"
+if test -s "$comm_result"; then
+    echo "error: The following system calls have unexpected SYS_* macros:"
+    cat -- "$comm_result"
+    errors=1
+fi
+
+exit "$errors"