Subject: Re: Shrinking NetBSD - deep final distribution re-linker
To: None <tech-embed@netbsd.org>
From: Ian Zagorskih <ianzag@megasignal.com>
List: tech-userlevel
Date: 10/20/2004 12:58:50
On Tuesday 19 October 2004 19:49, Jared Momose wrote:

> >Sorry for quite confusing subject, just i don't know how exactly express
> > my ideas :) Not sure where exactly should i post this message..
>
> tech-embed is definitely the place for this type of discussion.
>
> it sounds like you are describing crunchgen. man crunchgen, and take a look
> at src/distrib/i386/floppies/ramdisk-big/list for an example. crunchgen
> does have limitations and caveats (which i can enumerate upon request) but
> all can be worked around in one way or another. and there is an advantage
> of sharing all common code pages w/o ld glue. :^)

Thank you for response, i'v checked crunchgen and found this utility to be 
very nice :) Though i have several questions..

Let's say we'r using NetBSD-current:
$ uname -a
NetBSD IANZAG 2.99.10 NetBSD 2.99.10 (IANZAG-ACPI) #0: Mon Oct 18 17:31:49 
NOVST 2004  ianzag@IANZAG:/usr/src/sys/arch/i386/compile/IANZAG-ACPI i386

Let's make a simple test. Configuration file for crunchgen is:

---single.conf---
srcdirs /usr/src/bin
progs cat chmod cp date dd df echo expr kill ln ls mkdir mv ps pwd rm rmdir sh 
sleep stty sync test
ln test [
ln sh -sh
libs -lutil -lkvm -lm -ll -ledit -ltermcap
---single.conf---

I.e. we want to put almost complete /bin subset into single crunched 
executable.

$ crunchgen -m Makefile single.conf
$ make objs
$ make exe
$ strip single

As a result, we'v got statically linked and stripped single executable:

$ ls -l single
-rwxr-xr-x  1 ianzag  wheel  688376 Oct 19 21:02 single
$ size single
   text    data     bss     dec     hex filename
 626618   17904  109468  753990   b8146 single

Futher this is just a technical question to make proper hard or symbolic links 
on the target file system and so on. Let's omit this trivial phase.

For the same set of dynamically linked utilities included in 
single + required shared libraries (all are stripped too) we have smth like 
below:

---cut---
$ ls -l
total 2842
-r-xr-xr-x  2 root  wheel    7640 Oct 19 21:11 [
-r-xr-xr-x  1 root  wheel    7932 Oct 19 21:11 cat
-r-xr-xr-x  1 root  wheel    6360 Oct 19 21:11 chmod
-r-xr-xr-x  1 root  wheel   15452 Oct 19 21:11 cp
-r-xr-xr-x  1 root  wheel    9060 Oct 19 21:11 date
-r-xr-xr-x  1 root  wheel   19048 Oct 19 21:11 dd
-r-xr-xr-x  1 root  wheel   10248 Oct 19 21:11 df
-r-xr-xr-x  1 root  wheel    4396 Oct 19 21:11 echo
-r-xr-xr-x  1 root  wheel   11480 Oct 19 21:11 expr
-r-xr-xr-x  1 root  wheel    6412 Oct 19 21:11 kill
-r--r--r--  1 root  wheel  766972 Oct 19 21:11 libc.so.12.122
-r--r--r--  1 root  wheel  100112 Oct 19 21:11 libedit.so.2.9
-r--r--r--  1 root  wheel   23268 Oct 19 21:11 libkvm.so.5.2
-r--r--r--  1 root  wheel  113444 Oct 19 21:11 libm.so.0.2
-r--r--r--  1 root  wheel    8164 Oct 19 21:11 libm387.so.0.0
-r--r--r--  1 root  wheel   10072 Oct 19 21:11 libtermcap.so.0.5
-r--r--r--  1 root  wheel   37520 Oct 19 21:11 libutil.so.7.4
-r-xr-xr-x  1 root  wheel    5988 Oct 19 21:11 ln
-r-xr-xr-x  1 root  wheel   19948 Oct 19 21:11 ls
-r-xr-xr-x  1 root  wheel    5996 Oct 19 21:11 mkdir
-r-xr-xr-x  1 root  wheel    9020 Oct 19 21:11 mv
-r-xr-xr-x  1 root  wheel   32492 Oct 19 21:11 ps
-r-xr-xr-x  1 root  wheel    5040 Oct 19 21:11 pwd
-r-xr-xr-x  1 root  wheel   10164 Oct 19 21:11 rm
-r-xr-xr-x  1 root  wheel    4908 Oct 19 21:11 rmdir
-r-xr-xr-x  1 root  wheel  110008 Oct 19 21:11 sh
-r-xr-xr-x  1 root  wheel    5220 Oct 19 21:11 sleep
-r-xr-xr-x  1 root  wheel   17228 Oct 19 21:11 stty
-r-xr-xr-x  1 root  wheel    4140 Oct 19 21:11 sync
-r-xr-xr-x  2 root  wheel    7640 Oct 19 21:11 test
$ du -k
1414    .
---cut---

I.e. crunched executable saves us about 50..60% of disk space in comparison to 
the base set of utilites. Really not bad, indeed !

Now, some ideas that came in my mind..

1. Crunched executable is statically linked. Does it mean, that when i load 
any crunched "utility" dynamicall linker loads the whole executable imageinto 
memory every time? I.e. it makes an own dedicated copy of code/data sections 
for each exec() and code sections are not shared between different processes? 
If i'm right in my guess, crunchgen let me save my disk space but as the 
price it heavily increases RAM usage and, most likely, time to start 
executables. Specially when file system is located on relatively slow flash 
media.

2. AFAIU crunchgen requires source or at least object code to link target 
executable. Even more, for source code crunchgen expects project to be 
organized in NetBSD <category>/<utility> way i.e. using bsd.mk framework. If 
i'm right in my guess, this makes an obvious and quite serious limitation 
where crunchgen may be used. For example, i have different projects each of 
them using different project management frameworks and none of them uses 
bsd.mk :) Futher more, i have some binary-only shared libraries i'd to use in 
some projects..

Treat me correct, i do not want to say anything against crunchget. This is an 
excellent utility for it's tasks (as was shown above). Just i think that 
crunchgen does not cover the whole tasks  in resource usage optimization.

// wbr