Hello *.*,
It sounds like we have, perhaps, been talking at slight cross purposes.
It is true that you can build glibc against a different version of
linux-libc-headers than the version of the kernel that will be used at
runtime. So long as the runtime kernel version is newer than the
minimum kernel version that glibc was configured for (either via
--enable-kernel=XXX, or via an architecture-specific static definition)
then everything should still work fine, and glibc will use internal
fallbacks if it discovers that certain system calls are not available at
runtime.
Similarly, glibc will make some efforts to provide a backwards
compatible emulation for user-visible interfaces which might not be
available in all kernel versions. However, what it doesn't attempt to
do is provide a completely virtualised ABI which would insulate the
application entirely from the details of the running kernel. There are
some kernel features which simply aren't feasible to emulate in user
space.
In the openembedded world glibc will present the kernel headers provided
to it at compile time to any application being compiled. So every
application on our system thinks it's running on 2.6.31 (version of
linux-libc-headers) while it runs on 2.6.24.
In the specific case of epoll_create1() and inotify_init1(), it would be
reasonable for glibc to do something similar to the way that, say,
mmap64() is handled. That is, if the kernel doesn't have
epoll_create1() but does have epoll_create(), and the behaviour that the
user has requested is something that epoll_create() can do (i.e. none of
the flag bits are set) then use epoll_create(). But if the user has
asked for EPOLL_CLOEXEC then epoll_create() is not a suitable
replacement and you are going to get ENOSYS: it's then up to the
application to take some suitable recovery action.
It is a compile time matter: when an application is configured for
compilation, then glibc system headers (2.6.31) will claim that certain
interfaces (like e.g. inotify_init1) are there while they really are not
at runtime (2.6.24).
Let's see how an application could handle this situation:
If my application includes <sys/inotify.h> and it is using
inotify_init1() I expect the compilation to fail if the interface will
not be available at runtime. I can, however, provide compatibility to
older kernels at application level by providing different
implementations based on configure.h and HAVE_INOTIFY_INIT1 (or
similar). Configure figures out runtime availability of all non-portable
interfaces, so based on the results of a configure run I can decide
about which interfaces to use. Trying this at runtime is next to impossible.
I have no means of detecting a level of compatibility at runtime. How
could that work, anyway? I get ENOSYS when calling inotify_init1(), so,
well I *think* this interface is missing (although configure reported it
being available). Then I would have to dynamically fall back to
inotify_init() + fcntl(). What if that returns ENOSYS? Fall back to
dnotify? And repeat this dance every time I need to call
inotify_init1()? Basically, I'm blind at runtime concerning kernel
feature availability when my system header files lied to me at compile
time. Compatibility code would have to fumble for the interfaces
*really* available at runtime by using trial-and-error. I would not
expect anyone to provide this kind of compatibility.
Regards,
Thilo
--
Dipl.-Ing (FH) Thilo Fromm, MSc., Embedded Systems Developer
DResearch Digital Media Systems GmbH
Otto-Schmirgal-Str. 3, D-10319 Berlin, Germany
Amtsgericht: Berlin Charlottenburg, HRB:54412
Tel: +49 (30) 515 932 228 mailto:[email protected]
Fax: +49 (30) 515 932 77 http://www.dresearch.de
_______________________________________________
Openembedded-devel mailing list
[email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel