linux-api.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
@ 2016-11-11 12:08 Felix Janda
  2017-03-08 12:46 ` David Woodhouse
  2017-03-08 15:53 ` Carlos O'Donell
  0 siblings, 2 replies; 17+ messages in thread
From: Felix Janda @ 2016-11-11 12:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: David S. Miller, linux-api, musl

Currently, libc-compat.h detects inclusion of specific glibc headers,
and defines corresponding _UAPI_DEF_* macros, which in turn are used in
uapi headers to prevent definition of conflicting structures/constants.
There is no such detection for other c libraries, for them the
_UAPI_DEF_* macros are always defined as 1, and so none of the possibly
conflicting definitions are suppressed.

This patch enables non-glibc c libraries to request the suppression of
any specific interface by defining the corresponding _UAPI_DEF_* macro
as 0.

This patch together with the recent musl libc commit

http://git.musl-libc.org/cgit/musl/commit/?id=04983f2272382af92eb8f8838964ff944fbb8258

fixes the following compiler errors when <linux/in6.h> is included
after musl <netinet/in.h>:

./linux/in6.h:32:8: error: redefinition of 'struct in6_addr'
./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6'
./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq'

Signed-off-by: Felix Janda <felix.janda@posteo.de>
---
The previous mail misspelled the kernel mailing list. I am sorry for
this resulting spam.

There has already been one reply, which is available at

http://www.openwall.com/lists/musl/2016/11/11/2
---
 include/uapi/linux/libc-compat.h | 52 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h
index 44b8a6b..c316725 100644
--- a/include/uapi/linux/libc-compat.h
+++ b/include/uapi/linux/libc-compat.h
@@ -171,42 +171,94 @@
 #else /* !defined(__GLIBC__) */
 
 /* Definitions for if.h */
+#if !defined(__UAPI_DEF_IF_IFCONF)
 #define __UAPI_DEF_IF_IFCONF 1
+#endif
+#if !defined(__UAPI_DEF_IF_IFMAP)
 #define __UAPI_DEF_IF_IFMAP 1
+#endif
+#if !defined(__UAPI_DEF_IFNAMSIZ)
 #define __UAPI_DEF_IF_IFNAMSIZ 1
+#endif
+#if !defined(__UAPI_DEF_IFREQ)
 #define __UAPI_DEF_IF_IFREQ 1
+#endif
 /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
+#if !defined(__UAPI_DEF_IF_NET_DEVICE_FLAGS)
 #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
+#endif
 /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
+#if !defined(__UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO)
 #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+#endif
 
 /* Definitions for in.h */
+#if !defined(__UAPI_DEF_IN_ADDR)
 #define __UAPI_DEF_IN_ADDR		1
+#endif
+#if !defined(__UAPI_DEF_IN_IPPROTO)
 #define __UAPI_DEF_IN_IPPROTO		1
+#endif
+#if !defined(__UAPI_DEF_IN_PKTINFO)
 #define __UAPI_DEF_IN_PKTINFO		1
+#endif
+#if !defined(__UAPI_DEF_IP_MREQ)
 #define __UAPI_DEF_IP_MREQ		1
+#endif
+#if !defined(__UAPI_DEF_SOCKADDR_IN)
 #define __UAPI_DEF_SOCKADDR_IN		1
+#endif
+#if !defined(__UAPI_DEF_IN_CLASS)
 #define __UAPI_DEF_IN_CLASS		1
+#endif
 
 /* Definitions for in6.h */
+#if !defined(__UAPI_DEF_IN6_ADDR)
 #define __UAPI_DEF_IN6_ADDR		1
+#endif
+#if !defined(__UAPI_DEF_IN6_ADDR_ALT)
 #define __UAPI_DEF_IN6_ADDR_ALT		1
+#endif
+#if !defined(__UAPI_DEF_SOCKADDR_IN6)
 #define __UAPI_DEF_SOCKADDR_IN6		1
+#endif
+#if !defined(__UAPI_DEF_IPV6_MREQ)
 #define __UAPI_DEF_IPV6_MREQ		1
+#endif
+#if !defined(__UAPI_DEF_IPPROTO_V6)
 #define __UAPI_DEF_IPPROTO_V6		1
+#endif
+#if !defined(__UAPI_DEF_IPV6_OPTIONS)
 #define __UAPI_DEF_IPV6_OPTIONS		1
+#endif
+#if !defined(__UAPI_DEF_IN6_PKTINFO)
 #define __UAPI_DEF_IN6_PKTINFO		1
+#endif
+#if !defined(__UAPI_DEF_IP6_MTUINFO)
 #define __UAPI_DEF_IP6_MTUINFO		1
+#endif
 
 /* Definitions for ipx.h */
+#if !defined(__UAPI_DEF_SOCKADDR_IPX)
 #define __UAPI_DEF_SOCKADDR_IPX			1
+#endif
+#if !defined(__UAPI_DEF_IPX_ROUTE_DEFINITION)
 #define __UAPI_DEF_IPX_ROUTE_DEFINITION		1
+#endif
+#if !defined(__UAPI_DEF_IPX_INTERFACE_DEFINITION)
 #define __UAPI_DEF_IPX_INTERFACE_DEFINITION	1
+#endif
+#if !defined(__UAPI_DEF_IPX_CONFIG_DATA)
 #define __UAPI_DEF_IPX_CONFIG_DATA		1
+#endif
+#if !defined(__UAPI_DEF_IPX_ROUTE_DEF)
 #define __UAPI_DEF_IPX_ROUTE_DEF		1
+#endif
 
 /* Definitions for xattr.h */
+#if !defined(__UAPI_DEF_XATTR)
 #define __UAPI_DEF_XATTR		1
+#endif
 
 #endif /* __GLIBC__ */
 
-- 
2.7.3

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

* Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2016-11-11 12:08 [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions Felix Janda
@ 2017-03-08 12:46 ` David Woodhouse
  2017-03-08 16:39   ` Carlos O'Donell
       [not found]   ` <1488977188.4347.134.camel-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
  2017-03-08 15:53 ` Carlos O'Donell
  1 sibling, 2 replies; 17+ messages in thread
From: David Woodhouse @ 2017-03-08 12:46 UTC (permalink / raw)
  To: Felix Janda, linux-kernel
  Cc: David S. Miller, linux-api, musl, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 5524 bytes --]

On Fri, 2016-11-11 at 07:08 -0500, Felix Janda wrote:
> Currently, libc-compat.h detects inclusion of specific glibc headers,
> and defines corresponding _UAPI_DEF_* macros, which in turn are used in
> uapi headers to prevent definition of conflicting structures/constants.
> There is no such detection for other c libraries, for them the
> _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
> conflicting definitions are suppressed.
> 
> This patch enables non-glibc c libraries to request the suppression of
> any specific interface by defining the corresponding _UAPI_DEF_* macro
> as 0.

Ick. It's fairly horrid for kernel headers to be reacting to __GLIBC__
in any way. That's just wrong.

It makes more sense for C libraries to define the __UAPI_DEF_xxx for
themselves as and when they add their own support for certain things,
and for the kernel not to have incestuous knowledge of them.

The part you add here in the #else /* !__GLIBC__ */ part is what we
should do at *all* times.

I understand that we'll want to grandfather in the glibc horridness,
but let's make it clear that that's what it is, by letting it set the
appropriate __UAPI_DEF_xxx macros to zero, and then continue through to
your new part. Something like this (incremental to yours):

diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h
index c316725..7673158 100644
--- a/include/uapi/linux/libc-compat.h
+++ b/include/uapi/linux/libc-compat.h
@@ -53,41 +53,18 @@
 
 /* Coordinate with glibc net/if.h header. */
 #if defined(_NET_IF_H) && defined(__USE_MISC)
-
 /* GLIBC headers included first so don't define anything
  * that would already be defined. */
-
 #define __UAPI_DEF_IF_IFCONF 0
 #define __UAPI_DEF_IF_IFMAP 0
 #define __UAPI_DEF_IF_IFNAMSIZ 0
 #define __UAPI_DEF_IF_IFREQ 0
 /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
 #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0
-/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
-#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
-#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
-#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
-
-#else /* _NET_IF_H */
-
-/* Linux headers included first, and we must define everything
- * we need. The expectation is that glibc will check the
- * __UAPI_DEF_* defines and adjust appropriately. */
-
-#define __UAPI_DEF_IF_IFCONF 1
-#define __UAPI_DEF_IF_IFMAP 1
-#define __UAPI_DEF_IF_IFNAMSIZ 1
-#define __UAPI_DEF_IF_IFREQ 1
-/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
-#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
-/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
-#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
-
 #endif /* _NET_IF_H */
 
 /* Coordinate with glibc netinet/in.h header. */
 #if defined(_NETINET_IN_H)
-
 /* GLIBC headers included first so don't define anything
  * that would already be defined. */
 #define __UAPI_DEF_IN_ADDR		0
@@ -104,8 +81,6 @@
  * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */
 #if defined(__USE_MISC) || defined (__USE_GNU)
 #define __UAPI_DEF_IN6_ADDR_ALT		0
-#else
-#define __UAPI_DEF_IN6_ADDR_ALT		1
 #endif
 #define __UAPI_DEF_SOCKADDR_IN6		0
 #define __UAPI_DEF_IPV6_MREQ		0
@@ -113,62 +88,23 @@
 #define __UAPI_DEF_IPV6_OPTIONS		0
 #define __UAPI_DEF_IN6_PKTINFO		0
 #define __UAPI_DEF_IP6_MTUINFO		0
-
-#else
-
-/* Linux headers included first, and we must define everything
- * we need. The expectation is that glibc will check the
- * __UAPI_DEF_* defines and adjust appropriately. */
-#define __UAPI_DEF_IN_ADDR		1
-#define __UAPI_DEF_IN_IPPROTO		1
-#define __UAPI_DEF_IN_PKTINFO		1
-#define __UAPI_DEF_IP_MREQ		1
-#define __UAPI_DEF_SOCKADDR_IN		1
-#define __UAPI_DEF_IN_CLASS		1
-
-#define __UAPI_DEF_IN6_ADDR		1
-/* We unconditionally define the in6_addr macros and glibc must
- * coordinate. */
-#define __UAPI_DEF_IN6_ADDR_ALT		1
-#define __UAPI_DEF_SOCKADDR_IN6		1
-#define __UAPI_DEF_IPV6_MREQ		1
-#define __UAPI_DEF_IPPROTO_V6		1
-#define __UAPI_DEF_IPV6_OPTIONS		1
-#define __UAPI_DEF_IN6_PKTINFO		1
-#define __UAPI_DEF_IP6_MTUINFO		1
-
 #endif /* _NETINET_IN_H */
 
 /* Coordinate with glibc netipx/ipx.h header. */
 #if defined(__NETIPX_IPX_H)
-
 #define __UAPI_DEF_SOCKADDR_IPX			0
 #define __UAPI_DEF_IPX_ROUTE_DEFINITION		0
 #define __UAPI_DEF_IPX_INTERFACE_DEFINITION	0
 #define __UAPI_DEF_IPX_CONFIG_DATA		0
 #define __UAPI_DEF_IPX_ROUTE_DEF		0
-
-#else /* defined(__NETIPX_IPX_H) */
-
-#define __UAPI_DEF_SOCKADDR_IPX			1
-#define __UAPI_DEF_IPX_ROUTE_DEFINITION		1
-#define __UAPI_DEF_IPX_INTERFACE_DEFINITION	1
-#define __UAPI_DEF_IPX_CONFIG_DATA		1
-#define __UAPI_DEF_IPX_ROUTE_DEF		1
-
 #endif /* defined(__NETIPX_IPX_H) */
 
 /* Definitions for xattr.h */
 #if defined(_SYS_XATTR_H)
 #define __UAPI_DEF_XATTR		0
-#else
-#define __UAPI_DEF_XATTR		1
 #endif
 
-/* If we did not see any headers from any supported C libraries,
- * or we are being included in the kernel, then define everything
- * that we need. */
-#else /* !defined(__GLIBC__) */
+#endif /* __GLIBC__ */
 
 /* Definitions for if.h */
 #if !defined(__UAPI_DEF_IF_IFCONF)
@@ -260,6 +196,4 @@
 #define __UAPI_DEF_XATTR		1
 #endif
 
-#endif /* __GLIBC__ */
-
 #endif /* _UAPI_LIBC_COMPAT_H */






[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 4938 bytes --]

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

* Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2016-11-11 12:08 [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions Felix Janda
  2017-03-08 12:46 ` David Woodhouse
@ 2017-03-08 15:53 ` Carlos O'Donell
  2017-03-08 16:25   ` Rich Felker
  2017-03-09  0:14   ` Szabolcs Nagy
  1 sibling, 2 replies; 17+ messages in thread
From: Carlos O'Donell @ 2017-03-08 15:53 UTC (permalink / raw)
  To: linux-kernel, David S. Miller, linux-api, musl, Rich Felker

On 11/11/2016 07:08 AM, Felix Janda wrote:
> Currently, libc-compat.h detects inclusion of specific glibc headers,
> and defines corresponding _UAPI_DEF_* macros, which in turn are used in
> uapi headers to prevent definition of conflicting structures/constants.
> There is no such detection for other c libraries, for them the
> _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
> conflicting definitions are suppressed.
> 
> This patch enables non-glibc c libraries to request the suppression of
> any specific interface by defining the corresponding _UAPI_DEF_* macro
> as 0.
> 
> This patch together with the recent musl libc commit
> 
> http://git.musl-libc.org/cgit/musl/commit/?id=04983f2272382af92eb8f8838964ff944fbb8258

Would it be possible to amend the musl patch to define the macros to 1.

A defined or undefined macro is typo prone.

Please see this wiki for examples of the problems it causes:
https://sourceware.org/glibc/wiki/Wundef

Having the UAPI macros always defined and be 0 or 1 allows you to create
tooling to check for problems, while an undefined macro is just that,
either a mistake or the intended value.

> fixes the following compiler errors when <linux/in6.h> is included
> after musl <netinet/in.h>:
> 
> ./linux/in6.h:32:8: error: redefinition of 'struct in6_addr'
> ./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6'
> ./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq'

Do you have plans for fixing the error when the inclusion order is the other way?

It will require kernel header changes to have each individual kernel header define
the requisite __UAPI_* values to 1 e.g. moving libc-compat.h into the header.

Do you plan to do that in a next step?

> Signed-off-by: Felix Janda <felix.janda@posteo.de>
> ---
> The previous mail misspelled the kernel mailing list. I am sorry for
> this resulting spam.
> 
> There has already been one reply, which is available at
> 
> http://www.openwall.com/lists/musl/2016/11/11/2
> ---
>  include/uapi/linux/libc-compat.h | 52 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h
> index 44b8a6b..c316725 100644
> --- a/include/uapi/linux/libc-compat.h
> +++ b/include/uapi/linux/libc-compat.h
> @@ -171,42 +171,94 @@
>  #else /* !defined(__GLIBC__) */

Would you please update the lead comment in libc-compat.h explaining this usage
model so glibc and other libc's can follow best practice. Any new usage model
should express how to fix header inclusion ordering in both directions.

>  /* Definitions for if.h */
> +#if !defined(__UAPI_DEF_IF_IFCONF)

Typo prone. Please use #if __UAPI_DEF_IF_IFCONF for all of this.

>  #define __UAPI_DEF_IF_IFCONF 1
> +#endif
> +#if !defined(__UAPI_DEF_IF_IFMAP)
>  #define __UAPI_DEF_IF_IFMAP 1
> +#endif
> +#if !defined(__UAPI_DEF_IFNAMSIZ)
>  #define __UAPI_DEF_IF_IFNAMSIZ 1
> +#endif
> +#if !defined(__UAPI_DEF_IFREQ)
>  #define __UAPI_DEF_IF_IFREQ 1
> +#endif
>  /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
> +#if !defined(__UAPI_DEF_IF_NET_DEVICE_FLAGS)
>  #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
> +#endif
>  /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
> +#if !defined(__UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO)
>  #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
> +#endif
>  
>  /* Definitions for in.h */
> +#if !defined(__UAPI_DEF_IN_ADDR)
>  #define __UAPI_DEF_IN_ADDR		1
> +#endif
> +#if !defined(__UAPI_DEF_IN_IPPROTO)
>  #define __UAPI_DEF_IN_IPPROTO		1
> +#endif
> +#if !defined(__UAPI_DEF_IN_PKTINFO)
>  #define __UAPI_DEF_IN_PKTINFO		1
> +#endif
> +#if !defined(__UAPI_DEF_IP_MREQ)
>  #define __UAPI_DEF_IP_MREQ		1
> +#endif
> +#if !defined(__UAPI_DEF_SOCKADDR_IN)
>  #define __UAPI_DEF_SOCKADDR_IN		1
> +#endif
> +#if !defined(__UAPI_DEF_IN_CLASS)
>  #define __UAPI_DEF_IN_CLASS		1
> +#endif
>  
>  /* Definitions for in6.h */
> +#if !defined(__UAPI_DEF_IN6_ADDR)
>  #define __UAPI_DEF_IN6_ADDR		1
> +#endif
> +#if !defined(__UAPI_DEF_IN6_ADDR_ALT)
>  #define __UAPI_DEF_IN6_ADDR_ALT		1
> +#endif
> +#if !defined(__UAPI_DEF_SOCKADDR_IN6)
>  #define __UAPI_DEF_SOCKADDR_IN6		1
> +#endif
> +#if !defined(__UAPI_DEF_IPV6_MREQ)
>  #define __UAPI_DEF_IPV6_MREQ		1
> +#endif
> +#if !defined(__UAPI_DEF_IPPROTO_V6)
>  #define __UAPI_DEF_IPPROTO_V6		1
> +#endif
> +#if !defined(__UAPI_DEF_IPV6_OPTIONS)
>  #define __UAPI_DEF_IPV6_OPTIONS		1
> +#endif
> +#if !defined(__UAPI_DEF_IN6_PKTINFO)
>  #define __UAPI_DEF_IN6_PKTINFO		1
> +#endif
> +#if !defined(__UAPI_DEF_IP6_MTUINFO)
>  #define __UAPI_DEF_IP6_MTUINFO		1
> +#endif
>  
>  /* Definitions for ipx.h */
> +#if !defined(__UAPI_DEF_SOCKADDR_IPX)
>  #define __UAPI_DEF_SOCKADDR_IPX			1
> +#endif
> +#if !defined(__UAPI_DEF_IPX_ROUTE_DEFINITION)
>  #define __UAPI_DEF_IPX_ROUTE_DEFINITION		1
> +#endif
> +#if !defined(__UAPI_DEF_IPX_INTERFACE_DEFINITION)
>  #define __UAPI_DEF_IPX_INTERFACE_DEFINITION	1
> +#endif
> +#if !defined(__UAPI_DEF_IPX_CONFIG_DATA)
>  #define __UAPI_DEF_IPX_CONFIG_DATA		1
> +#endif
> +#if !defined(__UAPI_DEF_IPX_ROUTE_DEF)
>  #define __UAPI_DEF_IPX_ROUTE_DEF		1
> +#endif
>  
>  /* Definitions for xattr.h */
> +#if !defined(__UAPI_DEF_XATTR)
>  #define __UAPI_DEF_XATTR		1
> +#endif
>  
>  #endif /* __GLIBC__ */
>  
> 

-- 
Cheers,
Carlos.

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

* Re: Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-03-08 15:53 ` Carlos O'Donell
@ 2017-03-08 16:25   ` Rich Felker
  2017-03-08 17:29     ` Carlos O'Donell
  2017-03-09  0:14   ` Szabolcs Nagy
  1 sibling, 1 reply; 17+ messages in thread
From: Rich Felker @ 2017-03-08 16:25 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: linux-kernel, David S. Miller, linux-api, musl

On Wed, Mar 08, 2017 at 10:53:00AM -0500, Carlos O'Donell wrote:
> On 11/11/2016 07:08 AM, Felix Janda wrote:
> > Currently, libc-compat.h detects inclusion of specific glibc headers,
> > and defines corresponding _UAPI_DEF_* macros, which in turn are used in
> > uapi headers to prevent definition of conflicting structures/constants.
> > There is no such detection for other c libraries, for them the
> > _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
> > conflicting definitions are suppressed.
> > 
> > This patch enables non-glibc c libraries to request the suppression of
> > any specific interface by defining the corresponding _UAPI_DEF_* macro
> > as 0.
> > 
> > This patch together with the recent musl libc commit
> > 
> > http://git.musl-libc.org/cgit/musl/commit/?id=04983f2272382af92eb8f8838964ff944fbb8258
> 
> Would it be possible to amend the musl patch to define the macros to 1.

I don't follow. They're defined to 0 explicitly to tell the kernel
headers not to define their own versions of these structs, etc. since
they would clash. Defining to 1 would have the opposite meaning.

Rich

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

* Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-03-08 12:46 ` David Woodhouse
@ 2017-03-08 16:39   ` Carlos O'Donell
       [not found]     ` <459a8faf-4585-5063-3d94-3a1fecfa8289-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
       [not found]   ` <1488977188.4347.134.camel-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
  1 sibling, 1 reply; 17+ messages in thread
From: Carlos O'Donell @ 2017-03-08 16:39 UTC (permalink / raw)
  To: David Woodhouse, Felix Janda, linux-kernel
  Cc: David S. Miller, linux-api, musl

On 03/08/2017 07:46 AM, David Woodhouse wrote:
> On Fri, 2016-11-11 at 07:08 -0500, Felix Janda wrote:
>> Currently, libc-compat.h detects inclusion of specific glibc headers,
>> and defines corresponding _UAPI_DEF_* macros, which in turn are used in
>> uapi headers to prevent definition of conflicting structures/constants.
>> There is no such detection for other c libraries, for them the
>> _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
>> conflicting definitions are suppressed.
>>
>> This patch enables non-glibc c libraries to request the suppression of
>> any specific interface by defining the corresponding _UAPI_DEF_* macro
>> as 0.
> 
> Ick. It's fairly horrid for kernel headers to be reacting to __GLIBC__
> in any way. That's just wrong.
> 
> It makes more sense for C libraries to define the __UAPI_DEF_xxx for
> themselves as and when they add their own support for certain things,
> and for the kernel not to have incestuous knowledge of them.
> 
> The part you add here in the #else /* !__GLIBC__ */ part is what we
> should do at *all* times.
> 
> I understand that we'll want to grandfather in the glibc horridness,
> but let's make it clear that that's what it is, by letting it set the
> appropriate __UAPI_DEF_xxx macros to zero, and then continue through to
> your new part. Something like this (incremental to yours):

Any model we propose should be documented in the header of libc-compat.h
and explain how it works to solve header inclusion order in _both_ directions.
User use cases include header inclusion in _both_ directions and we should look
to support that.

> diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h
> index c316725..7673158 100644
> --- a/include/uapi/linux/libc-compat.h
> +++ b/include/uapi/linux/libc-compat.h
> @@ -53,41 +53,18 @@
>  
>  /* Coordinate with glibc net/if.h header. */
>  #if defined(_NET_IF_H) && defined(__USE_MISC)
> -
>  /* GLIBC headers included first so don't define anything
>   * that would already be defined. */
> -
>  #define __UAPI_DEF_IF_IFCONF 0
>  #define __UAPI_DEF_IF_IFMAP 0
>  #define __UAPI_DEF_IF_IFNAMSIZ 0
>  #define __UAPI_DEF_IF_IFREQ 0
>  /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
>  #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0
> -/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
> -#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
> -#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
> -#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
> -
> -#else /* _NET_IF_H */
> -
> -/* Linux headers included first, and we must define everything
> - * we need. The expectation is that glibc will check the
> - * __UAPI_DEF_* defines and adjust appropriately. */
> -
> -#define __UAPI_DEF_IF_IFCONF 1
> -#define __UAPI_DEF_IF_IFMAP 1
> -#define __UAPI_DEF_IF_IFNAMSIZ 1
> -#define __UAPI_DEF_IF_IFREQ 1
> -/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */
> -#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
> -/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */
> -#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
> -

Any header needing compat with a libc includes libc-compat.h (per the 
documented way the model works). With this patch any included linux kernel
header that also includes libc-compat.h would immediately define all 
the __UAPI_DEF_* constants to 1 as-if it had defined those structures, 
but it has not.

For example, with these two patches applied, the inclusion of linux/if.h
would define __UAPI_DEF_XATTR to 1, but linux/if.h has not defined
XATTR_CREATE or other constants, so a subsequent inclusion sys/xattrs.h
from userspace would _not_ define XATTR_CREATE because __UAPI_DEF_XATTR set
to 1 indicates the kernel has.

I don't want to read into the model you are proposing and would rather you
document the semantics clearly so we can all see what you mean.

>  #endif /* _NET_IF_H */
>  
>  /* Coordinate with glibc netinet/in.h header. */
>  #if defined(_NETINET_IN_H)
> -
>  /* GLIBC headers included first so don't define anything
>   * that would already be defined. */
>  #define __UAPI_DEF_IN_ADDR		0
> @@ -104,8 +81,6 @@
>   * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */
>  #if defined(__USE_MISC) || defined (__USE_GNU)
>  #define __UAPI_DEF_IN6_ADDR_ALT		0
> -#else
> -#define __UAPI_DEF_IN6_ADDR_ALT		1
>  #endif
>  #define __UAPI_DEF_SOCKADDR_IN6		0
>  #define __UAPI_DEF_IPV6_MREQ		0
> @@ -113,62 +88,23 @@
>  #define __UAPI_DEF_IPV6_OPTIONS		0
>  #define __UAPI_DEF_IN6_PKTINFO		0
>  #define __UAPI_DEF_IP6_MTUINFO		0
> -
> -#else
> -
> -/* Linux headers included first, and we must define everything
> - * we need. The expectation is that glibc will check the
> - * __UAPI_DEF_* defines and adjust appropriately. */
> -#define __UAPI_DEF_IN_ADDR		1
> -#define __UAPI_DEF_IN_IPPROTO		1
> -#define __UAPI_DEF_IN_PKTINFO		1
> -#define __UAPI_DEF_IP_MREQ		1
> -#define __UAPI_DEF_SOCKADDR_IN		1
> -#define __UAPI_DEF_IN_CLASS		1
> -
> -#define __UAPI_DEF_IN6_ADDR		1
> -/* We unconditionally define the in6_addr macros and glibc must
> - * coordinate. */
> -#define __UAPI_DEF_IN6_ADDR_ALT		1
> -#define __UAPI_DEF_SOCKADDR_IN6		1
> -#define __UAPI_DEF_IPV6_MREQ		1
> -#define __UAPI_DEF_IPPROTO_V6		1
> -#define __UAPI_DEF_IPV6_OPTIONS		1
> -#define __UAPI_DEF_IN6_PKTINFO		1
> -#define __UAPI_DEF_IP6_MTUINFO		1
> -
>  #endif /* _NETINET_IN_H */
>  
>  /* Coordinate with glibc netipx/ipx.h header. */
>  #if defined(__NETIPX_IPX_H)
> -
>  #define __UAPI_DEF_SOCKADDR_IPX			0
>  #define __UAPI_DEF_IPX_ROUTE_DEFINITION		0
>  #define __UAPI_DEF_IPX_INTERFACE_DEFINITION	0
>  #define __UAPI_DEF_IPX_CONFIG_DATA		0
>  #define __UAPI_DEF_IPX_ROUTE_DEF		0
> -
> -#else /* defined(__NETIPX_IPX_H) */
> -
> -#define __UAPI_DEF_SOCKADDR_IPX			1
> -#define __UAPI_DEF_IPX_ROUTE_DEFINITION		1
> -#define __UAPI_DEF_IPX_INTERFACE_DEFINITION	1
> -#define __UAPI_DEF_IPX_CONFIG_DATA		1
> -#define __UAPI_DEF_IPX_ROUTE_DEF		1
> -
>  #endif /* defined(__NETIPX_IPX_H) */
>  
>  /* Definitions for xattr.h */
>  #if defined(_SYS_XATTR_H)
>  #define __UAPI_DEF_XATTR		0
> -#else
> -#define __UAPI_DEF_XATTR		1
>  #endif
>  
> -/* If we did not see any headers from any supported C libraries,
> - * or we are being included in the kernel, then define everything
> - * that we need. */
> -#else /* !defined(__GLIBC__) */
> +#endif /* __GLIBC__ */
>  
>  /* Definitions for if.h */
>  #if !defined(__UAPI_DEF_IF_IFCONF)
> @@ -260,6 +196,4 @@
>  #define __UAPI_DEF_XATTR		1
>  #endif
>  
> -#endif /* __GLIBC__ */
> -
>  #endif /* _UAPI_LIBC_COMPAT_H */
> 
> 
> 
> 
> 


-- 
Cheers,
Carlos.

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

* Re: Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-03-08 16:25   ` Rich Felker
@ 2017-03-08 17:29     ` Carlos O'Donell
  0 siblings, 0 replies; 17+ messages in thread
From: Carlos O'Donell @ 2017-03-08 17:29 UTC (permalink / raw)
  To: Rich Felker; +Cc: linux-kernel, David S. Miller, linux-api, musl

On 03/08/2017 11:25 AM, Rich Felker wrote:
> On Wed, Mar 08, 2017 at 10:53:00AM -0500, Carlos O'Donell wrote:
>> On 11/11/2016 07:08 AM, Felix Janda wrote:
>>> Currently, libc-compat.h detects inclusion of specific glibc headers,
>>> and defines corresponding _UAPI_DEF_* macros, which in turn are used in
>>> uapi headers to prevent definition of conflicting structures/constants.
>>> There is no such detection for other c libraries, for them the
>>> _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
>>> conflicting definitions are suppressed.
>>>
>>> This patch enables non-glibc c libraries to request the suppression of
>>> any specific interface by defining the corresponding _UAPI_DEF_* macro
>>> as 0.
>>>
>>> This patch together with the recent musl libc commit
>>>
>>> http://git.musl-libc.org/cgit/musl/commit/?id=04983f2272382af92eb8f8838964ff944fbb8258
>>
>> Would it be possible to amend the musl patch to define the macros to 1.
> 
> I don't follow. They're defined to 0 explicitly to tell the kernel
> headers not to define their own versions of these structs, etc. since
> they would clash. Defining to 1 would have the opposite meaning.

My apologies, I must have misread the original musl patch.

Defining them to a known value is exactly what I was looking for.

The other outstanding questions remain.

-- 
Cheers,
Carlos.

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

* Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-03-08 15:53 ` Carlos O'Donell
  2017-03-08 16:25   ` Rich Felker
@ 2017-03-09  0:14   ` Szabolcs Nagy
  2017-03-09  0:51     ` Carlos O'Donell
       [not found]     ` <20170309001435.GJ2082-4P1ElwuDYu6sTnJN9+BGXg@public.gmane.org>
  1 sibling, 2 replies; 17+ messages in thread
From: Szabolcs Nagy @ 2017-03-09  0:14 UTC (permalink / raw)
  To: Carlos O'Donell
  Cc: linux-kernel, David S. Miller, linux-api, musl, Rich Felker

* Carlos O'Donell <carlos@redhat.com> [2017-03-08 10:53:00 -0500]:
> On 11/11/2016 07:08 AM, Felix Janda wrote:
> > fixes the following compiler errors when <linux/in6.h> is included
> > after musl <netinet/in.h>:
> > 
> > ./linux/in6.h:32:8: error: redefinition of 'struct in6_addr'
> > ./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6'
> > ./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq'
> 
> Do you have plans for fixing the error when the inclusion order is the other way?

the other way (linux header included first) is
problematic because linux headers don't follow
all the standards the libc follows, they violate
namespace rules in their struct definitions, so
the libc definitions are necessarily incompatible
with them and thus different translation units can
end up refering to the same object through
incompatible types which is undefined.
(even if the abi matches and thus works across
the syscall interface, a sufficiently smart
toolchain can break such code at link time,
and since the libc itself uses its own definitons
that's what user code should use too).

there should be a way to include standard conform
libc headers and linux headers into the same tu,
at least the case when all conflicting definitions
come from the libc should work and i think that
should be the scope of these libc-compat.h changes.
(of course if glibc tries to support arbitrary
interleavings then the changes should not break that)

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

* Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-03-09  0:14   ` Szabolcs Nagy
@ 2017-03-09  0:51     ` Carlos O'Donell
  2017-03-09  2:01       ` Rich Felker
       [not found]     ` <20170309001435.GJ2082-4P1ElwuDYu6sTnJN9+BGXg@public.gmane.org>
  1 sibling, 1 reply; 17+ messages in thread
From: Carlos O'Donell @ 2017-03-09  0:51 UTC (permalink / raw)
  To: linux-kernel, David S. Miller, linux-api, musl, Rich Felker

On 03/08/2017 07:14 PM, Szabolcs Nagy wrote:
> * Carlos O'Donell <carlos@redhat.com> [2017-03-08 10:53:00 -0500]:
>> On 11/11/2016 07:08 AM, Felix Janda wrote:
>>> fixes the following compiler errors when <linux/in6.h> is included
>>> after musl <netinet/in.h>:
>>>
>>> ./linux/in6.h:32:8: error: redefinition of 'struct in6_addr'
>>> ./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6'
>>> ./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq'
>>
>> Do you have plans for fixing the error when the inclusion order is the other way?
> 
> the other way (linux header included first) is
> problematic because linux headers don't follow
> all the standards the libc follows, they violate
> namespace rules in their struct definitions, so
> the libc definitions are necessarily incompatible
> with them and thus different translation units can
> end up refering to the same object through
> incompatible types which is undefined.
> (even if the abi matches and thus works across
> the syscall interface, a sufficiently smart
> toolchain can break such code at link time,
> and since the libc itself uses its own definitons
> that's what user code should use too).
> 
> there should be a way to include standard conform
> libc headers and linux headers into the same tu,
> at least the case when all conflicting definitions
> come from the libc should work and i think that
> should be the scope of these libc-compat.h changes.
> (of course if glibc tries to support arbitrary
> interleavings then the changes should not break that)

You can get non-standard defines even when including the
linux headers _after_ libc headers because linux headers
should rightly continue to define things that are required
for linux-specific applications.

IMO the fact that the UAPI headers may cause problems with
standards conformance is orthogonal to the discussion of 
_how_ we fix inclusion order issues.

Some of the network headers can be used in relative safety
and need to be used for some applications. It is those cases
where I'd like to see an inclusion guard design that works
for both inclusion orders.

-- 
Cheers,
Carlos.

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

* Re: Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-03-09  0:51     ` Carlos O'Donell
@ 2017-03-09  2:01       ` Rich Felker
  0 siblings, 0 replies; 17+ messages in thread
From: Rich Felker @ 2017-03-09  2:01 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: linux-kernel, David S. Miller, linux-api, musl

On Wed, Mar 08, 2017 at 07:51:29PM -0500, Carlos O'Donell wrote:
> On 03/08/2017 07:14 PM, Szabolcs Nagy wrote:
> > * Carlos O'Donell <carlos@redhat.com> [2017-03-08 10:53:00 -0500]:
> >> On 11/11/2016 07:08 AM, Felix Janda wrote:
> >>> fixes the following compiler errors when <linux/in6.h> is included
> >>> after musl <netinet/in.h>:
> >>>
> >>> ./linux/in6.h:32:8: error: redefinition of 'struct in6_addr'
> >>> ./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6'
> >>> ./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq'
> >>
> >> Do you have plans for fixing the error when the inclusion order is the other way?
> > 
> > the other way (linux header included first) is
> > problematic because linux headers don't follow
> > all the standards the libc follows, they violate
> > namespace rules in their struct definitions, so
> > the libc definitions are necessarily incompatible
> > with them and thus different translation units can
> > end up refering to the same object through
> > incompatible types which is undefined.
> > (even if the abi matches and thus works across
> > the syscall interface, a sufficiently smart
> > toolchain can break such code at link time,
> > and since the libc itself uses its own definitons
> > that's what user code should use too).
> > 
> > there should be a way to include standard conform
> > libc headers and linux headers into the same tu,
> > at least the case when all conflicting definitions
> > come from the libc should work and i think that
> > should be the scope of these libc-compat.h changes.
> > (of course if glibc tries to support arbitrary
> > interleavings then the changes should not break that)
> 
> You can get non-standard defines even when including the
> linux headers _after_ libc headers because linux headers
> should rightly continue to define things that are required
> for linux-specific applications.
> 
> IMO the fact that the UAPI headers may cause problems with
> standards conformance is orthogonal to the discussion of 
> _how_ we fix inclusion order issues.
> 
> Some of the network headers can be used in relative safety
> and need to be used for some applications. It is those cases
> where I'd like to see an inclusion guard design that works
> for both inclusion orders.

The issue has been discussed on our side (musl) and our position so
far is that we don't want to try to support the case of including the
kernel headers before the libc headers, at least not at this time.
It's a big rabbit hole of stuff that could go wrong. This doesn't
preclude the kernel folks trying to make things so that it _can_ be
supported more smoothly.

Rich

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

* Re: [musl] Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
       [not found]   ` <1488977188.4347.134.camel-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
@ 2017-04-25  6:37     ` Hauke Mehrtens
       [not found]       ` <9373f78c-ff15-fbb5-724a-27152d6f994b-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
  0 siblings, 1 reply; 17+ messages in thread
From: Hauke Mehrtens @ 2017-04-25  6:37 UTC (permalink / raw)
  To: musl-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8, Felix Janda,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: David S. Miller, linux-api-u79uwXL29TY76Z2rM5mHXA, Carlos O'Donell



On 03/08/2017 01:46 PM, David Woodhouse wrote:
> On Fri, 2016-11-11 at 07:08 -0500, Felix Janda wrote:
>> Currently, libc-compat.h detects inclusion of specific glibc headers,
>> and defines corresponding _UAPI_DEF_* macros, which in turn are used in
>> uapi headers to prevent definition of conflicting structures/constants.
>> There is no such detection for other c libraries, for them the
>> _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
>> conflicting definitions are suppressed.
>>
>> This patch enables non-glibc c libraries to request the suppression of
>> any specific interface by defining the corresponding _UAPI_DEF_* macro
>> as 0.
> 
> Ick. It's fairly horrid for kernel headers to be reacting to __GLIBC__
> in any way. That's just wrong.
> 
> It makes more sense for C libraries to define the __UAPI_DEF_xxx for
> themselves as and when they add their own support for certain things,
> and for the kernel not to have incestuous knowledge of them.
> 
> The part you add here in the #else /* !__GLIBC__ */ part is what we
> should do at *all* times.
> 
> I understand that we'll want to grandfather in the glibc horridness,
> but let's make it clear that that's what it is, by letting it set the
> appropriate __UAPI_DEF_xxx macros to zero, and then continue through to
> your new part. Something like this (incremental to yours):

Felix's and this change and are looking better than my patches here:
https://lkml.org/lkml/2017/3/12/235

Is someone working on brining this into the mainline kernel?

Is it correct that only the comments should be improved?
musl only supports including the musl header files before the kernel
anyway, I assume that it is not needed to make the kernel uapi code
support also the other order.

Hauke

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

* Re: [musl] Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
       [not found]     ` <459a8faf-4585-5063-3d94-3a1fecfa8289-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2017-04-25  6:45       ` Hauke Mehrtens
  2017-04-25 12:29         ` Carlos O'Donell
  0 siblings, 1 reply; 17+ messages in thread
From: Hauke Mehrtens @ 2017-04-25  6:45 UTC (permalink / raw)
  To: musl-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8, David Woodhouse,
	Felix Janda, linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: David S. Miller, linux-api-u79uwXL29TY76Z2rM5mHXA

On 03/08/2017 05:39 PM, Carlos O'Donell wrote:
> Any header needing compat with a libc includes libc-compat.h (per the 
> documented way the model works). With this patch any included linux kernel
> header that also includes libc-compat.h would immediately define all 
> the __UAPI_DEF_* constants to 1 as-if it had defined those structures, 
> but it has not.
> 
> For example, with these two patches applied, the inclusion of linux/if.h
> would define __UAPI_DEF_XATTR to 1, but linux/if.h has not defined
> XATTR_CREATE or other constants, so a subsequent inclusion sys/xattrs.h
> from userspace would _not_ define XATTR_CREATE because __UAPI_DEF_XATTR set
> to 1 indicates the kernel has.
> 
> I don't want to read into the model you are proposing and would rather you
> document the semantics clearly so we can all see what you mean.

What about moving the code from libc-comapt.h into the specific header
files? This way including linux/if.h would not have an impact on
__UAPI_DEF_XATTR, because this is defined in linux/xattr.h. We would
still have a problem when the specific Linux header file gets included
before the libc header file, but at least musl does not support this anyway.

Hauke

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

* Re: [musl] Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
       [not found]       ` <9373f78c-ff15-fbb5-724a-27152d6f994b-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
@ 2017-04-25 12:13         ` Carlos O'Donell
  2017-07-08 20:27           ` Felix Janda
  0 siblings, 1 reply; 17+ messages in thread
From: Carlos O'Donell @ 2017-04-25 12:13 UTC (permalink / raw)
  To: Hauke Mehrtens, musl-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8,
	Felix Janda, linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: David S. Miller, linux-api-u79uwXL29TY76Z2rM5mHXA

On 04/25/2017 02:37 AM, Hauke Mehrtens wrote:
> 
> 
> On 03/08/2017 01:46 PM, David Woodhouse wrote:
>> On Fri, 2016-11-11 at 07:08 -0500, Felix Janda wrote:
>>> Currently, libc-compat.h detects inclusion of specific glibc headers,
>>> and defines corresponding _UAPI_DEF_* macros, which in turn are used in
>>> uapi headers to prevent definition of conflicting structures/constants.
>>> There is no such detection for other c libraries, for them the
>>> _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
>>> conflicting definitions are suppressed.
>>>
>>> This patch enables non-glibc c libraries to request the suppression of
>>> any specific interface by defining the corresponding _UAPI_DEF_* macro
>>> as 0.
>>
>> Ick. It's fairly horrid for kernel headers to be reacting to __GLIBC__
>> in any way. That's just wrong.
>>
>> It makes more sense for C libraries to define the __UAPI_DEF_xxx for
>> themselves as and when they add their own support for certain things,
>> and for the kernel not to have incestuous knowledge of them.
>>
>> The part you add here in the #else /* !__GLIBC__ */ part is what we
>> should do at *all* times.
>>
>> I understand that we'll want to grandfather in the glibc horridness,
>> but let's make it clear that that's what it is, by letting it set the
>> appropriate __UAPI_DEF_xxx macros to zero, and then continue through to
>> your new part. Something like this (incremental to yours):
> 
> Felix's and this change and are looking better than my patches here:
> https://lkml.org/lkml/2017/3/12/235
> 
> Is someone working on brining this into the mainline kernel?
> 
> Is it correct that only the comments should be improved?
> musl only supports including the musl header files before the kernel
> anyway, I assume that it is not needed to make the kernel uapi code
> support also the other order.

Please repost to linux-api so other relevant C library authors can review
the changes and comment on how they might be harmonized.

Whether or not you  support both inclusion orders, kernel first, or libc first,
is a property of your libc implementation.

Today glibc aims to support both inclusion orders since we see applications
with either order, and the ordering should not matter in this case. You either
get one or the other without needing to know any special rules about header
ordering.

-- 
Cheers,
Carlos.

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

* Re: Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-04-25  6:45       ` [musl] " Hauke Mehrtens
@ 2017-04-25 12:29         ` Carlos O'Donell
  2017-04-25 17:00           ` Rich Felker
       [not found]           ` <9f591383-6e4c-c231-1e5b-68e4b8c16d94-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  0 siblings, 2 replies; 17+ messages in thread
From: Carlos O'Donell @ 2017-04-25 12:29 UTC (permalink / raw)
  To: Hauke Mehrtens, musl, David Woodhouse, Felix Janda, linux-kernel
  Cc: David S. Miller, linux-api

On 04/25/2017 02:45 AM, Hauke Mehrtens wrote:
> On 03/08/2017 05:39 PM, Carlos O'Donell wrote:
>> Any header needing compat with a libc includes libc-compat.h (per the 
>> documented way the model works). With this patch any included linux kernel
>> header that also includes libc-compat.h would immediately define all 
>> the __UAPI_DEF_* constants to 1 as-if it had defined those structures, 
>> but it has not.
>>
>> For example, with these two patches applied, the inclusion of linux/if.h
>> would define __UAPI_DEF_XATTR to 1, but linux/if.h has not defined
>> XATTR_CREATE or other constants, so a subsequent inclusion sys/xattrs.h
>> from userspace would _not_ define XATTR_CREATE because __UAPI_DEF_XATTR set
>> to 1 indicates the kernel has.
>>
>> I don't want to read into the model you are proposing and would rather you
>> document the semantics clearly so we can all see what you mean.
> 
> What about moving the code from libc-comapt.h into the specific header
> files? This way including linux/if.h would not have an impact on
> __UAPI_DEF_XATTR, because this is defined in linux/xattr.h. We would
> still have a problem when the specific Linux header file gets included
> before the libc header file, but at least musl does not support this anyway.

The point of libc-compat.h is to contain the libc-related logic to a single header
where it can be reviewed easily as a whole for each libc.

Headers that include libc-compat.h need not have any libc-related logic, they need
only guard their structures with the appropriate __UAPI_DEF* macros per the rules
described in libc-compat.h.

This way we minimize any changes to the header files and keep the complex
logic in one place where the libc authors can discuss it.

In glibc right now we support including linux or glibc header files first,
and this has always been a requirement from the start. This requirement dictates
that the kernel know which libc it's being used with so it can tailor coordination.

If musl only needs header coordination in one direction, then support only that
direction, but please do not presume to simplify the code by deleting a bunch of
things that were worked into the kernel to ensure header inclusion ordering works
in both ways.

I have lots of customers writing code that includes kernel headers and letting them
include headers safely in any order where both headers provide the same define is
the simplest thing.

If you have a suggestion, please describe your proposed model in detail, and provide
a patch that explains and show how it works.

-- 
Cheers,
Carlos.

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

* Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
       [not found]     ` <20170309001435.GJ2082-4P1ElwuDYu6sTnJN9+BGXg@public.gmane.org>
@ 2017-04-25 13:22       ` Florian Weimer
  0 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2017-04-25 13:22 UTC (permalink / raw)
  To: Carlos O'Donell, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	David S. Miller, linux-api-u79uwXL29TY76Z2rM5mHXA,
	musl-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8, Rich Felker

On 03/09/2017 01:14 AM, Szabolcs Nagy wrote:
> the other way (linux header included first) is
> problematic because linux headers don't follow
> all the standards the libc follows, they violate
> namespace rules in their struct definitions, so
> the libc definitions are necessarily incompatible
> with them and thus different translation units can
> end up refering to the same object through
> incompatible types which is undefined.
> (even if the abi matches and thus works across
> the syscall interface, a sufficiently smart
> toolchain can break such code at link time,
> and since the libc itself uses its own definitons
> that's what user code should use too).

I don't think this is relevant in this context.  LTO implementations 
have to deal with this already.  For glibc's sake alone, it must be 
supported to link together code using differing feature test macros.

Thanks,
Florian

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

* Re: Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-04-25 12:29         ` Carlos O'Donell
@ 2017-04-25 17:00           ` Rich Felker
       [not found]           ` <9f591383-6e4c-c231-1e5b-68e4b8c16d94-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  1 sibling, 0 replies; 17+ messages in thread
From: Rich Felker @ 2017-04-25 17:00 UTC (permalink / raw)
  To: Carlos O'Donell
  Cc: Hauke Mehrtens, musl, David Woodhouse, Felix Janda, linux-kernel,
	David S. Miller, linux-api

On Tue, Apr 25, 2017 at 08:29:00AM -0400, Carlos O'Donell wrote:
> On 04/25/2017 02:45 AM, Hauke Mehrtens wrote:
> > On 03/08/2017 05:39 PM, Carlos O'Donell wrote:
> >> Any header needing compat with a libc includes libc-compat.h (per the 
> >> documented way the model works). With this patch any included linux kernel
> >> header that also includes libc-compat.h would immediately define all 
> >> the __UAPI_DEF_* constants to 1 as-if it had defined those structures, 
> >> but it has not.
> >>
> >> For example, with these two patches applied, the inclusion of linux/if.h
> >> would define __UAPI_DEF_XATTR to 1, but linux/if.h has not defined
> >> XATTR_CREATE or other constants, so a subsequent inclusion sys/xattrs.h
> >> from userspace would _not_ define XATTR_CREATE because __UAPI_DEF_XATTR set
> >> to 1 indicates the kernel has.
> >>
> >> I don't want to read into the model you are proposing and would rather you
> >> document the semantics clearly so we can all see what you mean.
> > 
> > What about moving the code from libc-comapt.h into the specific header
> > files? This way including linux/if.h would not have an impact on
> > __UAPI_DEF_XATTR, because this is defined in linux/xattr.h. We would
> > still have a problem when the specific Linux header file gets included
> > before the libc header file, but at least musl does not support this anyway.
> 
> The point of libc-compat.h is to contain the libc-related logic to a single header
> where it can be reviewed easily as a whole for each libc.
> 
> Headers that include libc-compat.h need not have any libc-related logic, they need
> only guard their structures with the appropriate __UAPI_DEF* macros per the rules
> described in libc-compat.h.
> 
> This way we minimize any changes to the header files and keep the complex
> logic in one place where the libc authors can discuss it.
> 
> In glibc right now we support including linux or glibc header files first,
> and this has always been a requirement from the start. This requirement dictates
> that the kernel know which libc it's being used with so it can tailor coordination.
> 
> If musl only needs header coordination in one direction, then support only that
> direction, but please do not presume to simplify the code by deleting a bunch of
> things that were worked into the kernel to ensure header inclusion ordering works
> in both ways.

Agreed.

On the musl side, we really don't want to be playing cat-and-mouse
having to follow every kernel change and rework things when subtle
differences from kernel-provided definitions might conflict. Saying
(with a macro) "we've got this, please don't try to redefine it" is
easy and maitenance-free; trying to make do with a definition that may
or may not be entirely compatible with libc types or namespace
constraints is nontrivial, and I'd rather it (including kernel defs
first) just not work from the outset than break somewhere down the
line and turn into an argument over whether it needs to be fixed and
if so how.

But none of this justifies breaking stuff that's working for glibc or
preventing them from cleanly supporting both orders.

Rich

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

* Re: [musl] Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
       [not found]           ` <9f591383-6e4c-c231-1e5b-68e4b8c16d94-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2017-06-02  7:07             ` Florian Weimer
  0 siblings, 0 replies; 17+ messages in thread
From: Florian Weimer @ 2017-06-02  7:07 UTC (permalink / raw)
  To: Carlos O'Donell, Hauke Mehrtens,
	musl-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8, David Woodhouse,
	Felix Janda, linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: David S. Miller, linux-api-u79uwXL29TY76Z2rM5mHXA

On 04/25/2017 02:29 PM, Carlos O'Donell wrote:
> In glibc right now we support including linux or glibc header files first,
> and this has always been a requirement from the start. This requirement dictates
> that the kernel know which libc it's being used with so it can tailor coordination.

“right now we support” is not a support commitment, but more of an
aspiration, right?

A lot of combinations are broken, especially when kernel headers are
included first.  Maybe it's time for us to admit defeat and come up with
a simpler scheme which actually works.

Thanks,
Florian

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

* Re: Re: [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions
  2017-04-25 12:13         ` Carlos O'Donell
@ 2017-07-08 20:27           ` Felix Janda
  0 siblings, 0 replies; 17+ messages in thread
From: Felix Janda @ 2017-07-08 20:27 UTC (permalink / raw)
  To: Carlos O'Donell
  Cc: Hauke Mehrtens, musl, linux-kernel, David S. Miller, linux-api

Carlos O'Donell wrote:
> On 04/25/2017 02:37 AM, Hauke Mehrtens wrote:
> > 
> > 
> > On 03/08/2017 01:46 PM, David Woodhouse wrote:
> >> On Fri, 2016-11-11 at 07:08 -0500, Felix Janda wrote:
> >>> Currently, libc-compat.h detects inclusion of specific glibc headers,
> >>> and defines corresponding _UAPI_DEF_* macros, which in turn are used in
> >>> uapi headers to prevent definition of conflicting structures/constants.
> >>> There is no such detection for other c libraries, for them the
> >>> _UAPI_DEF_* macros are always defined as 1, and so none of the possibly
> >>> conflicting definitions are suppressed.
> >>>
> >>> This patch enables non-glibc c libraries to request the suppression of
> >>> any specific interface by defining the corresponding _UAPI_DEF_* macro
> >>> as 0.
> >>
> >> Ick. It's fairly horrid for kernel headers to be reacting to __GLIBC__
> >> in any way. That's just wrong.
> >>
> >> It makes more sense for C libraries to define the __UAPI_DEF_xxx for
> >> themselves as and when they add their own support for certain things,
> >> and for the kernel not to have incestuous knowledge of them.
> >>
> >> The part you add here in the #else /* !__GLIBC__ */ part is what we
> >> should do at *all* times.
> >>
> >> I understand that we'll want to grandfather in the glibc horridness,
> >> but let's make it clear that that's what it is, by letting it set the
> >> appropriate __UAPI_DEF_xxx macros to zero, and then continue through to
> >> your new part. Something like this (incremental to yours):
> > 
> > Felix's and this change and are looking better than my patches here:
> > https://lkml.org/lkml/2017/3/12/235
> > 
> > Is someone working on brining this into the mainline kernel?
> > 
> > Is it correct that only the comments should be improved?
> > musl only supports including the musl header files before the kernel
> > anyway, I assume that it is not needed to make the kernel uapi code
> > support also the other order.
> 
> Please repost to linux-api so other relevant C library authors can review
> the changes and comment on how they might be harmonized.

>From the beginning, this patch was CCed to linux-api. Let me repost
anyway with a new (hopefully clearer) commit message.

> Whether or not you  support both inclusion orders, kernel first, or libc first,
> is a property of your libc implementation.
> 
> Today glibc aims to support both inclusion orders since we see applications
> with either order, and the ordering should not matter in this case. You either
> get one or the other without needing to know any special rules about header
> ordering.

This patch does not change anything for glibc (or uclibc), it just, in
a not very intrusive way, improves the situation for any other libc.

Felix

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

end of thread, other threads:[~2017-07-08 20:27 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-11 12:08 [PATCH resent] uapi libc compat: allow non-glibc to opt out of uapi definitions Felix Janda
2017-03-08 12:46 ` David Woodhouse
2017-03-08 16:39   ` Carlos O'Donell
     [not found]     ` <459a8faf-4585-5063-3d94-3a1fecfa8289-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-04-25  6:45       ` [musl] " Hauke Mehrtens
2017-04-25 12:29         ` Carlos O'Donell
2017-04-25 17:00           ` Rich Felker
     [not found]           ` <9f591383-6e4c-c231-1e5b-68e4b8c16d94-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-06-02  7:07             ` [musl] " Florian Weimer
     [not found]   ` <1488977188.4347.134.camel-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2017-04-25  6:37     ` Hauke Mehrtens
     [not found]       ` <9373f78c-ff15-fbb5-724a-27152d6f994b-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
2017-04-25 12:13         ` Carlos O'Donell
2017-07-08 20:27           ` Felix Janda
2017-03-08 15:53 ` Carlos O'Donell
2017-03-08 16:25   ` Rich Felker
2017-03-08 17:29     ` Carlos O'Donell
2017-03-09  0:14   ` Szabolcs Nagy
2017-03-09  0:51     ` Carlos O'Donell
2017-03-09  2:01       ` Rich Felker
     [not found]     ` <20170309001435.GJ2082-4P1ElwuDYu6sTnJN9+BGXg@public.gmane.org>
2017-04-25 13:22       ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).