# Lazy client part III



In my ongoing effort to make my lazy client work I've embarked on
the next phase of the project: Making a client boot from a generic
NFS mounted root partition and then giving it its own /etc on a ramdisk.

This way I'm saving disk space and administration overhead on my
server. The virtual /etc is provisioned by `cfengine`. This allows
for small changes between the lazy clients while they still share
the bulk of the rest of the files.

In Debian and Ubuntu the first script that is started when
`init` is booting is:

    # grep sysinit /etc/inittab
    si::sysinit:/etc/init.d/rcS

`/etc/init.d/rcS`. This will be a good starting point to make
a ramdisk and copying /etc over to the ramdisk and then restarting
the boot-up.

The script itself is small:

    #! /bin/sh
    #
    # rcS
    #
    # Call all S??* scripts in /etc/rcS.d/ in numerical/alphabetical order
    #

    exec /etc/init.d/rc S

# Ramdisk
What is needed to make a ramdisk? I'm going to use `tmpfs` here.
First we need an empty directory which will hold our ramdisk. As
this directory is created on the shared (NFS) filesystem, we need
some way to make this directory random. As this is the first
script run from `init` it will probably have a low `PID`, so
using `$$` is not a good idea as it might be not so random. 
Let's use `/bin/mktemp` to create a dir, mount it as a ramdisk,
copying /etc over and re-mounting it over `/etc`. Like this

    # make a unique directory
    RAMDISK=$(mktemp -d -p /var/tmp ram.XXXXXX)

    # mount it as tmpfs disk
    /bin/mount -t tmpfs tmpfs $RAMDISK

    # next copy /etc over
    /bin/cp -rap /etc $RAMDISK

    # mount this "new" disk UNDER /etc
    /bin/mount -o bind $RAMDISK /etc

 The final script
When putting this together the following *SHOULD* work. I say
should here, because I haven't tested this (yet).

    #! /bin/sh
    #
    # rcS
    #
    # Call all S??* scripts in /etc/rcS.d/ in numerical/alphabetical order
    #

    # make a unique directory
    RAMDISK=$(mktemp -d -p /var/tmp ram.XXXXXX)

    # mount it as tmpfs disk
    /bin/mount -t tmpfs tmpfs $RAMDISK

    # next copy /etc over
    /bin/cp -rap /etc $RAMDISK

    # mount this "new" disk UNDER /etc
    /bin/mount -o bind $RAMDISK /etc

    # start the rest 
    exec /etc/init.d/rc S

Somewhere in the boot process `cfengine` comes along and will
configure this host. The only thing needed for that is that
`cfengine` needs to know which host it is configuring. One idea
could be to put the IP number of a host in `/proc/cmdline` and then
have a module look at the file.

If this works then `cfengine` can work its magic.

 Links
Other postings about this subject:

* [Part I](/2008/july/24/not_thin_not_thick_but_lazy/index.html)
* [Part II](/2008/september/28/lazy_client_part_ii/index.html)

# Update
It works! More postings on this later

