diff options
-rwxr-xr-x | initramfs-init.in | 166 |
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 |