# genkernel + gPXE + diskless+unionfs problem

## redwood

I have an etherboot+ltsp-4.2 working setup which I'd like to convert to my own

gentoo-compiled diskless setup with unionfs.

I've followed the guide

http://www.gentoo.org/doc/en/diskless-howto.xml

as well as the forum discussion

http://www.gentoo.org/doc/en/diskless-howto.xml

and  wimalopaan's 2005 German guide

http://mozart.informatik.fh-kl.de/download/Software/GentooDiskless/diskless.pdf

and the updated English version

http://mozart.informatik.fh-kl.de/download/Software/GentooDiskless/diskless2_en.pdf

wimalopaan's guide modifies numerous /etc/init.d/scripts by commenting out services which

are no longer needed; whereas the updated guide includes a "stateless.sh" script to replace the

bootup init script.

/tftpboot/gentoo/boot/stateless.sh:

```
#!/bin/bash                                                                                               

MODPROBE=/sbin/modprobe                                                                                    

IFCONFIG=/sbin/ifconfig                                                                                    

ahostname (){                                                                                              

   MYHOST="$1_`$IFCONFIG eth0 | awk '/HWaddr/ {print $5}' | tr -d ':'`"                                    

   echo "STATELESS: Setting Hostname to $MYHOST"                                                           

   echo "HOSTNAME=\"$MYHOST\"" > /etc/conf.d/hostname                                                      

   /bin/hostname "$MYHOST"                                                                                 

}                                                                                                          

getparams() {                                                                                              

   local cmdline=$(dmesg | grep "^Kernel command line" | sed 's/^Kernel command line ://g')                

   for pp in cmdline; do                                                                                   

      echo $pp | grep '^stateless=' >/dev/null 2>&1                                                        

      if [ $? -eq 0 ]; then                                                                                

         echo $pp | sed 's/stateless=//g'                                                                  

         return 0                                                                                          

      fi                                                                                                   

   done                                                                                                    

   echo ""                                                                                                 

   return 1                                                                                                

}                                                                                                          

isset() {                                                                                                  

   for p in $( getparams | tr ',' ' ' ); do                                                                

      if [ "$p" == "$1" ]; then                                                                            

         return 0                                                                                          

      fi                                                                                                   

   done                                                                                                    

   return 1                                                                                                

}                                                                                                          

aunionfs() {                                                                                               

   isset unionfs                                                                                           

   if [ $? -eq 0 ]; then

      echo "STATELESS: Loading module unionfs ..."

      $MODPROBE unionfs

      while [ "$1" != "" ]; do

      echo "STATELESS: Mounting tmpfs $1 ..."

      mount -n -t tmpfs -o defaults none /mnt/unionfs/$1

      echo "STATELESS: Mounting $1 unionfs ..."

      mount -n -t unionfs -o dirs=/mnt/unionfs/$1=rw:/$1=ro none /$1

      shift

      done

   else

      echo "STATELESS: Not using unionfs as requested ..."

   fi

}

aunionfs etc var

ahostname stateless

exec /sbin/init
```

I downloaded gPXE from http://etherboot.org with git

and compiled and made a gPXE boot floppy.

I've created a 5G lvm2 ext3 partition mounted on /tftpboot/gentoo

and installed a fresh PentiumII system on that partition following my usual guide

http://www.gentoo.org/doc/en/gentoo-x86+raid+lvm2-quickinstall.xml

And I've compiled a client kernel using

 *Quote:*   

> genkernel --splash --menuconfig all

 

with my nic drivers compiled in as well as 

the following networking options

```
Networking  --->-*- Networking support Networking options  --->

[*]   IP: kernel level autoconfiguration

[*]     IP: DHCP support

[*]     IP: BOOTP support
```

I created a /tftpboot/pxe directory (following the ltsp setup)

containing pxelinux.0 and the 

symlink gentoo -> /tftpboot/gentoo (to find my diskless partition)

and the pxelinux.cfg directory containing the default setup:

```
prompt 0

label linux

kernel /gentoo/boot/kernel-genkernel-x86-2.6.25-gentoo-r8

append ip=dhcp root=/dev/ram0 real_root=/dev/nfs nfsroot=192.168.1.254:/tftpboot/gentoo hard,intr,ro  initrd=/gentoo/boot/initramfs-genkernel-x86-2.6.25-gentoo-r8 init=/gentoo/boot/stateless.sh vga=791 splash=silent,theme:defaultconsole=tty1 quiet
```

My server:/etc/dhcp/dhcp.conf:

```

#(Some general options)                

#Global defaults                       

not authoritative;                              # only primary servers use authoritative

#default-lease-time            21600;           # 6 hours                               

#max-lease-time                21600;           # 6 hours                               

default-lease-time              28800;          # 8 hours                               

max-lease-time                  86400;          # 1 day                                 

use-host-decl-names             on;                                                     

ddns-update-style               ad-hoc;         # Dynamic DNS update style (off,interim,ad-hoc)

#(Bootp options)

allow booting;  

allow bootp;    

boot-unknown-clients            false;          # Prevent random machines

#(Network Options) 192.168.1.0/24

option subnet-mask            255.255.255.0;

option broadcast-address      192.168.1.255;

option routers                192.168.1.1;      #The default gateway (our Linksys WRT54G router)

option domain-name-servers    192.168.1.254, 192.168.1.1;                                       

option log-servers            192.168.1.254;    #The box that accepts logging                   

#option nntp-server             10.0.0.11;      # The Ntp time server                           

option domain-name            "mydomain.net";                                                     

#range 10.0.0.100 10.0.0.150;                   # Comment this if you have another DHCP server  

#(LTSP Path Options)

option root-path              "192.168.1.254:/opt/ltsp/i386";

#option domain-name     "ltsp.mydomain.net";      # A fake domain-name for our thin-clients                                

# Specify the TFTP server to be used

next-server                   192.168.1.254; 

option space PXE;

option PXE.mtftp-ip               code 1 = ip-address;

option PXE.mtftp-cport            code 2 = unsigned integer 16;

option PXE.mtftp-sport            code 3 = unsigned integer 16;

option PXE.mtftp-tmout            code 4 = unsigned integer 8; 

option PXE.mtftp-delay            code 5 = unsigned integer 8; 

option PXE.discovery-control      code 6 = unsigned integer 8; 

option PXE.discovery-mcast-addr   code 7 = ip-address;         

option pxe-menu                   code 150 = text;

# gPXE-specific encapsulated options

#                                   

option space gpxe;                  

option gpxe-encap-opts          code 175 = encapsulate gpxe;

option gpxe.priority            code 1 = signed integer 8;  

option gpxe.no-proxydhcp        code 176 = unsigned integer 8;

option gpxe.bus-id              code 177 = string;            

option gpxe.bios-drive          code 189 = unsigned integer 8;

option gpxe.username            code 190 = string;            

option gpxe.password            code 191 = string;            

# Other options that may be useful                             

option iscsi-initiator-iqn code 203 = string;

#(If your workstations have ISA NICs uncomment the following)

#(lines and alter the driver and IO)                         

# PXE & legacy options                                       

option option-128               code 128 = string; # required for PXE boot

option option-129               code 129 = text;   # required for PXE boot

option option-128               e4:45:74:68:00:00; # magic value for PXE booting

shared-network WORKSTATIONS {

  subnet 192.168.1.0 netmask 255.255.255.0 {

    #(Distribute dynamic IPs to the workstations)

    range 192.168.1.11 192.168.1.20;            

    use-host-decl-names on;                     

    allow unknown-clients;

    class "pxeclient" {                             

       match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";

       vendor-option-space PXE;                                               

       option PXE.mtftp-ip 0.0.0.0;

       #option pxe-menu "/pxe/grub.1st";

       # This is the name of the file the boot ROMs should download.

       #filename "/gentoo/boot/grub/pxegrub";                       

       filename "/pxe/pxelinux.0";                      #tftp gPXE kernel       

      #filename "http://my.web.server/pxe.0";   # http              

    }

#   Provide Etherboot clients with appropriate information

    class "etherboot" {                                   

       match if substring(option vendor-class-identifier, 0, 9) = "Etherboot";

       filename "/lts/vmlinuz-2.6.17.8-ltsp-1";     # tftp Etherboot kernel            

      #filename "http://my.web.server/pxe.0";   # http boot                   

    }

    group DISKLESS { #workstation nodes

        host ws002 {

                hardware ethernet       <mac address>;

                option option-129 "NIC=8139too vga=788";

        }

    }

 }
```

My server:/etc/exportfs

```
/tftpboot/gentoo        192.168.1.*(ro,sync,no_all_squash,no_root_squash)
```

and my client:/etc/fstab

```
192.168.1.254:/tftpboot/gentoo  /       nfs             defaults,hard,intr,ro,rsize=8192        0 0

/dev/cdrom              /mnt/cdrom      auto            noauto,ro       0 0

shm                     /dev/shm        tmpfs           nodev,nosuid,noexec     0 0

proc                    /proc           proc            defaults                0 0

none    /mnt/unionfs/var        tmpfs   defaults        0 0

none    /mnt/unionfs/etc        tmpfs   defaults        0 0

none    /var    unionfs         dirs=/mnt/unionfs/var=rw:/var/=ro       0 0

none    /etc    unionfs         dirs=/mnt/unionfs/etc=rw:/etc/=ro

none    /tmp    tmpfs   defaults        0 0
```

After booting the diskless client with the gPXE boot floppy

the client correctly downloads /tftpboot/gentoo/boot/kernel-genkernel-x86-2.6.25-gentoo-r8

and begins booting.

However, it then tries to mount the root filesystem rw

which is denied by my server's /etc/exportfs line.

Is something wrong with my server's /tftpboot/pxe/pxelinux.cfg/default file?

THANKS for any ideas.

UPDATE:

the gentoo-wiki is off-line, but I've learned I need sys-kernel/mm-sources for unionfs support.

I've gotten my kernel to load using this

/tftpboot/pxe/pxelinux.cfg/default:

```
kernel /gentoo/boot/linux

append ip=dhcp root=/dev/nfs nfsroot=192.168.1.254:/tftpboot/gentoo,hard,intr,ro tty:12 console=tty1 init=/boot/stateless.sh
```

I just need to compile a kernel with unionfs support.

----------

