Header files and the kernel ABI
OK... I have had a thought grinding in my head for a while, and wanted to throw it out for everyone to think about...
In the libc4/libc5 days, we attempted to use kernel headers in user space. This was a total mess, not the least because the kernel headers tended to pull in a lot of other kernel headers, and the datatypes were unsuitable to have spead all across userspace.
In glibc, the official rule is "don't use kernel headers." This causes problems, because certain aspects of the kernel ABI is only available through the include files, and reproducing them by hand is tedious and error-prone.
I'm in the process of writing a very tiny libc for initramfs, and will likely have to deal with how to use the kernel ABI as well.
It seems to me that a reasonable solution for how to do this is not for user space to use kernel headers, but for user space and the kernel to share a set of common ABI description files[1]. These files should be highly stylized, and only describe things visible to user space. Furthermore, if they introduce types, they should use the already-established __kernel_ namespace, and of course __s* and __u* could be used for specific types.
This means that we would be able to get rid of #if(n)def __KERNEL__ in the main kernel header files, because there would be a separation by file location -- something in the main kernel include files could include the ABI description files, but the opposite should never be true.
I would like to propose that these files be set up in the #include namespace as <linux/abi/*>, with <linux/abi/arch/*> for any architecture-specific support files (I do believe, however, that those files should only be included by files in the linux/abi/ root. This probably would be a symlink to ../asm/abi in the kernel sources, unless we change the kernel include layout.) The linux/ namespace is universally reserved for the kernel, and unlike <abi/*> I don't know of any potential conflicts. I was considered <kabi/*>, but it seems cleaner to use existing namespace.
If people think this is an idea, I will try to set up the infrastructure as part of my work on klibc, although I'm definitely not going to be able to migrate every portion of every include file that needs to be migrated all by myself.
Thoughts?
-hpa
[1] I'm assuming here they are C include files, just because it's a common language to everyone; however, it would be possible to create an "ABI description language" which would compile to C headers as well as perhaps other formats (assembly language support files?), ...)
Signature · 3 lines
<[email protected]> at work, <[email protected]> in private! "Unix gives you enough rope to shoot yourself in the foot." http://www.zytor.com/~hpa/puzzle.txt <[email protected]>
Quoted 8 lines · H. Peter Anvin
It seems to me that a reasonable solution for how to do this is not for user space to use kernel headers, but for user space and the kernel to share a set of common ABI description files[1]. These files should be highly stylized, and only describe things visible to user space. Furthermore, if they introduce types, they should use the already-established
__kernel_namespace, and of course __s* and __u* could be used for specific types.
Quoted 9 lines
I would like to propose that these files be set up in the #include namespace as <linux/abi/*>, with <linux/abi/arch/*> for any architecture-specific support files (I do believe, however, that those files should only be included by files in the linux/abi/ root. This probably would be a symlink to ../asm/abi in the kernel sources, unless we change the kernel include layout.) The linux/ namespace is universally reserved for the kernel, and unlike <abi/*> I don't know of any potential conflicts. I was considered <kabi/*>, but it seems cleaner to use existing namespace.
I had thought on this briefly in the past, and my take would be for these ABI definition files to live directly in /usr/include/linux for user space (just as glibc puts its own sanitized copy of the kernel headers there) and the appropriate ABI headers are included as needed from the kernel.
The kernel side would be something like <linux/scsi.h> includes <linux/abi/scsi.h> or whatever, but in the future this can be included directly as needed throughout the kernel. The existing kernel <linux/*.h> headers would also have extra kernel-specific data in them.
The same could be done with the user-space headers, but I think that is missing the point that the linux/abi/*.h headers should define _all_ of the abi, so we may as well just use that directly.
Essentially "all" this would mean is that we take the existing headers, remove everything which is inside #ifdef __KERNEL__ (and all of the other kernel-specific non-abi headers that are included) and we are done. The kernel header now holds only things that were inside the #ifdef __KERNEL__ (or should have been), and #include <linux/abi/foo.h>.
Cheers, Andreas
--
Andreas Dilger
http://www-mddsp.enel.ucalgary.ca/People/adilger/
http://sourceforge.net/projects/ext2resize/
Quoted 6 lines · Andreas Dilger
I had thought on this briefly in the past, and my take would be for these ABI definition files to live directly in
/usr/include/linuxfor user space (just as glibc puts its own sanitized copy of the kernel headers there) and the appropriate ABI headers are included as needed from the kernel.
Given no legacy, I would agree with this, but I think it would imply bad legacy both on the kernel and the libc (it's not just glibc, either) side.
Quoted 8 lines
The kernel side would be something like <
linux/scsi.h> includes <linux/abi/scsi.h> or whatever, but in the future this can be included directly as needed throughout the kernel. The existing kernel <linux/*.h> headers would also have extra kernel-specific data in them.The same could be done with the user-space headers, but I think that is missing the point that the linux/abi/*.h headers should define _all_ of the abi, so we may as well just use that directly.
Except now the paths are gratuitously different between kernel programming and non-kernel programming, and we create a much harder migration problem. I'd rather leave the linux/* namespace to the user-space libc to do whatever backwards compatibility cruft they may consider necessary, for example, <linux/io.h> might #include <sys/io.h> since some user space apps bogusly included the former name. Leaving that namespace available for backwards compatibility hacks avoids those kinds of problems.
Quoted 5 lines
Essentially "all" this would mean is that we take the existing headers, remove everything which is inside #ifdef
__KERNEL__(and all of the other kernel-specific non-abi headers that are included) and we are done. The kernel header now holds only things that were inside the #ifdef__KERNEL__(or should have been), and #include <linux/abi/foo.h>.
Exactly.
-hpa
Quoted 10 lines · H. Peter Anvin
Quoted 8 lines · Andreas Dilger
The kernel side would be something like <
linux/scsi.h> includes <linux/abi/scsi.h> or whatever, but in the future this can be included directly as needed throughout the kernel. The existing kernel <linux/*.h> headers would also have extra kernel-specific data in them.The same could be done with the user-space headers, but I think that is missing the point that the linux/abi/*.h headers should define _all_ of the abi, so we may as well just use that directly.
Quoted 8 lines
Except now the paths are gratuitously different between kernel programming and non-kernel programming, and we create a much harder migration problem. I'd rather leave the linux/* namespace to the user-space libc to do whatever backwards compatibility cruft they may consider necessary, for example, <
linux/io.h> might #include <sys/io.h> since some user space apps bogusly included the former name. Leaving that namespace available for backwards compatibility hacks avoids those kinds of problems.
OK, but essentially then <linux/io.h> will be mostly a hollow shell which includes <linux/abi/io.h> and maybe a couple other files (e.g. <linux/abi/types.h> or similar). If so, then great.
That brings up the question - how do you tie a particular <linux/abi/*.h> to a particular kernel? Should there be a bunch of directories <linux/abi-2.4/*.h> and/or <linux/abi-2.4.12/*.h> and/or <linux/abi-uname -r/*.h> or what? While there are efforts to keep the ABI constant for major stable releases, this is not always true, so abi-2.4 will certainly not be enough. Maybe linux/abi is a symlink to the abi directory of currently running kernel?
Cheers, Andreas
--
Andreas Dilger
http://www-mddsp.enel.ucalgary.ca/People/adilger/
http://sourceforge.net/projects/ext2resize/
Quoted 7 lines · Andreas Dilger
That brings up the question - how do you tie a particular <linux/abi/*.h> to a particular kernel? Should there be a bunch of directories <linux/abi-2.4/*.h> and/or <linux/abi-2.4.12/*.h> and/or <linux/abi-
uname -r/*.h> or what? While there are efforts to keep the ABI constant for major stable releases, this is not always true, so abi-2.4 will certainly not be enough. Maybe linux/abi is a symlink to the abi directory of currently running kernel?
Ideally, the ABI layer would be maintained and packaged separately from both the kernel and glibc to avoid gratuitous changes from either side.
Signature · 1 line
"Love the dolphins," she advised him. "Write by W.A.S.T.E.."
Quoted 4 lines · Oliver Xymoron
Ideally, the ABI layer would be maintained and packaged separately from both the kernel and glibc to avoid gratuitous changes from either side.
I disagree. The ABI is a product of the kernel and should be attached to it. It is *not* a product of glibc -- glibc is a consumer of it, as are any other libcs.
-hpa
Quoted 9 lines · H. Peter Anvin
Quoted 4 lines · Oliver Xymoron
Ideally, the ABI layer would be maintained and packaged separately from both the kernel and glibc to avoid gratuitous changes from either side.
I disagree. The ABI is a product of the kernel and should be attached to it. It is *not* a product of glibc -- glibc is a consumer of it, as are any other libcs.
Agreed. I maintain a libc and I certainly do not want to have to maintain the kernel ABI of the day headers. That is clearly a job for the kernel.
-Erik
--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--
Quoted 7 lines · Erik Andersen
Quoted 6 lines · H. Peter Anvin
Quoted 4 lines · Oliver Xymoron
Ideally, the ABI layer would be maintained and packaged separately from both the kernel and glibc to avoid gratuitous changes from either side.
Quoted 7 lines
Quoted 3 lines
I disagree. The ABI is a product of the kernel and should be attached to it. It is *not* a product of glibc -- glibc is a consumer of it, as are any other libcs.
Agreed. I maintain a libc and I certainly do not want to have to maintain the kernel ABI of the day headers. That is clearly a job for the kernel.
The idea of maintaining them separately is that people won't be able to touch the ABI without explicitly going through a gatekeeper whose job is to minimize breakage. Linus usually catches ABI changes but not always.
I explicitly did _not_ suggest making it the job of libc maintainers. And the whole point of the exercise is to avoid ABI of the day anyway. The ABI should change less frequently than the kernel or libc. It's more analogous to something like modutils.
Signature · 1 line
"Love the dolphins," she advised him. "Write by W.A.S.T.E.."
Quoted 9 lines · Oliver Xymoron
The idea of maintaining them separately is that people won't be able to touch the ABI without explicitly going through a gatekeeper whose job is to minimize breakage. Linus usually catches ABI changes but not always.
I explicitly did _not_ suggest making it the job of libc maintainers. And the whole point of the exercise is to avoid ABI of the day anyway. The ABI should change less frequently than the kernel or libc. It's more analogous to something like modutils.
Except for ioctls. Until we can get those under control the abi headers need to remain part of the kernel. Gatekeeping on the ioctls is something we need.
And even if the code is part of the kernel, Linus can still delegate the work of verifying it he wants.
Eric
Quoted 9 lines · Andreas Dilger
That brings up the question - how do you tie a particular <linux/abi/*.h> to a particular kernel? Should there be a bunch of directories <linux/abi-2.4/*.h> and/or <linux/abi-2.4.12/*.h> and/or <linux/abi-
uname -r/*.h> or what? While there are efforts to keep the ABI constant for major stable releases, this is not always true, so abi-2.4 will certainly not be enough. Maybe linux/abi is a symlink to the abi directory of currently running kernel?
Well... I guess that depends on what kind of changes we make. In general, I belive linux/abi should be cumulative, i.e. it should describe "sys_stat" as well as "sys_oldstat" or whatever it is called. ABI changes are hard to deal with regardless; you never really know what you're breaking, and you probably have to deal with it on a case-by-case basis. People should at least understand that they're breaking the ABI, which I'm not sure they currently are.
In general I believe linux/abi should come from the current kernel, but for obvious reasons that doesn't mean it's the kernel that's running when the application is actually being executed. This sort of things apply to all ABI changes, inherently, which is why non-backwards-compatible ABI changes must be avoided. Ultimately, though, it's up to the person who changes it to do the appropriate thing.
-hpa
Hi HPA :)
Quoted 6 lines
I would like to propose that these files be set up in the #include namespace as <linux/abi/*>, with <linux/abi/arch/*> for any architecture-specific support files (I do believe, however, that those files should only be included by files in the linux/abi/ root. This probably would be a symlink to ../asm/abi in the kernel sources, unless we change the kernel include layout.)
I think this is a *really* great idea. It will solve lots of
problems IMHO. Now the glibc copies some of the kernel headers, and in the future it will support more, but standarizing an ABI set of headers will be better (IMHO again). Go for it ;)
Raúl
Quoted 7 lines · H. Peter Anvin
It seems to me that a reasonable solution for how to do this is not for user space to use kernel headers, but for user space and the kernel to share a set of common ABI description files[1]. These files should be highly stylized, and only describe things visible to user space. Furthermore, if they introduce types, they should use the already-established
__kernel_namespace, and of course __s* and __u* could be used for specific types.
I like it (having just argued for it), except for the __s* and __u*. The ABI definitions aren't for kernel programmers. They are for userspace programmers. So we should use standard types, even if they are a bit ugly (and uint16_t isn't really much uglier than __u16, and at least it doesn't carry connotations of something that is meant to be internal, which is what the standard double-underscore convention means).
Please, let us agree that the ABI definition should use standard types wherever possible.
Brad
Signature · 1 line
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.
Hi Brad & HPA :)
Quoted 3 lines
Quoted 2 lines
already-established
__kernel_namespace, and of course __s* and __u* could be used for specific types.I like it (having just argued for it), except for the __s* and __u*.
[...]
Quoted 2 lines
Please, let us agree that the ABI definition should use standard types wherever possible.
I think so. Moreover, any user-space developer should be familiar
with them and anyone may even use the standard ones by mistake, so it's better to get them equal and be standard.
Raúl
Quoted 8 lines · Brad Hards
I like it (having just argued for it), except for the __s* and __u*.
The ABI definitions aren't for kernel programmers. They are for userspace programmers. So we should use standard types, even if they are a bit ugly (anduint16_tisn't really much uglier
than__u16, and at least it doesn't carry connotations of
something that is meant to be internal, which is what the standard
double-underscore convention means).
Not quite -- it means they are implementation-specific (in this case, Linux-specific.) The Linux __s* and __u* predates <stdint.h>; I certainly would like to migrate to <stdint.h> but I don't see it as a very high priority.
-hpa
Quoted 11 lines · H. Peter Anvin
Quoted 9 lines · Brad Hards
I like it (having just argued for it), except for the __s* and __u*. The ABI definitions aren't for kernel programmers. They are for userspace programmers. So we should use standard types, even if they are a bit ugly (and
uint16_tisn't really much uglier than__u16, and at least it doesn't carry connotations of something that is meant to be internal, which is what the standard double-underscore convention means).
Quoted 4 lines
Not quite -- it means they are implementation-specific (in this case, Linux-specific.) The Linux __s* and __u* predates <
stdint.h>; I certainly would like to migrate to <stdint.h> but I don't see it as a very high priority.
Using stdint.h types at least in the kernel ABI headers would be a _huge_ improvement! I hate having to cut-n-paste kernel structs into my user-spave code and then rework the types so user-space code can compile things.
-Erik
--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--
Kernel ABI BoF at Linux-Kongress? [was: Header files and the kernel ABI]
In reply to H. Peter AnvinQuoted 8 lines · H. Peter Anvin
OK... I have had a thought grinding in my head for a while, and wanted to throw it out for everyone to think about...
In the libc4/libc5 days, we attempted to use kernel headers in user space. This was a total mess, not the least because the kernel headers tended to pull in a lot of other kernel headers, and the datatypes were unsuitable to have spead all across userspace.
Quoted 7 lines
In glibc, the official rule is "don't use kernel headers." This causes problems, because certain aspects of the kernel ABI is only available through the include files, and reproducing them by hand is tedious and error-prone.
I'm in the process of writing a very tiny libc for initramfs, and will likely have to deal with how to use the kernel ABI as well.
Well the initial enthusiasm appears to have passed, and nothing is happening.
Is there interest in getting together to resolve this issue?
I note that the next major conference appears to be Linux Kongress (Koln/Cologne) in early September. Maybe we can get some glibc / other-libraries people there, and make some progress.
If there is some interest (post off-list if preferred), I'll contact the organisers and try to get a BoF together for this.
I'll look at linux.conf.au as an additional opportunity when time gets a bit closer.
Signature · 1 line
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.