Subject: Re: RFC: migration to a fully dynamically linked system
To: None <cgd@broadcom.com>
From: Luke Mewburn <lukem@wasabisystems.com>
List: tech-userlevel
Date: 12/26/2001 16:58:33
On Thu, Dec 20, 2001 at 05:58:33PM -0800, cgd@broadcom.com wrote:
| More seriously, I think this is a problem that should be solved, and I
| lean towards solution 3 as well. It's the most sane long-term, in my
| opinion.
|
|
| At Fri, 21 Dec 2001 01:20:14 +0000 (UTC), "Luke Mewburn" wrote:
| > 3. Dynamically link everything against /lib
| >
| > Provide /lib, which contains /lib/ld.elf_so and all of the
| > .so* files from /usr/lib. /usr/lib still contains the .a,
| > _p.a, and _pic.a libraries. Convert /usr/libexec/ld.elf_so
| > to a symlink to /lib/ld.elf_so.
|
| uh, well, if keeping consistent w/ the filenames used in the rest of
| the system, why not /libexec/ld.elf_so?
A few (probably subjective :) reasons:
- Why create /libexec just to contain ld.*so ?
- SVR4 has ld.*so in /lib (which is actually /usr/lib), as
well as /etc/lib (for some programs in /)
- Linux has ld.*so in /lib
- It's a .so file, so let's put it with the other .so files.
(ok, ok, that's a lame reason :)
| > Dynamically link all of /bin and /sbin and the other bits of
| > the tree which are currently statically linked, against /lib.
|
| uh, excluding what? there _have_ to be _some_ exclusions, like i'd
| bloody well hope 'init' isn't dynamically linked. 8-)
My solution would not preclude creating statically linked programs;
they just won't have the benefits provided by the dlopen()-aware
dynamic libc.so.
| That does restrict 'init' from e.g. knowing about some mechanisms of
| getting passwords (no PAM for root for secure console access! 8-), but
| if you don't do this I don't see how you can have sane recovery.
As to /sbin/init; there's a couple of solutions:
- Statically link /sbin/init, for simple sane recovery.
My test box currently has this.
- Dynamically link /sbin/init so that dynamic features
can be used (e.g, ldap for secure console access, different
dynamically linked locales, etc ;-).
Provide /sbin/init.static and/or /recovery/sbin/static
(see below for more info about recovery options), and add
those paths to the list of paths (listpaths[]) that
sys/kern/init_main.c::start_init() tries to exec.
The former is simpler, and less intrusive whilst experimenting with
the system. The latter still providss for recovery.
| > Provide an optional recovery mechanism such as /stand/{,s}bin
| > which contains statically linked versions of some (or all) of
| > the programs in /{s,}bin.
|
| what's the thought of how to invoke the recovery mode? (can't invoke
| sh for rc, time to recover?) I think the possibility of a special
| 'recovery kernel' is losing. (If you're the klutz who rm'd libc.so,
| what are the odds you've got a correct recovery kernel? 8-)
|
| I think some thought has to be put into the set of programs for
| recovery. Maybe it's the current set of /sbin & /bin, maybe it's more
| or less.
My test machine now has /recovery/bin and /recovery/sbin, as a full
copy of the old statically linked /bin and /sbin. This is good for
testing, but does consume more disk space :)
My current thoughts are that a /recovery directory (either single
level, or with bin and sbin subdirectories), containing statically
linked versions of tools that are useful to help recovery, is the
best approach. The list of tools could be the set of /sbin and /bin,
although arguably it could more like the list of tools provided in the
ramdisk install media.
Andrew Brown sent me details of a /recovery he built from
src/distrib/i386/floppies/ramdisk-big as a possible solution to this
problem. It's a crunchgen-ed binary, consumes approximately 1.6MB,
and contains:
[ bad144 cat cd9660 chgrp chio chmod chown chroot cp dd df
dhclient disklabel ed fdisk ffs fsck fsck_ffs ftp gunzip
gzcat gzip halt ifconfig init installboot kernfs less ln
ls mbrlabel mkdir mknod more mount mount_cd9660 mount_ext2fs
mount_ffs mount_kernfs mount_mfs mount_msdos mount_nfs
mount_ntfs msdos mt mv newfs nfs ntfs pax ping ping6 pwd
rcmd reboot rm route rtsol scsictl sed sh shutdown slattach
stty swapctl sync sysinst tar test tgt tip umount wiconfig
Obviously we'd need to put more thought into this list of tools, but
this example shows how small we can make things.
In the case of a broken ld.so (or whatever), recovery is not much
different than today:
- If you are already logged in to your system you'd just
use the tools in /recovery instead of /bin and /sbin.
- If you reboot to single user mode, you can specify
/recovery/sh as the shell. If /sbin/init was dynamically
linked (see above), the kernel could just try
/recovery/init as an alternative (see above).
| > - dynamic linked applications apparently run slower
| > than statically linked applications.
| > Adding support for "prebinding" (in the newer
| > binutils toolchain for some platforms) alleviates
| > most (if not all) of this.
|
| s/apparently//
|
| Does pre-binding do anything to touch the 'runs slower' problem? (I
| thought it just helped -- but did not completely address -- the
| 'starts slower' problem.)
I'm not an expert here; I'll defer to the toolchain experts here.
Regarding the overhead of dynamic linked applications, I took a look
at the accounting information from my main machine. The top 30 lines
are:
# sa -an | head -30
776734 6350389.44re 967.79cp 35avio 0k
221246 9.29re 0.03cp 5avio 0k rpc.rstatd
113055 1956.75re 0.08cp 0avio 0k sh*
76755 60617.01re 2.11cp 0avio 0k sh
44794 4.05re 0.62cp 0avio 0k sed
42463 3.27re 0.02cp 0avio 0k formail
28948 870497.72re 35.56cp 4avio 0k ssh
21343 1.69re 0.00cp 1avio 0k procmail*
21120 158.18re 4.91cp 9avio 0k procmail
14944 37.45re 0.58cp 6avio 0k rm
12431 11318.53re 0.04cp 0avio 0k cat
12293 25.23re 8.85cp 3avio 0k cpp
12143 0.34re 0.00cp 1avio 0k rpcbind*
12137 934.51re 6.05cp 3avio 0k make
11035 217.30re 0.05cp 1avio 0k cc
10339 1.08re 0.03cp 1avio 0k pkg_info
8703 168.49re 58.33cp 0avio 0k cc1
7815 12.61re 2.28cp 1avio 0k as
6975 1.74re 0.02cp 0avio 0k egrep
6564 3.37re 0.06cp 0avio 0k awk
5555 24.33re 0.03cp 0avio 0k diff
4688 0.07re 0.13cp 0avio 0k uname
4335 5.53re 0.66cp 8avio 0k ls
3612 30.35re 1.39cp 19avio 0k grep
3362 46358.63re 2.12cp 1avio 0k less
3104 0.47re 0.02cp 3avio 0k install
2975 6.83re 3.83cp 2avio 0k ld
2838 6.97re 0.03cp 0avio 0k collect2
2741 0.06re 0.00cp 0avio 0k arp
2648 33478.41re 9.73cp 22avio 0k vi
Of those, the following are statically linked:
sh rm cat ls
(My shell - tcsh - has an inbuilt ls(1), which explains why ls is low
on that table)
Whilst the overhead of starting dynamic linked applications does
exist, the majority of programs that I use are dynamically linked
so I'm already "feeling this pain", and I'd argue that the vast
majority of users are in the same situation.
I.e, fixing this startup slowness of dynamic linked applications
should be investigated, even separately to this proposal!
| From where I sit, just to be up front about it:
|
| * the system needs to continue supporting creation of new
| statically-linked binaries which have normal basic functionality
| (i.e. passwd file and group lookups, DNS, etc.) that you'd expect. At
| the very least, you probably want people to be abile to run SPEC
| statically-linked. 8-)
For the specific case of adding dynamic module support to nsswitch,
my intention has always been to support both compiled-in and
dynamically loaded databases (e.g, "nis", "files"), etc, with
user controlled overrides in nsswitch.conf as to which linkage takes
priority.
As mentioned above, compilation of static binaries would still be
possible; said programs just would not have support for the funkier
features that the libc.so tools would provide. (Similar to the way
that dynamic loading of multibyte regions is not available for
statically linked programs).
| * (with the same caveat) it should remain possible to build a complete
| system statically, or to build parts of the system statically as is
| currently done. (You don't like it? Don't do it. Oh, you wanted
| those fancy new features? You chose to not enable them; feel free to
| enable them at your convenience. 8-)
Yes. :)
| Personally, on some systems (mostly, systems where i've got root on
| NFS), I've been using completely dynamically linked systems for years,
| and loving it. As long as you're careful (i have rm aliased to rm -i
| everywhere 8-) it's a good choice for an individual user, and if good
| recovery tools are provided I think it's a fine choice for the system
| as a whole.
Providing good recovery tools is definitely my goal. Other systems
like Solaris and Linux often have good ideas but the implementation
needs refinement, and it is not necessary to avoid the functionality
because of bad experience with a flawed implementation. I believe
strongly in good recovery tools because of this.
| Really, I don't think _I'd_ mind if we wanted to move in the direction
| of / & /usr on same partition. However, I suspect I'd have little
| company there, and people with ancient, small disks would howl (for
| good reason, I suppose; it's probably hard to replace some of them, at
| this point)...
I personally prefer keeping / and /usr together, but I have no
intention of forcing any particular requirement down people's throats
here. That's why I proposed the /lib stuff in the first place.
I have working versions of the third and fourth proposed solutions
(moving /usr/lib/*.so -> /lib, moving parts of /usr/lib/*.so -> /lib),
and pointers to building a reasonable /recovery system, and will
expand on that in a separate email.
Thanks for your comments and feedback,
Luke.
--
Luke Mewburn <lukem@wasabisystems.com> http://www.wasabisystems.com
Luke Mewburn <lukem@netbsd.org> http://www.netbsd.org
Wasabi Systems - NetBSD hackers for hire
NetBSD - the world's most portable UNIX-like operating system