diff --git a/TODO b/TODO index 5603834..63a8346 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,17 @@ YES: - * Downloading rootfs over http * Specifying rootfs location filesystem type - * Other compression algorithms * Start different init than /sbin/init * Configuration examples, HOWTOs - * Rootfs "overlays"/"parts" + * DNS configuration. MAYBE: + * Change the rootfs_part= argument handling, so that it would accept arbitrary + ammount of transformations; will lead to awesome stuff like transforming + next parts using scripts downloaded in previous parts. * Compression algorithm autodetection based on filename OR bsdtar automagic * Fancier OK/FAIL - at the end of the line, or somewhere +DONE: + * Downloading rootfs over http + * Other compression algorithms + * Rootfs "overlays"/"parts" diff --git a/initramfs/init b/initramfs/init index 67cddc1..57ca7a2 100755 --- a/initramfs/init +++ b/initramfs/init @@ -1,9 +1,15 @@ #!/busybox sh -NORMAL="\\033[0m" -FAIL="\\033[1;31m" -OK="\\033[1;32m" -INFO="\\033[1;34m" +NORMAL="\\033[0m" # white on black, or whatever your terminal is +FAIL="\\033[1;31m" # red foreground +OK="\\033[1;32m" # green foreground +INFO="\\033[1;34m" # blue foreground + +alias tar='/busybox tar -C /roottmpfs -xpf -' +alias bzcat='/busybox bzcat' +alias xzcat='/busybox xzcat' +alias mount='/busybox mount' +alias umount='/busybox umount' die() { echo "" @@ -46,29 +52,6 @@ info "mounting proc" /busybox mount -n -t proc proc ./proc isok $? -# rootfs_location_uuid=f822d881-d88a-4200-a9cf-6986c5a3e69a -info "looking for device with rootfs" -for var in $(cat /proc/cmdline); do - if [[ ${var/=*} = rootfs_location_uuid ]]; then - uuid="${var/*=}" - fi -done -device=$(findfs UUID=${uuid}) -isok $? - -# rootfs_filename=rootfs.tar.xz -info "getting rootfs filename" -for var in $(cat /proc/cmdline); do - if [[ ${var/=*} = rootfs_filename ]]; then - filename="${var/*=}" - fi -done -if [[ -z ${filename} ]]; then - info "going with default: rootfs.tar.xz" - filename="rootfs.tar.xz" -fi -isok 0 - info "getting root tmpfs size" for var in $(cat /proc/cmdline); do if [[ ${var/=*} = rootfs_size ]]; then @@ -81,25 +64,86 @@ if [[ -z ${size} ]]; then fi isok 0 -info "trying to mount ${device}" -/busybox mount -n -o ro ${device} /mnt -isok $? - info "trying to mount root tmpfs" /busybox mount -n -o size=${size} -t tmpfs roottmpfs /roottmpfs isok $? -info "checking if ${filename} exists" -[[ -e /mnt/${filename} ]] -isok $? +info "checking if the user wants to use a different init" +for var in $(cat /proc/cmdline); do + if [[ ${var/=*} = init ]]; then + init="${var/*=}" + info "user wants ${init}" + fi +done +if [[ -z "${init}" ]]; then + info "no; default: /sbin/init" + init="/sbin/init" + isok $? +fi -info "unpacking; will take some time" +info "checking for network configuration on kernel commandline" echo "" -/pv /mnt/${filename} | /busybox tar -C /roottmpfs -xJf - +for var in $(cat /proc/cmdline); do + if [[ ${var/=*} = ipcmd ]]; then + # Split the "value" part of this parameter into parts, with "," as + # separators and then use them for constructing iproute2 commandline. + # Don't do any input validation; escape to the shell if things break. + # Do it in a subshell to prevent IFS change leak. + ( + IFS="," + set -- ${var/*=} + info "ip ${@}" + /busybox ip ${@} + isok $? + ) + fi +done -info "unmounting rootfs package location" -/busybox umount -n /mnt -isok $? +# syntax examples: +# rootfs_part=uuid|f822d881-d88a-4200-a9cf-6986c5a3e69a/some_directory/file|xzcat|tar +# -> findfs -> mount -> xzcat | tar +# rootfs_part=url|http://10.3.13.37/url.tar.bz2|bzcat|tar +# -> wget -O - | bzcat | tar +# You might find bugs & dragons here; patches accepted. +info "looking for root filesystem tarballs" +echo "" +for var in $(cat /proc/cmdline); do + if [[ "${var/=*}" = rootfs_part ]]; then + part="${var/*=}" + info "found ${part}" + # uuid or url + url_type="${part/|*}" + # url + transformations + url="${part#${url_type}|}" + # transformations + transformations="${url#*|}" + # url + url="${url/|*}" + ( + if [[ ${url_type} = "uuid" ]]; then + uuid="$(echo ${url} | /busybox cut -d / -f 1)" + filepath="${url#*/}" + + info "mounting $(findfs UUID="${uuid}") on /mnt" + mount -n -o ro "$(findfs UUID="${uuid}")" /mnt + isok $? + + info "unpacking /mnt/${filepath}" + echo "" + /pv "/mnt/${filepath}" | eval ${transformations} + isok $? + + info "unmounting" + umount -n /mnt + isok $? + else + info "wgetting ${url} and transforming it on the fly" + /busybox wget -O - "${url}" | eval ${transformations} + isok $? + fi + ) + fi +done info "unmounting /dev" /busybox umount -n /dev @@ -109,6 +153,10 @@ info "unmounting /proc" /busybox umount -n /proc isok $? +info "checking if /roottmpfs/${init} exists" +[[ -e /roottmpfs/${init} ]] +isok $? + info "trying to switch root" exec /busybox switch_root /roottmpfs /sbin/init