

Static Linux - joseflavio
http://sta.li/

======
zackmorris
I wish Linux would replace dynamic libraries (especially ones referencing
specific paths) with a system based on the library's hash. Then we could have
a single lib folder with 1 copy of each library, and get ourselves out of
dependency hell by just making dynamic loading act like static loading. We
could even download libraries from the web on the fly, if needed. Heck it
would even remove a lot of the need to compile every_single_time because apps
could reference binaries.

The notion of being able to fix an app by merely upgrading a library it
depends on has not worked out in practice. More often than not, when I upgrade
a library, I find myself having to upgrade my app’s code because so much has
changed. The burden of having to constantly backup, upgrade, manually tweak
config files, over and over and over again for days/weeks/months was SO not
worth the few hundred megabytes or whatever dynamic loading was supposed to
have saved.

~~~
deathanatos
> I wish Linux would replace dynamic libraries (especially ones referencing
> specific paths) with a system based on the library's hash.

Given this scheme, how would you distribute a security patch? Is each user of
the library supposed to re-compile against the patched library?

Also, a program A depends on library B and library C v1.1. Library B also
depends on C, but v1.2. Which gets used?

> More often than not, when I upgrade a library, I find myself having to
> upgrade my app’s code because so much has changed.

To me, this is the point of major version numbers. If you break clients, you
increment the major version number, resulting in libfoo.so.2 and libfoo.so.3.
Then, the scheme becomes much like hashes, in that newer versions won't break
older clients, except you get security patches and a single copy of the
library. However, the responsibility of knowing when to increment the major is
left to a human, and all the error that entails.

As a sibling notes, there are distros out there that do this. (They are not my
preference, for the above reasons.)

~~~
chongli
>Given this scheme, how would you distribute a security patch? Is each user of
the library supposed to re-compile against the patched library?

No, this is the responsibility of the server which distributes binaries to
users via the package manager.

~~~
palunon
User, as in programmer who uses the library.

~~~
chongli
Programmers are used to recompiling all the time. What's the problem here?

------
ultramancool
Cool idea. Not enough people seem aware of executable packers like UPX
[http://upx.sourceforge.net/](http://upx.sourceforge.net/) though.

These are excellent tools to keep the size down when using large static
binaries. By compressing the file on disk and decompressing in memory you
often wind up with a smaller and sometimes even faster loading (depending on
disk IO speed vs decompression speed) package. I got a static Qt binary from 4
MB down to 1.3 with upx --lzma. Very nice stuff.

~~~
Lerc
The downside to tools like UPX is that the executable code is actively
transformed on load. This limits the ability to use shared memory for multiple
concurrent executions of the same executable.

If the OS loads executables by mmap and load on page-hit, you can potentially
save memory by not ever loading unused parts of an executable. a transform-on-
load requires the entire program to be loaded before execution begins.

~~~
GeorgeTirebiter
'... never loading unused parts of an executable...' \- this is one of the
benefits of a paging system. Paging was (is?) the best way to keep memory
requirement down. The way Multics worked was by having paged segments.
[http://www.osinfoblog.com/post/136/segmentation-with-
paging:...](http://www.osinfoblog.com/post/136/segmentation-with-
paging:-multics/) The x86(-64) can support something like this, but as far as
I know, no modern OS supports this feature.

~~~
asuffield
Linux does this, as does basically every other modern OS.

Pick a random large process on a linux host - like your web browser. cat
/proc/$pid/status.

VmExe is the size of the mapped executable; VmLib is the size of all the other
mapped libraries and executable pages. Add those two numbers together to find
the size of all the executable code mapped into this binary.

VmRSS is the amount of physical memory that the process is currently using.
You'll find that this is a lot smaller than the code mapped into the binary.
That's because the kernel hasn't loaded any of that into physical memory.

~~~
GeorgeTirebiter
Thank you. I'm not at all sure why the 'old hands' here on HN have decided to
so viciously downvote this. I didn't call anybody names, didn't violate any
posting rules, did not violate etiquette, and provided a very nice link to
Multics.

If there is a perceived error in what I wrote, then, like the one nice
responder, explain, please.

HN is such a different community now than when I joined 1,835 days ago. It
brings tears to my eyes.

------
stonogo
I have been keeping an eye on this "project" for years and have yet to see
anything come of it except lightning talks.

suckless.org seems to focus on their web browser and their xterm clone these
days, judging by the listserv traffic.

~~~
saysjonathan
Sin, the original author and maintainer of a few of the suckless utils
necessary for Stali, has a similar project called Morpheus[0]. He has actually
shipped a bootable image for testing and has more or less gotten the packaging
sorted out[1].

If you're interested in the idea, definitely check it out.

0: [http://morpheus.2f30.org](http://morpheus.2f30.org) 1:
[http://morpheus.2f30.org/0.0/packages/x86_64/](http://morpheus.2f30.org/0.0/packages/x86_64/)

~~~
vezzy-fnord
A similarly interesting project is the musl-based Sabotage Linux with its own
tiny but concurrent package manager: [https://github.com/sabotage-
linux/sabotage](https://github.com/sabotage-linux/sabotage)

~~~
saysjonathan
Much of the bootstrapping of Morpheus appears to have come from Sabotage
Linux, especially the use of musl-cross[0]. I thought I remember seeing
numerous references to Sabotage in the docs but now I can't seem to find them.

Anyhow, definitely another interesting project in a similar vein. The biggest
difference I see, from a base perspective, is the choice of coreutils
replacement: Sabotage uses Busybox while Morpheus uses a mixture of sbase[1],
ubase[2], hbase[3] (rewrite of heriloom utils[4]), and 9base[5] (some utils
from plan9port[6].)

0\. [https://github.com/sabotage-linux/musl-
cross](https://github.com/sabotage-linux/musl-cross) 1\.
[http://git.2f30.org/sbase/](http://git.2f30.org/sbase/) 2\.
[http://git.2f30.org/ubase/](http://git.2f30.org/ubase/) 3\.
[http://git.2f30.org/hbase/](http://git.2f30.org/hbase/) 4\.
[http://heirloom.sourceforge.net](http://heirloom.sourceforge.net) 5\.
[http://git.suckless.org/9base/](http://git.suckless.org/9base/) 6\.
[http://swtch.com/plan9port/](http://swtch.com/plan9port/)

~~~
vezzy-fnord
The README for hbase characterizes it differently:

    
    
       hbase is a collection of programs that complements sbase
       and ubase. It's meant to be a temporary project that
       will shrink and die once sbase and ubase gets
       implementations of most of the programs included. hbase
       mostly contains programs taken from the Heirloom project,
       but also has other programs, such as patch taken from
       FreeBSD and mk taken from plan9port.
    

So it's not a rewrite, but rather a temporary code dump for "miscellaneous
utilities". Skimming at the code confirms this.

~~~
saysjonathan
Correct. When I said 'rewrite', I mean 'update of some'.

------
TsukasaUjiie
"Of course Ulrich Drepper thinks that dynamic linking is great, but clearly
that’s because of his lack of experience and his delusions of grandeur." I
find these kind of comments reflect veerryyy poorly on their authors..

------
dfc

      > Because dwm is customized through editing its source code, it’s
      > pointless to make binary packages of it. This keeps its userbase
      > small and elitist. No novices asking stupid questions.
    

I never understood why the authors of dwm thought this was a "nice" feature of
configuration via source code.

~~~
ertdfgcb
They don't mind if DWM is only ever used by a handful of people if only a
handful of people agree with the principles behind it.

------
gnufx
Apart from the general system management advantages of dynamic libraries, they
provide an important extensibility/customization mechanism (e.g.
[https://www.gnu.org/software/emacs/emacs-
paper.html](https://www.gnu.org/software/emacs/emacs-paper.html) for an early
mention).

High performance computing systems typically use dynamic linking extensively
for that. One example: The hooks for profiling and tool support in the MPI
standard for parallel programming pretty much depend on an LD_PRELOAD-type
mechanism to be useful. Another: You can cope with the mess due to missing
policy on BLAS libraries in Fedora/EPEL (unlike Debian) by using OpenBLAS
replacements for the reference and ATLAS libraries; have them preferred by
ld.so.conf and get a worthwhile system-wide speed increase on your Sandybridge
nodes with EPEL packages.

Anyhow, rebuilding a static system to address a problem with a library ignores
all its uses in user programs. The ability to adjust things via properly-
engineered dynamic libraries really has a lot more pros than cons in my non-
trivial experience. The use of rpath ("ones referencing specific paths"?) is
mostly disallowed by packaging rules in the GNU/Linux distributions I know, so
I'm not sure where that comment came from, and it tends to defeat the
techniques above.

------
leakybucket
An advantage of dynamic libraries is that the memory used to hold the
library's executable pages can be shared across processes. So using static
only binaries will lead to less free memory on the OS.

~~~
Animats
That's the party line. It's often wrong. If two copies of the same program are
running, they share memory for code. For a shared library to reduce memory
consumption, there must be multiple _different_ programs using the _same_
version of the _same_ library. That's not all that common, beyond very basic
libraries such as "libc".

Linking to a shared library brings in and initializes the whole library, even
if you only need one function from it. So you tend to get stuff paged in
during load that never gets used.

~~~
icebraining
_That 's not all that common_

Isn't it? Usually distros target their packages to a single library version,
and often people run suites (Gnome, KDE, etc) that use a similar set of
libraries in their different processes.

~~~
cplease
Indeed. ldd any substantial GTK app and scroll past the dependencies. They are
huge. Most of them are shared across applications.

Desktop would be crippled if every app was compiled with the whole stack of X,
toolkit and Gnome libraries linked in statically.

~~~
ANTSANTS
I'd argue that libraries like GTK were only allowed to become so bloated
because dynamic linking masked their true impact on the system. If static
linking were the norm, we'd be using _much_ simpler, cleaner libraries because
people would think twice about adding 100+ megabytes to their binaries for
basic GUIs.

------
curlyquote
Static linking OpenSSL is probably not a good idea

~~~
AjithAntony
You mean for security patches? i.e rebuilding all your binaries, instead of
just openssl's shared libs

------
w8rbt
One downside to static linking is security vulnerabilities. Say, for example
that all the programs on your computer that use OpenSSL statically link. When
OpenSSL has a security flaw, you have to not only update OpenSSL, but all of
those other programs too.

------
proveanegative
Are there any static BSDs?

~~~
justincormack
You can build NetBSD to be statically linked [1]. It is not the default, but
it is trivial to do, one line config change. Note that you can build NetBSD
from source on any system, eg Linux or OSX and then boot it in a VM, so you
dont really need a binary "distro".

[1] [https://www.netbsd.org/docs/guide/en/chap-build.html#chap-
bu...](https://www.netbsd.org/docs/guide/en/chap-build.html#chap-build-
environment-static-build)

------
kkedacic
I would like to see "static" USE flag in Gentoo for all packages with ability
to statically link whole system. Also profiles or env with other libc's would
be nice. Dunno why they need to crate new distribution instead of expanding
ones that are already there.

------
enthdegree
Stali has been in 'planning' for as long as I can remember. At least 4 years.

------
spiritplumber
Wonder if it helps with dep hell...

~~~
bch
It would for a certain class of hell. You won't get issues w/ resolving
symbols in dynamic libs, but you _would_ open yourself to feature disparity
across different apps that use similar libs. For example, if you've got a
Client-A that uses libfoo feature X(v1), and Client-B that shipped w/ and
links against libfoo feature X(v2), it might be frustrating -- this scenario
is part of the promise (and responsibility) of shared libraries.

Can't have your cake and eat it too.

~~~
mwilliamson
And that feature disparity includes security updates. If a library is updated
with a security fix, you'll need to update everything that uses that library
to get the fix, rather than just the shared dynamic library.

~~~
Lerc
The tools for updating security fixes should be applicable for the
applications just as easily as the libraries. The applications would have to
be rebuilt which should be automated. If the library changes anything that
causes the build to fail, much better to find that out at that time than to
have the failure occur when it dynamically links on end user machines.

There would be inevitable bandwidth costs in updating like this, but that is
the trade-off that is Explicitly made by choosing to go with static.

~~~
bch
> The tools for updating security fixes should be applicable for the
> applications just as easily as the libraries...

I don't think anybody would disagree, but you can't dismiss out-of-hand this
required effort. The point is there _are_ pros and cons. Its arguable that one
really ought to have a build-server to mitigate the effect/work. For an
OS/distribution, this would be a repository of binaries that are maintained,
and you could do an (eg) apt-get update and have the proper software fixed
(for your "enterprise" or similar software, a similar in-house mechanism) --
if everything is static, the act of replacing the binaries on the end-machine
ought to be relatively simple for binary replacement, with the effort for
library maintenance moved to maintaining an "out of band" record of what libs
ea. app is using, so that when you have a flaw in libxyz that client-a,
client-b, and client-c are using, you _know_ you need to update the source for
client-[a-c] one way or another -- it boils down to a case of responsibility
-- are you going to build safeguards into the link/run mechanism (dynamic
libs) and have it adopt a certain amount of responsibility or move the cost
upfront to build/maintenance and manage the responsibility yourself (with some
other appropriate tooling)...

