diff --git a/initramfs-init.in b/initramfs-init.in index 3c05f81..0050787 100755 --- a/initramfs-init.in +++ b/initramfs-init.in @@ -52,6 +52,11 @@ find_ovl() { local ovl local lines + if [ -n "$APKOVL" ]; then + [ -f "$mnt/$APKOVL" ] && echo "$mnt/$APKOVL" + return + fi + # look for apkovl's on mounted media ovl=$( ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null ) || return 1 lines=$(echo "$ovl" | wc -l) @@ -191,7 +196,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 +245,81 @@ 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 +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" + case "$client_ip" in + off|none|'') return;; + dhcp) autoconf="dhcp";; + esac + + [ -n "$device" ] || device=$(ip_choose_if) + if [ -z "$device" ]; then + echo "ERROR: IP requested but no network device was found" + return 1 + fi + + if [ "$autoconf" = "dhcp" ]; then + if [ ! -e /usr/share/udhcpc/default.script ]; then + echo "ERROR: DHCP requested but not present in initrd" + return 1 + 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 +355,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 :) @@ -286,8 +370,9 @@ echo "Alpine Init $VERSION" # acpi_osi="!Windows 2006" eval set -- `cat /proc/cmdline` -myopts="alpine_dev autodetect autoraid chart cryptroot debug_init dma init_args - keep_apk_new modules ovl_dev pkgs quiet root_size root usbdelay" +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 ip alpine_repo apkovl" for opt; do case "$opt" in @@ -340,6 +425,8 @@ ALPINE_DEV_FS=${KOPT_alpine_dev##*:} if [ "$ALPINE_DEV_FS" = "$ALPINE_DEV" ]; then unset ALPINE_DEV_FS fi + +# /dev/blah:ext3 if [ -n "$KOPT_ovl_dev" ] ; then OVL_DEV=${KOPT_ovl_dev%%:*} OVL_DEV_FS=${KOPT_ovl_dev##*:} @@ -348,13 +435,44 @@ if [ -n "$KOPT_ovl_dev" ] ; then fi fi +# http://.../blah.apkovl.tar.gz +case "$KOPT_apkovl" in + http://*|https://|ftp://*) + OVL_DEV="$KOPT_apkovl";; + *:*:*) # apkovl=sda1:ext4:/subdir/host.apkovl.tar.gz + OVL_DEV="${KOPT_apkovl%%:*}" + OVL_DEV_FS="${KOPT_apkovl%:*}" + OVL_DEV_FS="${OVL_DEV_FS#*:}" + APKOVL="${KOPT_apkovl##*:}" + ;; + *:*) # apkovl=sda1:/subdir/host.apkovl.tar.gz + OVL_DEV=${KOPT_apkovl%%:*} + APKOVL=${KOPT_apkovl##*:} + ;; + *) # apkovl=subdir/host.apkovl.tar.gz + APKOVL="${KOPT_apkovl}" + ;; +esac + case "$ALPINE_DEV" in UUID=*|LABEL=*) ;; + nfs) + # nfs:IP:EXPORT + ALPINE_DEV_FS="$ALPINE_DEV" + ALPINE_DEV="${KOPT_alpine_dev:4}" + ;; *) ALPINE_DEV=/dev/$ALPINE_DEV ;; 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" ] && [ "$ALPINE_DEV_FS" = nfs ] && ALPINE_MNT=/media/alpine [ -z "$ALPINE_MNT" ] && ALPINE_MNT=/media/${ALPINE_DEV##*/} # hide kernel messages @@ -428,6 +546,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 @@ -444,6 +565,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 @@ -462,19 +584,27 @@ 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) -else - find_ovl_dev -fi +case "$OVL_DEV" in + '') + find_ovl_dev + ;; + http://*|https://*|ftp://*) + ovl=/tmp/boot.apkovl.tar.gz + wget -O "$ovl" "$OVL_DEV" || ovl= + ;; + *) + 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) + ;; +esac + if ! [ -f "$ovl" ]; then ovl=$(find_ovl $ALPINE_MNT) fi @@ -508,7 +638,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 @@ -524,6 +655,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 @@ -569,7 +702,14 @@ 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 + apkflags="$apkflags --update-cache" +fi + if [ -n "$KOPT_quiet" ]; then apkflags="$apkflags --quiet" fi @@ -580,7 +720,7 @@ if [ "$KOPT_keep_apk_new" != yes ]; then fi if [ -n "$ovlfiles" ]; then - apk add --root $sysroot $repo_opt $apkflags $pkgs <$ovlfiles>/dev/null + apk add --root $sysroot $repo_opt $apkflags $pkgs <$ovlfiles>/dev/null else apk add --root $sysroot $repo_opt $apkflags $pkgs >/dev/null fi @@ -613,11 +753,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