summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xinitramfs-init.in166
1 files changed, 148 insertions, 18 deletions
diff --git a/initramfs-init.in b/initramfs-init.in
index 9bce5f8..f06bc21 100755
--- a/initramfs-init.in
+++ b/initramfs-init.in
@@ -191,7 +191,7 @@ setup_inittab_console(){
esac
shift
- # skip "current console" from beign added to inittab
+ # skip "current console" from being added to inittab
[ "$tty" = "tty0" ] && continue
# do nothing if inittab already have the tty set up
@@ -240,6 +240,79 @@ start_lvm() {
lvm vgchange --ignorelockingfailure -a y >/dev/null 2>&1
}
+# determine the default interface to use if ip=dhcp is set
+# uses the first "eth" interface.
+ip_choose_if() {
+ for x in /sys/class/net/eth*; do
+ [ -e "$x" ] && echo ${x##*/} && return
+ done
+}
+
+# ip_set <device> <ip> <netmask> <gateway-ip>
+ip_set() {
+ ifconfig "$1" "$2" netmask "$3" || return $?
+ if [ -n "$4" ]; then
+ ip route add 0.0.0.0/0 via "$4" dev "$1" || return $?
+ fi
+}
+
+# if "ip=dhcp" is specified on the command line, we obtain an IP address
+# using udhcpc. we do this now and not by enabling kernel-mode DHCP because
+# kernel-model DHCP appears to require that network drivers be built into
+# the kernel rather than as modules. At this point all applicable modules
+# in the initrd should have been loaded.
+#
+# You need af_packet.ko available as well modules for your Ethernet card.
+#
+# Valid syntaxes:
+# ip=client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf
+# ip=dhcp
+# "server-ip" and "hostname" are not supported here.
+#
+configure_ip() {
+ [ -n "$KOPT_ip" ] || return
+ OIFS=$IFS
+ IFS=':'
+ eval set -- $KOPT_ip
+ IFS=$OIFS
+
+ local client_ip="$1"
+ local gw_ip="$3"
+ local netmask="$4"
+ local device="$6"
+ local autoconf="$7"
+ [ "$client_ip" == "off" -o "$client_ip" == "none" ] && return
+ if [ "$client_ip" == "dhcp" ]; then
+ autoconf="dhcp"
+ client_ip=
+ fi
+
+ [ -n "$device" ] || device=$(ip_choose_if)
+ [ -n "$device" ] || return
+
+ if [ "$autoconf" == "dhcp" ]; then
+ if [ ! -e /usr/share/udhcpc/default.script ]; then
+ echo "ERROR: DHCP requested but not present in initrd"
+ return
+ fi
+ # automatic configuration
+ ebegin "Obtaining IP via DHCP ($device)..."
+ ifconfig $device 0.0.0.0
+ udhcpc -i $device -f -q
+ eend $?
+ else
+ # manual configuration
+ [ -n "$client_ip" -a -n "$netmask" ] || return
+ ebegin "Setting IP ($device)..."
+ ip_set "$device" "$client_ip" "$netmask" "$gw_ip"
+ eend $?
+ fi
+ MAC_ADDRESS=$(cat /sys/class/net/$device/address)
+ MACHINE_UUID=$(cat /sys/class/dmi/id/product_uuid)
+ OVL_DEV="${OVL_DEV/{MAC\}/$MAC_ADDRESS}"
+ OVL_DEV="${OVL_DEV/{UUID\}/$MACHINE_UUID}"
+}
+
# resolve an uuid or symlink to the real device
resolve_dev() {
case "$1" in
@@ -275,8 +348,12 @@ find_fs_type() {
# find the dirs under ALPINE_MNT that are boot repositories
find_boot_repositories() {
- find $ALPINE_MNT -name .boot_repository -type f -maxdepth 3 \
- | sed 's:/.boot_repository$::'
+ if [ -n "$ALPINE_REPO" ]; then
+ echo "$ALPINE_REPO"
+ else
+ find $ALPINE_MNT -name .boot_repository -type f -maxdepth 3 \
+ | sed 's:/.boot_repository$::'
+ fi
}
# gotta start from somewhere :)
@@ -288,7 +365,7 @@ eval set -- `cat /proc/cmdline`
myopts="alpine_dev autodetect autoraid chart cryptroot cryptdm debug_init
dma init_args keep_apk_new modules ovl_dev pkgs quiet root_size root
- usbdelay"
+ usbdelay ip alpine_repo"
for opt; do
case "$opt" in
@@ -341,21 +418,47 @@ ALPINE_DEV_FS=${KOPT_alpine_dev##*:}
if [ "$ALPINE_DEV_FS" = "$ALPINE_DEV" ]; then
unset ALPINE_DEV_FS
fi
+
+# /dev/blah:ext3
+# http://.../blah.apkovl.tar.gz
if [ -n "$KOPT_ovl_dev" ] ; then
OVL_DEV=${KOPT_ovl_dev%%:*}
OVL_DEV_FS=${KOPT_ovl_dev##*:}
if [ "$OVL_DEV_FS" = "$OVL_DEV" ]; then
unset OVL_DEV_FS
fi
+
fi
case "$ALPINE_DEV" in
UUID=*|LABEL=*) ;;
+ nfs)
+ # nfs:IP:EXPORT
+ ALPINE_DEV_FS="$ALPINE_DEV"
+ ALPINE_DEV="${KOPT_alpine_dev:4}"
+ ALPINE_DEV_IS_NETWORK=y
+ ;;
*) ALPINE_DEV=/dev/$ALPINE_DEV ;;
esac
+case "$OVL_DEV" in
+ http|https)
+ OVL_DEV_FS="$OVL_DEV"
+ OVL_DEV="$KOPT_ovl_dev"
+ OVL_DEV_IS_NETWORK=y
+ ;;
+ *) ;;
+esac
+
+# The following values are supported:
+# alpine_repo=auto -- default, search for .boot_repository
+# alpine_repo=http://... -- network repository
+ALPINE_REPO=${KOPT_alpine_repo}
+[ "$ALPINE_REPO" == "auto" ] && ALPINE_REPO=
+
# look for standard mountpoint locations
ALPINE_MNT=$(find_mnt $ALPINE_DEV /etc/fstab)
+[ -z "$ALPINE_MNT" -a -n "$ALPINE_DEV_IS_NETWORK" ] && ALPINE_MNT=/media/alpine_dev
[ -z "$ALPINE_MNT" ] && ALPINE_MNT=/media/${ALPINE_DEV##*/}
# hide kernel messages
@@ -429,6 +532,9 @@ if [ -z "${ALPINE_DEV##*usb*}" ]; then
wait_usb
fi
+# IP. This shouldn't be needed if root= is set.
+configure_ip
+
# incase we have alpine_dev on raid device...
start_raid
start_cryptsetup
@@ -445,6 +551,7 @@ fi
if [ -n "$ALPINE_DEV_FS" ]; then
mount_opts="-t $ALPINE_DEV_FS"
+ [ "$ALPINE_DEV_FS" == "nfs" ] && mount_opts="$mount_opts -o nolock"
fi
retry_mount -o ro $mount_opts $ALPINE_DEV $ALPINE_MNT >/dev/null 2>&1
@@ -463,18 +570,26 @@ if [ -n "$KOPT_root_size" ]; then
fi
mount -t tmpfs $root_opts tmpfs $sysroot
-if [ -n "$OVL_DEV" ]; then
- mkdir -p /media/$OVL_DEV
- unset mount_opts
- if [ -n "$OVL_DEV_FS" ]; then
- mount_opts="-t $OVL_DEV_FS"
- fi
-
- retry_mount -o ro $mount_opts /dev/$OVL_DEV /media/$OVL_DEV \
- >/dev/null 2>&1
- ovl=$(find_ovl /media/$OVL_DEV)
+OVL_MNT=/media/$OVL_DEV
+[ -n "$OVL_DEV_IS_NETWORK" ] && OVL_MNT=/media/ovl_dev
+
+if [ -n "$OVL_DEV_IS_NETWORK" ]; then
+ ovl=/tmp/boot.apkovl.tar.gz
+ wget -O "$ovl" "$OVL_DEV"
else
- find_ovl_dev
+ if [ -n "$OVL_DEV" ]; then
+ mkdir -p /media/$OVL_DEV
+ unset mount_opts
+ if [ -n "$OVL_DEV_FS" ]; then
+ mount_opts="-t $OVL_DEV_FS"
+ fi
+
+ retry_mount -o ro $mount_opts /dev/$OVL_DEV /media/$OVL_DEV \
+ >/dev/null 2>&1
+ ovl=$(find_ovl /media/$OVL_DEV)
+ else
+ find_ovl_dev
+ fi
fi
if ! [ -f "$ovl" ]; then
ovl=$(find_ovl $ALPINE_MNT)
@@ -509,7 +624,8 @@ if [ -f "$ovl" ]; then
-e 's|:/etc/init.d/rcK|:/sbin/rc shutdown|' \
"$sysroot"/etc/inittab
fi
-else
+fi
+if [ -f "$sysroot/etc/.default_boot_services" -o ! -f "$ovl" ]; then
# add some boot services by default
rc_add devfs sysinit
rc_add dmesg sysinit
@@ -525,6 +641,8 @@ else
rc_add mount-ro shutdown
rc_add killprocs shutdown
rc_add savecache shutdown
+
+ rm -f "$sysroot/etc/.default_boot_services"
fi
if [ -f $sysroot/etc/fstab ]; then
@@ -570,7 +688,16 @@ ebegin "Installing packages to root filesystem"
if [ "$KOPT_chart" = yes ]; then
pkgs="$pkgs acct"
fi
-apkflags="--initdb --progress --force --no-network"
+
+apkflags="--initdb --progress --force"
+if [ -z "$ALPINE_REPO" ]; then
+ apkflags="$apkflags --no-network"
+else
+ # HTTP: convince apk to behave
+ apk add --root $sysroot $repo_opt $apkflags
+ apk update --root $sysroot $repo_opt
+fi
+
if [ -n "$KOPT_quiet" ]; then
apkflags="$apkflags --quiet"
fi
@@ -614,11 +741,14 @@ fi
setup_inittab_console $CONSOLE
# copy alpine release info
-if ! [ -f "$sysroot"/etc/alpine-release ]; then
+if ! [ -f "$sysroot"/etc/alpine-release ] && [ -f $ALPINE_MNT/.alpine-release ]; then
cp $ALPINE_MNT/.alpine-release $sysroot/
ln -sf /.alpine-release $sysroot/etc/alpine-release
fi
+! [ -f "$sysroot"/etc/resolv.conf ] && [ -f /etc/resolv.conf ] && \
+ cp /etc/resolv.conf "$sysroot"/etc
+
# setup bootchart for switch_root
chart_init=""
if [ "$KOPT_chart" = yes ]; then