aboutsummaryrefslogtreecommitdiff
blob: ab590769ddc349c46020a50173584fe2f8905220 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/bin/bash
# (C) Eric Thibodeau 2006-2008 GPL v2
# Replacement initrc/linuxrc script hack to get diskless NFS nodes booted
# This script is largely inspired by prior work from 
# http://mozart.informatik.fh-kl.de/download/Software/GentooDiskless/
#

MODPROBE=/sbin/modprobe
IFCONFIG=/sbin/ifconfig
#MYHOST=$(/sbin/dhcpcd -H; /bin/hostname) # By default, we'll use the DHCP assigned hostname

NODE_NAME="node"

ahostname(){
	if [[ -z ${MYHOST} || ${MYHOST} == ${MYIP} ]]; then
		echo "DHCP didn't tell me my name. Generating my own hostname..."
		MYHOST="${NODE_NAME}${MYIP##*.}"
		echo "I proclaim that I am $MYHOST !!"
	else
		echo "DHCP told me my hostname is ${MYHOST}..."
	fi

	echo "$0: Setting Hostname to $MYHOST"
	echo "HOSTNAME=\"$MYHOST\"" > /etc/conf.d/hostname
	/bin/hostname "$MYHOST"
	
	echo "Setting domainname to DHCP's settings: $DOMAIN"
	/bin/domainname $DOMAIN
}


# Used to mount the RW part of the ROOT, it should be easy to add other
# FS than tmpfs here.
mount_rw_dev() {
	echo "$0: Mounting $RWDEV as Read Write device ..."
	if [ $RWDEV == "tmpfs" ]; then
		mount -n -t tmpfs -o defaults tmpfs_rw /mnt/rw_mounts/
	fi
}

mount_rw_dir() {
	while [ "$1" != "" ]; do
		echo "$0: Mounting $1 using $UNIONMOD ..."
		mkdir -p /mnt/rw_mounts/$1
		mount -i -n -t $UNIONMOD -o dirs=/mnt/rw_mounts/$1=rw:/$1=ro ${UNIONMOD}_$1 /$1
		shift
	done
}

# ahosts was added so that we could dynamically change the NFS server address
# using the rootserver= DHCP option as the NFS mount server. This is usefull
# when you want to split the load onto different NIC interfaces within a same
# logical network.
ahosts() {
	echo "Setting rootserver to $ROOTSERV in /etc/hosts file..."
	echo "$ROOTSERV rootserver" >> /etc/hosts
	echo "Setting up fstab"
	echo "$ROOTSERV:$ROOTPATH     /  nfs   ro,defaults,hard,intr,actimeo=120,timeo=14,tcp 0 1" > /etc/fstab
}

# get_param: parses parameters in PARSELINE which could be, for example, the kernel's command line
# (This implies PARSELINE=$(cat /proc/cmdline) 
# Example:
# 	ip=dhcp nfsroot=192.168.1.2:/tftproot/nfsroot/x86_64/,hard,intr init=/boot/stateless.sh softlevel=unionfs
# IN: 
#	$1: parameter we want (ie: nfsroot)
#	$2: which token # we want, ie: the IP address of nfsroot it token 1
get_param() {
    PARAM=$2
    for opt in $PARSELINE
    do
        case $opt in
            ${1}=*) set $(echo $opt | sed -e's/[=:,]/ /g' )
                    if [[ -z $PARAM ]]; then
                        shift
                        echo $*
                    else
                        shift $PARAM
						echo $1
                    fi
                    return 0
            ;;
        esac
    done
    echo "Parameter '$1' not found" >&2
    return 1
}

# Used to extract useful information for the rest of the configuration
# It's a horrible hack that parses dmesg but, unfortunately, /proc/net/pnp
# is insufficient even with /proc/cmdline
# Here is an example output of dmesg (partial)
#IP-Config: Complete:
#      device=eth0, addr=10.0.1.140, mask=255.255.255.0, gw=10.0.1.129,
#     host=thinkbig24, domain=cluster.local, nis-domain=(none),
#     bootserver=10.0.1.129, rootserver=10.0.1.129, rootpath=/tftproot/AthlonXP

import_dhcp_info() {
	PARSELINE=$(dmesg | grep -A3 'IP-Config: Complete:' | sed -e 's/[:,]/ /g' | tr -d '\n')
	MYIP=$(get_param addr 1)
	MYHOST=$(get_param host 1)
	DOMAIN=$(get_param domain 1)
	ROOTPATH=$(get_param rootpath 1)
	ROOTSERV=$(get_param rootserver 1)
}

# if mounting /proc becomes a problem we have to use the following:
# PARSELINE=$(dmesg | grep '^Kernel command line' | sed 's/^Kernel command line://g')
import_cmdline() {
	mount -n -t proc none /proc
	PARSELINE=$(cat /proc/cmdline)
	UNIONMOD=$(get_param unionmod 1)
	RWDEV=$(get_param rwdev 1)
}


import_dhcp_info
import_cmdline
[ ! -z $RWDEV ] && mount_rw_dev
if [ ! -z $UNIONMOD ]; then
	echo "Loading $UNIONMOD"
	# we should detect wether it's a mod or kernel builtin...
	$MODPROBE $UNIONMOD
	mount_rw_dir etc var tmp
fi
touch /etc || /bin/bash
ahostname
ahosts
exec /sbin/init