On Friday 10 July 2009 05:12:53 Denys Vlasenko wrote: > On Fri, Jul 10, 2009 at 10:46 AM, Rob Landley<[email protected]> wrote: > > How is the MS_BIND stuff a good idea? Duplicating a long #ifdef > > staircase in two places doesn't really sound like an improvement. > > I agree that duplicating is bad. > > I don't want to handle _libc_ compat issues in platform.h, > because in order to do > > #ifdnef FOO > # define FOO good_foo > #endif > > one needs to #include <relevant_file.h> first. And if we do that > in platform.h, it will grow big. > > I decided to do such things in libbb.h instead, directly after each > #include <relevant_file.h> which needs such treatment.
The problem is that this mixes busybox knowledge with platform knowledge. Essentially, a different platform is a different build environment. Linux on powerpc is a different build environment from x86-64 glibc Linux, you need a special compiler and libraries to build it, and a special runtime environment (hardware or emulator) to test the result. Linux on uClibc is also a different build environment, one which most people don't have lying around, so they can't easily test their changes against it. Linux developers have to modify libbb.h to add functionality all the time. If they screw up platform stuff, they can't regression test it. This means that if libbb.h contains a lot of magic that most people aren't expected to understand, and thus shouldn't touch under any circumstances, then they're expected to add stuff around it and never remove anything they didn't put there... That's a recipe for accumulating cruft. I can see splitting platform.h into a "platform" directory and a bunch of #includes of platform/macos.h, platform/linux.h, platform/libgloss.h, and so on. (That was always a possibility when platform.h was introduced, we just didn't have enough stuff to justify it back then.) But segregating "only practicioners of this particular dark art should ever need to look at this bit" code from "everybody should be able to understand/test this and change it as needed" code was about half the reason for platform.h. (The rest was to try to make everything work the same way as much as possible, so you didn't have to worry about platform idiosyncrasies when trying to wrap your head around things like "sed".) > And if some headers aren't included into libbb.h because they are > specialized (like sys/mount.h), then I decided to do it whereever they > are included. If a standard header always needs fixups, that sounds like that's more of an argument for centralizing those fixups somewhere. Perhaps doing a "mount_.h" wrapper the way there's grp_.h, pwd_.h, rtc_.h, and shadow_.h today? (Why there's header_.h style for those and xregex.c style for xregcomp() is something I don't remember the reasoning behind...) But I'd like to make sure that doing without the fixups isn't a viable option first... What platforms does busybox currently support, anyway? (I vaguely recall somebody was seriously defending Dec Ultrix compatability, or some such. And somebody was trying to port the thing to MacOSX but went away again. And the guy who was getting some subset of the applets running on newlib/libgloss...) > > Besides, all these > > #defines are already in a standard header file if you're building on a > > system that can actually use the result. (If they're not in your header, > > that means the kernel headers you're using don't know about that call, > > and thus you probably shouldn't be using it.) > > And if you're building on an old(er) system, but run on a newer one? If you have an older build environment, that limits the functionality binaries you build can access out of a newer system. This issue isn't specific to busybox, this is in general. Trying to provide every missing system call and longer ioctl structure and so on in your own code is not only a nightmare, but it's not our job. The C library provides that stuff, that's its' job. Reproducing it in busybox, a project intended to be smaller and simpler than the alternative implementations it replaces, is probably not a good idea. If busybox _isn't_ smaller and simpler, there's no point in reinventing the wheel. The horrible, horrible, horrible history of loop.c is one example of where we couldn't quite avoid this, and had to settle for minimizing it. Once upon a time I managed to localize the horribleness to an #else for the 2.4 kernel (look at the libbb/loop.c part of "git show 6a6798b8e47c7"), and I'd hoped it could go away entirely when the 2.4 kernel finally fell off of people's radars. (Keep in mind 2.6 had only been out for a couple years at the time, and it was so new some distros most recent releases were still using 2.4.) Unfortunately, looking at it now, none of the old horribleness ever expired, and instead new #ifdefs grew up around it... Um, I think this is wrong: + +/* For 2.6, use the cleaned up header to get the 64 bit API. */ +/* linux/loop.h relies on __u64. Make sure we have that as a proper type + * until userspace is widely fixed. */ +# if (defined __INTEL_COMPILER && !defined __GNUC__) \ + || (defined __GNUC__ && defined __STRICT_ANSI__) What does __INTEL_COMPILER or __STRICT_ANSI__ have to do with a linux kernel header? The file "linux/loop.c" is exported by the kernel source via "make headers_install". It has nothing to do with your compiler, it's a Linux kernel header. It's supposed to match your Linux kernel version, not your compiler version. (And technically it's your C library that the kernel headers are exported to, not your compiler at all.) +__extension__ typedef long long __s64; +__extension__ typedef unsigned long long __u64; +# endif +# include <linux/loop.h> The linux/loop.h header #includes either asm/types.h or linux/types.h (depending on kernel version) to get the definition of __u64. There's a comment to that effect in the kernel headers, which come from the Linux kernel. If somebody's build environment isn't getting that, then their kernel headers are broken. (Most likely because they weren't exported properly.) Busybox really shouldn't be working around obvious bugs in people's build environments, that way lies madness. (By the way, the reason I didn't try to throw any of the loop.c setup in platform.h is precisely because it's so linux-specific, yet doesn't vary by target architecture. The "losetup" command only existed on Linux, it's based around #including a header with "linux" in its name because that's the only place the ioctl structure for it was ever defined, and as far as I know other operating systems haven't got the loopback device association system call unless they're copying the Linux one. Therefore, a "make this work on freebsd" checkin touching loop.c is WEIRD.) > I suspect that was the original motivation for this. Actually, the original motivation was to avoid build breaks in mount.c (which I rewrote three times trying to get it right). The first #ifdef was pretty much me being lazy, if I added a proper config option for --bind and --move then I'd need to change the option parsing and help text, the quick and dirty way to make it build everywhere was just #define it if it wasn't there. I expected old kernels that didn't support it to fall out of use anyway, so didn't put a whole lot of effort into supporting them. I did a quick hack instead of a config option for it because I thought the problem was _going_away_, at which point the hack could be removed. In general, older systems are yet more build environments most developers didn't tend to have lying around, which we couldn't easily test on, so we erred on the side of not build breaking on them. That's why I put that Red Hat 9 image up in downloads/qemu, so we at least had the capability of regression testing against a common "old" system. (The _interest_ in doing so is another matter; I just tried building 1.14.1 defconfig under that RH9 image and it died in miscutils/ionice.c. Switching that off, it died in miscutils/watchdog.c.) Even back in 2006 the majority opinion was already that Red hat 9 was probably too old to care about in new releases of busybox. (If you want to use an older build environment, you can always download older busybox source to build under it.) I was being a bit conservative at the time, largely because RH9 was only about 3 years old then. These days it's more like 7, and that's a very different threshold. Beyond a certain point, newer busyboxes not working with older build environments (kernel, C library, compiler, make, command line utilities) is probably a subset of http://busybox.net/FAQ.html#backporting It's a balancing act, but if you accept "simple" is one of the virtues of busybox, accumuluating cruft is bad. > > What might be better is some kind of switch you can throw to trim this > > functionality when it's not supported, to avoid a build break. Either a > > CONFIG option for "2.6 mount options", or a single "#ifndef MS_RELATIME" > > to disable the lot of it, checking the most recent one. (There's not > > much point in adding extra granularity, special support for a 2.6.12 > > kernel as distinct from a 2.4 kernel doesn't really seem worth the effort > > to me.) > > Feel free to send a patch for CONFIG option for "2.6 mount options". > > Another possible thing is to just wait a year and then declare that > whoever still uses 2.6.12 instead of migrating to something > less antiquated (less antiquated within 2.6.x world) > is going to suffer, and delete the ifdefs. I'd strongly lean towards the second. On that note: commit 4c5ad2fc90389bf1239f17d84967d07b82f31dd7 Author: Rob Landley <[email protected]> Date: Wed Jun 7 20:11:53 2006 +0000 Consolidate devfs garbage and mark it as obsolete. It's been over three years since then. Can it go away yet? Rob -- Latency is more important than throughput. It's that simple. - Linus Torvalds _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
