diff --git a/package/teha/rescue-stage1-init/init.c b/package/teha/rescue-stage1-init/init.c new file mode 100644 index 000000000..a3abec972 --- /dev/null +++ b/package/teha/rescue-stage1-init/init.c @@ -0,0 +1,365 @@ +/* + * --- ROCK-COPYRIGHT-NOTE-BEGIN --- + * + * This copyright note is auto-generated by ./scripts/Create-CopyPatch. + * Please add additional copyright information _after_ the line containing + * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by + * the ./scripts/Create-CopyPatch script. Do not edit this copyright text! + * + * ROCK Linux: init.c + * ROCK Linux is Copyright (C) 1998 - 2003 Clifford Wolf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. A copy of the GNU General Public + * License can be found at Documentation/COPYING. + * + * Many people helped and are helping developing ROCK Linux. Please + * have a look at http://www.rocklinux.org/ and the Documentation/TEAM + * file for details. + * + * --- ROCK-COPYRIGHT-NOTE-END --- + * + * This is stage1 init for ROCK Linux advanced rescue system (C) 2004 Tobias Hintze + * + * Plan: + * - mount boot filesystem + * - mount tmpfs as new root filesystem + * - extract system.tar.bz2 and overlay.tar.bz2 from boot filesystem into new root filesystem + * - move /dev under new root + * - do pivot_root into tmpfs + * - exec /sbin/init in new root + * + * This init accepts the following (kernel append) parameters: + * *_PARAM macros hold parameter names only! + * + * SYSTEM_FAILURE_PARAM - action to be taken if extracting system fails + * (panic|reboot|shell) + * + * OVERLAY_FAILURE_PARAM - action to be taken if extracting overlay fails + * (panic|reboot|shell|ignore) + * + * SYSTEM_LOCATION_PARAM - name and path of system.tar.bz2 + * NB: boot filesystem mounted as /mnt_boot + * + * OVERLAY_LOCATION_PARAM - name and path of overlay.tar.bz2 + * NB: boot filesystem mounted as /mnt_boot + * + * BOOT_DEVICE_PARAM - device that holds boot filesystem + * + * STAGE2_INIT_PARAM - executable to be run in stage2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int verbose = 0; + +#define VERBOSE_PARAM "verbose" +#define SYSTEM_FAILURE_PARAM "system_failure" +#define OVERLAY_FAILURE_PARAM "overlay_failure" +#define SYSTEM_LOCATION_PARAM "system" +#define OVERLAY_LOCATION_PARAM "overlay" +#define STAGE2_INIT_PARAM "stage2init" +#define BOOT_DEVICE_PARAM "boot" + +#ifndef DEFAULT_BOOT_DEVICE +#define DEFAULT_BOOT_DEVICE "/dev/discs/disc0/part1" +#endif + +#ifndef DEFAULT_STAGE2_INIT +#define DEFAULT_STAGE2_INIT "/sbin/init" +#endif + +#ifndef DEFAULT_BOOT_FST +#define DEFAULT_BOOT_FST "ext2" +#endif + +#ifndef DEFAULT_SYSTEM_LOCATION +#define DEFAULT_SYSTEM_LOCATION "/mnt_boot/rescue/system.tar.bz2" +#endif + +#ifndef DEFAULT_OVERLAY_LOCATION +#define DEFAULT_OVERLAY_LOCATION "/mnt_boot/rescue/overlay.tar.bz2" +#endif + +#ifndef DEFAULT_ACTION_ON_SYSTEM_FAILURE +#define DEFAULT_ACTION_ON_SYSTEM_FAILURE "shell" +#endif + +#ifndef DEFAULT_ACTION_ON_OVERLAY_FAILURE +#define DEFAULT_ACTION_ON_OVERLAY_FAILURE "ignore" +#endif + +#define PANIC 1 +#define REBOOT 2 +#define SHELL 3 +#define IGNORE 4 + +#ifndef MS_MOVE +# define MS_MOVE 8192 +#endif + +/* 64 MB should be enough for the tmpfs */ +#define TMPFS_OPTIONS "size=67108864" + +extern char **environ; + +static int system_failure; +static int overlay_failure; + +int pivot_root(const char *new_root, const char *put_old); + +int untarbz2(const char *arch, const char *trg_dir) { + int status; + + if (!fork()) { +#ifdef VEROSE + printf("Extracting %s ...", arch); fflush(stdout); +#endif + execlp("tar", "tar", "--use-compress-program=bzip2", "-C", trg_dir, "-xf", arch, NULL); + perror("tar"); + _exit(1); + } + wait(&status); + +#ifdef VEROSE + printf(" finished (%i).\n\n", status); +#endif + return WEXITSTATUS(status); +} + +void die() { + printf("Aieee. I lost all hope. Take that shell!\n\n"); + execl("/bin/kiss", "kiss", 0); + perror("kiss"); + _exit(1); +} + +void shell() { + printf("Quit the shell to continue in stage 1 loader!\n"); + if (!fork()) { + execl("/bin/kiss", "kiss", 0); + perror("kiss"); + _exit(1); + } + wait(0); +} + +void do_reboot() { + reboot(LINUX_REBOOT_CMD_RESTART); +} + +void raise_panic() { + if (verbose) { + printf("Terminating process to trigger kernel panic...\n\n"); + } + _exit(0); +} + + +int main(int argc, char **argv) { + int i, err; + char *syst = DEFAULT_SYSTEM_LOCATION; + char *overlay = DEFAULT_OVERLAY_LOCATION; + char *bootdev = DEFAULT_BOOT_DEVICE; + char *bootfst = DEFAULT_BOOT_FST; + char *stage2init = DEFAULT_STAGE2_INIT; + + /* pre read environment; determine verbosity */ + for (i=0; ; i++) { + if (!environ[i]) break; + if (!i) continue; + if (!strcmp(VERBOSE_PARAM, environ[i])) verbose = 1; + if (!strcmp(VERBOSE_PARAM "=1", environ[i])) verbose = 1; + if (!strcmp(VERBOSE_PARAM "=yes", environ[i])) verbose = 1; + if (!strcmp(VERBOSE_PARAM "=on", environ[i])) verbose = 1; + } + + if (verbose) { + printf("\n" + "=========================================\n" + "=== ROCK Linux rescue boot system ===\n" + "=== rescue-stage1-init ===\n" + "=========================================\n" + "(verbose operation)" + "\n\n"); + } + + /* evaluate compile-time defaults */ + if (!strcmp(DEFAULT_ACTION_ON_SYSTEM_FAILURE, "reboot")) system_failure = REBOOT; + if (!strcmp(DEFAULT_ACTION_ON_SYSTEM_FAILURE, "panic")) system_failure = PANIC; + if (!strcmp(DEFAULT_ACTION_ON_SYSTEM_FAILURE, "shell")) system_failure = SHELL; + + if (!strcmp(DEFAULT_ACTION_ON_OVERLAY_FAILURE, "panic")) overlay_failure = PANIC; + if (!strcmp(DEFAULT_ACTION_ON_OVERLAY_FAILURE, "reboot")) overlay_failure = REBOOT; + if (!strcmp(DEFAULT_ACTION_ON_OVERLAY_FAILURE, "shell")) overlay_failure = SHELL; + if (!strcmp(DEFAULT_ACTION_ON_OVERLAY_FAILURE, "ignore")) overlay_failure = IGNORE; + + + for (i=0; ; i++) { + if (!environ[i]) break; + if (verbose) { + printf("environ[%i]: %s\n", i, environ[i]); + } + if (!i) continue; + /* read failure behaviour from parameter */ + if (!strcmp(SYSTEM_FAILURE_PARAM "=reboot", environ[i])) system_failure = REBOOT; + if (!strcmp(SYSTEM_FAILURE_PARAM "=panic", environ[i])) system_failure = PANIC; + if (!strcmp(SYSTEM_FAILURE_PARAM "=shell", environ[i])) system_failure = SHELL; + if (!strcmp(OVERLAY_FAILURE_PARAM "=reboot", environ[i])) overlay_failure = REBOOT; + if (!strcmp(OVERLAY_FAILURE_PARAM "=panic", environ[i])) overlay_failure = PANIC; + if (!strcmp(OVERLAY_FAILURE_PARAM "=shell", environ[i])) overlay_failure = SHELL; + if (!strcmp(OVERLAY_FAILURE_PARAM "=ignore", environ[i])) overlay_failure = IGNORE; + + /* path to system.tar.bz2 as parameter? */ + if (!strncmp(SYSTEM_LOCATION_PARAM "=", environ[i], strlen(SYSTEM_LOCATION_PARAM "="))) { + syst = environ[i] + strlen(SYSTEM_LOCATION_PARAM "="); + } + + /* path to overlay.tar.bz2 as parameter? */ + if (!strncmp(OVERLAY_LOCATION_PARAM "=", environ[i], strlen(OVERLAY_LOCATION_PARAM "="))) { + overlay = environ[i] + strlen(OVERLAY_LOCATION_PARAM "="); + } + + /* stage2 init as parameter? */ + if (!strncmp(STAGE2_INIT_PARAM "=", environ[i], strlen(STAGE2_INIT_PARAM "="))) { + stage2init = environ[i] + strlen(STAGE2_INIT_PARAM "="); + } + + /* boot device */ + if (!strncmp(BOOT_DEVICE_PARAM "=", environ[i], strlen(BOOT_DEVICE_PARAM "="))) { + char *p; + bootdev = environ[i] + strlen(BOOT_DEVICE_PARAM "="); + /* check for specified boot-fstype */ + if (p = strchr((const char*)bootdev, (int)':')) { + bootfst = bootdev; + bootdev = p+1; + *p = 0; + } + } + } + + if (mount("none", "/dev", "devfs", 0, NULL)) { + if (errno != EBUSY) { /* might be mounted automatically at boot */ + perror("Can't mount /dev"); + die(); + } + } + + if (mount(bootdev, "/mnt_boot", bootfst, MS_RDONLY, 0)) { + perror("Can't mount boot device. I need it at /mnt_boot - good luck."); + printf("I tried: mount(%s, /mnt_boot, %s, MS_RDONLY, 0)\n", + bootdev, bootfst); + shell(); + } + if (mount("none", "/mnt_root", "tmpfs", 0, TMPFS_OPTIONS)) { + perror("Can't mount root-tmpfs. I need it at /mnt_root - good luck."); + shell(); + } + + err = 0; + if (!access(syst, R_OK)) { + if (verbose) { + printf("Found %s. Using as system.\n", syst); + } + if (untarbz2((const char*)syst, "/mnt_root")) { + printf("Failed to extract rescue system. "); + err = 1; + } + } else { + printf("System %s not found! ", syst); + err = 1; + } + if (err) { + switch (system_failure) { + case SHELL: + printf("Spawning shell.\n", syst); + shell(); + break; + case REBOOT: + printf("Going to reboot.\n", syst); + do_reboot(); + break; + case PANIC: + printf("Going to panic kernel.\n", syst); + raise_panic(); + break; + } + } + + err = 0; + if (!access(overlay, R_OK)) { + if (verbose) { + printf("Found %s. Using as overlay.\n", overlay); + } + if (untarbz2((const char*)overlay, "/mnt_root")) { + printf("Failed to extract system overlay. "); + err = 1; + } + } else { + printf("Overlay %s not found! ", overlay); + err = 1; + } + if (err) { + switch (overlay_failure) { + case SHELL: + printf("Spawning shell.\n", syst); + shell(); + break; + case REBOOT: + printf("Going to reboot.\n", syst); + do_reboot(); + break; + case PANIC: + printf("Going to panic kernel.\n", syst); + raise_panic(); + break; + case IGNORE: + if (verbose) { + printf("Ignoring.\n", overlay); + } + break; + } + } + + if (mkdir("/mnt_root/old_root", 700)) { + perror("Can't mkdir mount point for old root."); + die(); + } + if (pivot_root("/mnt_root", "/mnt_root/old_root")) { + perror("Can't pivot_root()"); + die(); + } + + chdir("/"); + if (mount("/old_root/dev", "/dev", NULL, MS_MOVE, NULL)) + perror("Can't remount /old_root/dev as /dev"); + + /* if (mount("/old_root/proc", "/proc", NULL, MS_MOVE, NULL)) + perror("Can't remount /old_root/proc as /proc"); */ + + execl(stage2init, stage2init, 0); + printf("\n\nAieeee. Failed to execute stage2 init (%s).\n\n", stage2init); + sleep(1); + execl("/bin/sh", "/bin/sh", 0); + printf("\n\nAieeee. Failed to execute stage2 shell (fallback).\n\n"); + sleep(10); + + return 0; +} diff --git a/package/teha/rescue-stage1-init/rescue-stage1-init.conf b/package/teha/rescue-stage1-init/rescue-stage1-init.conf new file mode 100644 index 000000000..9e6e7d071 --- /dev/null +++ b/package/teha/rescue-stage1-init/rescue-stage1-init.conf @@ -0,0 +1,12 @@ +main_rs1i() { + cd $root/ + echo "Building linuxrc ..." + $CC -Wall $confdir/init.c \ + -DDEFAULT_ACTION_ON_SYSTEM_FAILURE="\"${ROCKCFG_RESCUE_ACTION_SYSTEM_FAILURE}\""\ \ + -DDEFAULT_ACTION_ON_OVERLAY_FAILURE="\"${ROCKCFG_RESCUE_ACTION_OVERLAY_FAILURE}\""\ \ + -o $root/sbin/init +} + +mainfunction="main_rs1i" +srctar="" +autoextract=0 diff --git a/package/teha/rescue-stage1-init/rescue-stage1-init.desc b/package/teha/rescue-stage1-init/rescue-stage1-init.desc new file mode 100644 index 000000000..1443fbda0 --- /dev/null +++ b/package/teha/rescue-stage1-init/rescue-stage1-init.desc @@ -0,0 +1,43 @@ + +[COPY] --- ROCK-COPYRIGHT-NOTE-BEGIN --- +[COPY] +[COPY] This copyright note is auto-generated by ./scripts/Create-CopyPatch. +[COPY] Please add additional copyright information _after_ the line containing +[COPY] the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by +[COPY] the ./scripts/Create-CopyPatch script. Do not edit this copyright text! +[COPY] +[COPY] ROCK Linux: rock-src/package/teha/rescue-stage1-init2/rescue-stage1-init2.desc +[COPY] ROCK Linux is Copyright (C) 1998 - 2004 Clifford Wolf +[COPY] +[COPY] This program is free software; you can redistribute it and/or modify +[COPY] it under the terms of the GNU General Public License as published by +[COPY] the Free Software Foundation; either version 2 of the License, or +[COPY] (at your option) any later version. A copy of the GNU General Public +[COPY] License can be found at Documentation/COPYING. +[COPY] +[COPY] Many people helped and are helping developing ROCK Linux. Please +[COPY] have a look at http://www.rocklinux.org/ and the Documentation/TEAM +[COPY] file for details. +[COPY] +[COPY] --- ROCK-COPYRIGHT-NOTE-END --- + +[I] init for stage1 of rescue target + +[T] this init does the following: +[T] - mount boot a filesystem +[T] - mount tmpfs as root filesystem +[T] - extract system.tar.bz2 and overlay.tar.bz2 +[T] from boot filesystem into root filesystem +[T] - do pivot_root into tmpfs +[T] - exec /sbin/init in new root + +[A] Tobias Hintze +[M] Tobias Hintze + +[C] base/system + +[L] GPL +[S] Stable +[V] 0000 +[P] O ---3-----9 800.000 + diff --git a/target/rescue/build.sh b/target/rescue/build.sh new file mode 100644 index 000000000..74119c5c4 --- /dev/null +++ b/target/rescue/build.sh @@ -0,0 +1,48 @@ + +if [[ $rockver = 2.0* ]] ; then + disksdir="$build_dir/rescue" + pkgsdir="$build_dir/pkgs" + rootdir="$build_dir/root" +else + disksdir="$build_rock/rescue" + pkgsdir="$build_rock/pkgs" + rootdir="$build_rock/.." +fi + +if [ "$ROCK_DEBUG_RESCUE_NOSTAGE2" != 1 -a \ + "$ROCK_DEBUG_RESCUE_NOSTAGE1" != 1 ] +then + pkgloop + rm -rf $disksdir; mkdir -p $disksdir; chmod 700 $disksdir +fi + +# Re-evaluate CC and other variables (as we have built the cross cc now) +. scripts/parse-config + +if [ "$ROCK_DEBUG_RESCUE_NOSTAGE2" != 1 ] +then + . $base/target/$target/build_stage2.sh +fi + +if [ "$ROCK_DEBUG_RESCUE_NOSTAGE1" != 1 ] +then + . $base/target/$target/build_stage1.sh +fi + +if [ -f $base/target/$target/$arch/build.sh ]; then + . $base/target/$target/$arch/build.sh +fi + + +echo_header "Creating ISO filesystem description." +cd $disksdir; rm -rf isofs; mkdir -p isofs + +echo_status "Creating rescue/isofs directory.." +ln system.tar.bz2 isofs/ +ln *.img isofs/ 2>/dev/null || true # might not exist on some architectures + +echo_status "Creating isofs.txt file .." +echo "DISK1 build/${ROCKCFG_ID}/rescue/isofs/ ` + `${ROCKCFG_SHORTID}/" > ../isofs_generic.txt +cat ../isofs_*.txt > ../isofs.txt + diff --git a/target/rescue/build_stage1.sh b/target/rescue/build_stage1.sh new file mode 100644 index 000000000..d0d06227a --- /dev/null +++ b/target/rescue/build_stage1.sh @@ -0,0 +1,72 @@ + +echo_header "Creating initrd data:" +rm -rf $disksdir/initrd +mkdir -p $disksdir/initrd/{dev,proc,tmp,lib,bin,mnt_boot,mnt_root} +cd $disksdir/initrd +ln -s bin sbin +ln -s . usr + +echo_status "Copying linuxrc binary." +cp -v $rootdir/sbin/init sbin/ + +echo_status "Copy libc stuff." +cp -a $rootdir/lib/ld-*.so \ + $rootdir/lib/ld-linux* \ + $rootdir/lib/libc-* \ + $rootdir/lib/libc.* \ + $rootdir/lib/libc.* \ + $rootdir/lib/libresolv* \ + lib/ + +if [[ $rockver != 2.0* ]] ; then + echo_status "Copy some additional libs for tar." + cp -a $rootdir/lib/lib{pthread,rt}{.,-}* \ + lib/ +fi + +echo_status "Copy various helper applications." +cp $rootdir/bin/{tar,gzip,bzip2} bin/ +cp $rootdir/sbin/{insmod,ip} bin/ +cp $rootdir/usr/bin/wget bin/ + +# +if [ "$ROCKCFG_RESCUE_INITRD_USEKISS" = 1 ]; then + echo_status "Adding kiss shell for expert use of the initrd image." + cp $rootdir/bin/kiss bin/ +fi +cd .. + +echo_header "Creating initrd filesystem image: " + +ramdisk_size=8192 +[ $arch = x86 ] && ramdisk_size=4096 + +echo_status "Creating temporary files." +tmpdir=initrd_$$.dir +mkdir -p $disksdir/$tmpdir +cd $disksdir + +dd if=/dev/zero of=initrd.img bs=1024 count=$ramdisk_size &> /dev/null +tmpdev="" +for x in /dev/loop/* ; do + if /sbin/losetup $x initrd.img 2> /dev/null ; then + tmpdev=$x ; break + fi +done +if [ -z "$tmpdev" ] ; then + echo_error "No free loopback device found!" + rm -f $tmpfile ; rmdir $tmpdir; exit 1 +fi +echo_status "Using loopback device $tmpdev." + +echo_status "Writing initrd image file." +/sbin/mke2fs -m 0 -N 180 -q $tmpdev &> /dev/null +mount -t ext2 $tmpdev $tmpdir +rmdir $tmpdir/lost+found/ +cp -a initrd/* $tmpdir +umount $tmpdir + +echo_status "Removing temporary files." +/sbin/losetup -d $tmpdev +rm -rf $tmpdir + diff --git a/target/rescue/build_stage2.sh b/target/rescue/build_stage2.sh new file mode 100644 index 000000000..ff801403b --- /dev/null +++ b/target/rescue/build_stage2.sh @@ -0,0 +1,162 @@ + +set -e +taropt="--use-compress-program=bzip2 -xf" + +echo_header "Creating 2nd stage filesystem:" +mkdir -p $disksdir/rescue_root ; cd $disksdir/rescue_root +# +package_map=' +00-dirtree +glibc22 +glibc23 +-gcc2 -gcc3 -gcc33 -gcc32 -gccx +-linux24-src -linux26-src -linux24benh-src +-linux24-source +-linux24-header -linux26-header -linux24benh-header +-linux24 -linux26 -linux24benh +-binutils -bin86 -nasm ++grub +lilo +yaboot +aboot ++silo +parted +mac-fdisk +pdisk ++xfsprogs +mkdosfs +jfsutils ++e2fsprogs +reiserfsprogs +genromfs +lvm ++raidtools +dump +eject +disktype ++hdparm -memtest86 +openssl +openssh ++mine -termcap +ncurses ++readline -strace -ltrace -perl5 +-m4 -time -gettext +zlib + +attr +acl +findutils ++mktemp +coreutils -diffutils -patch +-make +grep +sed +gzip ++tar +gawk -flex +bzip2 +-texinfo +less -groff -man ++nvi -bison +bc +cpio ++ed -autoconf -libtool ++curl +wget +dialog +minicom ++lrzsz +rsync +tcpdump +module-init-tools +-sysvinit +shadow +util-linux +wireless-tools ++net-tools +procps +psmisc -rockplug ++modutils +pciutils +portmap +busybox +-sysklogd -devfsd +setserial +iproute2 ++netkit-base +netkit-ftp +netkit-telnet +netkit-tftp ++sysfiles +libpcap +iptables +tcp_wrappers +-kiss +kbd -syslinux -rescue-stage1-init ++device-mapper +lvm2 +mdadm +dhcpcd ++smartmontools +' + +if [[ $rockver = 2.0* ]] ; then + package_map="$package_map +bash -automake " +else + package_map="$package_map +bash2 -bash3 -automake17 -automake18 +bize +ethtool " +fi + +package_map="+$ROCKCFG_DEFAULT_KERNEL $package_map" + +echo_status "Extracting the packages archives." +for x in $( ls $pkgsdir/*.tar.bz2 | \ + grep -v -e ':dev.tar.bz2' -e ':doc.tar.bz2' ) +do + x="`basename $x .tar.bz2`" + if echo "" $package_map "" | grep -q " +$x " + then + echo_status "\`- Extracting $x.tar.bz2 ..." + tar --use-compress-program=bzip2 -xpf $pkgsdir/$x.tar.bz2 + elif ! echo "" $package_map "" | grep -q " -$x " + then + echo_error "\`- Not found in \$package_map: $x" + echo_error " ... fix target/$target/build.sh" + fi +done +# +echo_status "Remove the stuff we don't need ..." +rm -rf home usr/{local,doc,man,info,games,share} +rm -rf var/adm/* var/games var/adm var/mail var/opt +rm -rf usr/{include,src} usr/*-linux-gnu {,usr/}lib/*.{a,la,o} +rm -rf etc/rc.d/rcX.d/ +for x in usr/lib/*/; do rm -rf ${x%/}; done +# +echo_status "Installing some terminfo databases ..." +tar $taropt $pkgsdir/ncurses.tar.bz2 \ + usr/share/terminfo/x/xterm usr/share/terminfo/a/ansi \ + usr/share/terminfo/n/nxterm usr/share/terminfo/l/linux \ + usr/share/terminfo/v/vt200 usr/share/terminfo/v/vt220 \ + usr/share/terminfo/v/vt100 usr/share/terminfo/s/screen +# +echo_status "Installing some keymaps ..." +tar $taropt $pkgsdir/kbd.tar.bz2 \ + usr/share/kbd/keymaps/amiga usr/share/kbd/keymaps/i386/qwerty \ + usr/share/kbd/keymaps/atari usr/share/kbd/keymaps/i386/qwertz \ + usr/share/kbd/keymaps/sun +find usr/share/kbd -name '*dvo*' -o -name '*az*' -o -name '*fgG*' | \ + xargs rm -f +# +#echo_status "Installing pci.ids ..." +#tar $taropt $pkgsdir/pciutils.tar.bz2 \ +# usr/share/pci.ids +# + +echo_status "Installing lvm-cycle-script ..." +cp -v $base/target/$target/contrib/init-boot-cycle sbin/init-lvm-cycle +chmod 755 sbin/init-lvm-cycle + +echo_status "Installing lvm2 wrapper ..." +cp -v $base/target/$target/contrib/lvm2wrap etc/conf/lvm2wrap + +echo_status "Creating init." +cp -v $rootdir/usr/bin/busybox sbin/init +cp -al sbin/init sbin/halt +cp -al sbin/init sbin/reboot +rm -f etc/inittab etc/HOSTNAME +< etc/inittab +::sysinit:/etc/init.d/rcS +vc/1::respawn:/sbin/agetty -f /etc/issue 38400 vc/1 linux +vc/2::respawn:/sbin/agetty -f /etc/issue 38400 vc/2 linux +vc/3::respawn:/sbin/agetty -f /etc/issue 38400 vc/3 linux +vc/4::respawn:/sbin/agetty -f /etc/issue 38400 vc/4 linux +vc/5::respawn:/sbin/agetty -f /etc/issue 38400 vc/5 linux +vc/6::respawn:/sbin/agetty -f /etc/issue 38400 vc/6 linux +EOF +< etc/issue + +\t \d -- \U online -- line [\l]. + +Welcome to \n (ROCK Linux advanced rescue system, Kernel \r). + +EOF +chmod 644 etc/issue + +< etc/shadow +root:::::::: +toor:*::::::: +bin:*::::::: +daemon:*::::::: +nobody:*::::::: +sshd:*::::::: +EOF +chmod 600 etc/shadow + +mkdir -p etc/init.d/ etc/boot.d/ +<<"EOF" cat > etc/init.d/rcS +#!/bin/sh +for x in /etc/boot.d/[0-9]* +do + [ -f $x ] && . $x +done +EOF +< etc/boot.d/05-system +[ -f /proc/mounts ] || mount -t proc none /proc +[ -d /mnt/boot ] || mkdir -p /mnt/boot +[ -d /dev/pts ] && mount /dev/pts +grep -q '/mnt_boot' /proc/mounts && mount --move /old_root/mnt_boot /mnt/boot +grep -q '/old_root' /proc/mounts && umount -n /old_root +grep -v ^rootfs /proc/mounts > /etc/mtab +EOF +< etc/boot.d/10-hostname +if [ -f /etc/HOSTNAME ] +then + /bin/hostname \`cat /etc/HOSTNAME\` +else + /bin/hostname "$ROCKFG_RESCUE_DEFAULT_HOSTNAME" +fi +EOF +chmod 755 etc/init.d/rcS etc/boot.d/[0-9][0-9]-* +echo_status "Creating system.tar.bz2 archive." +tar -cIf ../system.tar.bz2 * ; cd .. + diff --git a/target/rescue/config.hlp b/target/rescue/config.hlp new file mode 100644 index 000000000..6193185c8 --- /dev/null +++ b/target/rescue/config.hlp @@ -0,0 +1,28 @@ +# --- ROCK-COPYRIGHT-NOTE-BEGIN --- +# +# This copyright note is auto-generated by ./scripts/Create-CopyPatch. +# Please add additional copyright information _after_ the line containing +# the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by +# the ./scripts/Create-CopyPatch script. Do not edit this copyright text! +# +# ROCK Linux: rock-src/target/rescue/config.hlp +# ROCK Linux is Copyright (C) 1998 - 2004 Clifford Wolf +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. A copy of the GNU General Public +# License can be found at Documentation/COPYING. +# +# Many people helped and are helping developing ROCK Linux. Please +# have a look at http://www.rocklinux.org/ and the Documentation/TEAM +# file for details. +# +# --- ROCK-COPYRIGHT-NOTE-END --- + + +ROCKCFG_RESCUE_INITRD_USEKISS + If this options is enabled the kiss shell is installed into the first + stage initrd of the bootdisk. This is helpful for unusal installations + and debugging. + diff --git a/target/rescue/config.in b/target/rescue/config.in new file mode 100644 index 000000000..7410cc2a1 --- /dev/null +++ b/target/rescue/config.in @@ -0,0 +1,122 @@ +# --- ROCK-COPYRIGHT-NOTE-BEGIN --- +# +# This copyright note is auto-generated by ./scripts/Create-CopyPatch. +# Please add additional copyright information _after_ the line containing +# the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by +# the ./scripts/Create-CopyPatch script. Do not edit this copyright text! +# +# ROCK Linux: rock-src/target/bootdisk/config.in +# ROCK Linux is Copyright (C) 1998 - 2004 Clifford Wolf +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. A copy of the GNU General Public +# License can be found at Documentation/COPYING. +# +# Many people helped and are helping developing ROCK Linux. Please +# have a look at http://www.rocklinux.org/ and the Documentation/TEAM +# file for details. +# +# --- ROCK-COPYRIGHT-NOTE-END --- + +block_begin 0 + +bool 'Include the kiss shell into the initrd' ROCKCFG_RESCUE_INITRD_USEKISS 1 + +choice ROCKCFG_RESCUE_ACTION_SYSTEM_FAILURE "shell" \ + "reboot" "reboot if system fails to extract." \ + "panic" "panic if system fails to extract." \ + "shell" "give shell if system fails to extract" +choice ROCKCFG_RESCUE_ACTION_OVERLAY_FAILURE "ignore" \ + "ignore" "ignore if overlay fails to extract." \ + "reboot" "reboot if overlay fails to extract." \ + "panic" "panic if overlay fails to extract." \ + "shell" "give shell if overlay fails to extract" + +text "Hostname for the stage2 system" "ROCKFG_RESCUE_DEFAULT_HOSTNAME" "stage2" + +block_end + +pkgfilter sed ' + +# Select some packages explicitely (base) +/ lvm / { s/^[OX] /X /p; d; }; +/ mdadm / { s/^[OX] /X /p; d; }; +/ dhcpcd / { s/^[OX] /X /p; d; }; +/ lvm2 / { s/^[OX] /X /p; d; }; +/ device-mapper / { s/^[OX] /X /p; d; }; +/ smartmontools / { s/^[OX] /X /p; d; }; +/ rescue-stage1-init / { s/^[OX] /X /p; d; }; +/ busybox / { p; d; }; +/ dialog / { p; d; }; / bc / { p; d; }; +/ dump / { p; d; }; / cpio / { p; d; }; +/ ed / { p; d; }; / lrzsz / { p; d; }; +/ minicom / { p; d; }; / disktype / { p; d; }; +/ netkit-base / { p; d; }; / netkit-telnet / { p; d; }; +/ netkit-ftp / { p; d; }; / netkit-tftp / { p; d; }; +/ pciutils / { p; d; }; / portmap / { p; d; }; +/ reiserfsprogs / { p; d; }; / rsync / { p; d; }; +/ setserial / { p; d; }; / tcpdump / { p; d; }; +/ libpcap / { p; d; }; / tcp_wrappers / { p; d; }; +/ iptables / { p; d; }; / jfsutils / { p; d; }; +/ xfsprogs / { p; d; }; +/ kbd / { p; d; }; / eject / { p; d; }; +/ openssl / { p; d; }; / openssh / { p; d; }; + +# Select some packages explicitely (architectures) +/ bin86 / { p; d; }; +/ grub / { p; d; }; / lilo / { p; d; }; +/ memtest86 / { p; d; }; / aboot / { p; d; }; +/ silo / { p; d; }; / nasm / { p; d; }; +/ yaboot / { p; d; }; / aboot / { p; d; }; +/ mac-fdisk / { p; d; }; / pdisk / { p; d; }; +/ syslinux / { p; d; }; + +# Disable packages which are not in base or not build in stages 0-4 +/ base / ! { s/^X /O /p; d; }; /^. -----/ { s/^X /O /p; d; }; + +# Disable even more packages we do not need +/ gcc2 / { s/^X /O /p; d; }; / joe / { s/^X /O /p; d; }; +/ gdbm / { s/^X /O /p; d; }; / pam / { s/^X /O /p; d; }; +/ pdksh / { s/^X /O /p; d; }; / libelf / { s/^X /O /p; d; }; +/ prelink / { s/^X /O /p; d; }; / ccache / { s/^X /O /p; d; }; +/ cracklib / { s/^X /O /p; d; }; / hotplug / { s/^X /O /p; d; }; +/ devfsd / { s/^X /O /p; d; }; / rockplug / { s/^X /O /p; d; }; +/ cron / { s/^X /O /p; d; }; +/ dietlibc / { s/^X /O /p; d; }; +/ sysvinit / { s/^X /O /p; d; }; +/ uml_utilities / { s/^X /O /p; d; }; +/ python / { s/^X /O /p; d; }; +' +if [[ $rockver = 2.0* ]] ; then + pkgfilter sed ' + / KERNEL / { s/^X /O /p; d; }; + / linux26-src / { s/^X /O /p; d; }; + ' + ROCKCFGSET_PKG_GCC3_NO_JAVA=1 +else + pkgenable linux; + ROCKCFGSET_PKG_LINUX_SRC26=0 + ROCKCFGSET_PKG_LINUX_IMG26=0 + + ROCKCFGSET_PKG_GCC32_NO_JAVA=1 + ROCKCFGSET_PKG_GCC34_NO_JAVA=1 +fi ; + + +ROCKCFGSET_CREATE_TARBZ2=1 +ROCKCFGSET_CREATE_GEM=0 +ROCKCFGSET_PKGFILE_VER=0 + +ROCKCFGSET_PKG_TERMCAP_USEIT=1 +ROCKCFGSET_PKG_GCC2_NO_CHILL=1 +ROCKCFGSET_PKG_GCC33_NO_JAVA=1 +ROCKCFGSET_PKG_BASH_PROGCOMP=0 + +ROCKCFGSET_DO_REBUILD_STAGE=0 +ROCKCFGSET_CREATE_DOCS=0 +ROCKCFGSET_DISABLE_NLS=1 +ROCKCFGSET_OPTSIZE=1 +ROCKCFGSET_LIMITCXX=1 + diff --git a/target/rescue/contrib/init-boot-cycle b/target/rescue/contrib/init-boot-cycle new file mode 100644 index 000000000..8b1c262ea --- /dev/null +++ b/target/rescue/contrib/init-boot-cycle @@ -0,0 +1,97 @@ +#!/bin/sh +# +# This boot-script boots a system found in a given LVM +# logical volume. +# In case of trouble it passes control to the original init +# thus giving gettys and running /etc/boot.d/* +# It is included in system.tar.bz2. For usage information +# see below. +# +# Plan: +# -read kernel append line by /proc/1/environ and evaluate +# ROOTLV (should point to /dev/vg00/lvroot00 or kind of) +# -mount ROOTLV to /mnt/root (ro) +# -pivot_root to /mnt/root +# -chroot into /mnt/root and exec init +# +# mini-howto of usage: +# +# -build your rescue target (you get system.tar.bz2 and initrd.img) +# -put system.tar.bz2 in /rescue onto your boot-device-fs +# -optional: put overlay.tar.bz2 in /rescue onto your boot-device-fs +# -get a kernel and arm your favorite boot-loader +# -pass stage2init=/sbin/init-lvm-cycle to the kernel +# -pass ROOTLV=/dev/vgXX/lvYYY to the kernel +# -don't forget to pass initrd.img to your boot loader +# -and boot +# +# you can omit ROOTLV parameter to get the rescue system +# +# see contrib/menu.lst-example +# +# Tobias Hintze (c) 2004 +# + +shopt -s execfail + +fail() { + echo "$1" + echo + echo "continuing inside rescue-stage2..." + exec /sbin/init + echo "failed to execute /sbin/init." + echo "all that i can give to you is that shell." + echo + exec sh +} + +fail_shell() { + echo "$1" + echo + echo "try to fix the problem and terminate this shell." + echo + sh +} + +# some init +export PATH=/sbin:/bin:/usr/sbin:/usr/bin +mount -t proc none /proc +mkdir /mnt/boot /mnt/root +mount --move /old_root/mnt_boot /mnt/boot +umount -n /old_root + +# read ROOTLV and additional arguments (e.g. runlevel) +ROOTLV=`cat /proc/1/environ | tr '\0' '\n' | grep -i ^rootlv | cut -d= -f2` +[ -z "$ROOTLV" ] && fail "no ROOTLV specified." + +INITARGS="" +RUNLEVEL=`cat /proc/1/environ | tr '\0' '\n' | grep -i ^runlevel | cut -d= -f2` +if [ ! -z "$RUNLEVEL" ] ; then + echo "runlevel specified. passing $RUNLEVEL to init." + INITARGS="$RUNLEVEL" +fi + +# scan for and activate volume groups +[ -f /etc/conf/lvm2wrap ] && . /etc/conf/lvm2wrap +vgscan && vgchange -ay +[ -e "$ROOTLV" ] || fail "specified ROOTLV does not exist." + +# mount new root +mount -o ro $ROOTLV /mnt/root +cd /mnt/root + +# move mounts inside new root +[ -d dev ] || fail_shell "dev/ mountpoint does not exist." +mount --move /dev dev +[ -d mnt/boot ] || fail_shell "mnt/boot/ mountpoint does not exist." +mount --move /mnt/boot mnt/boot + +[ -d mnt/oldroot ] || fail_shell "mnt/oldroot/ mountpoint does not exist." +umount /proc + +# switch to new root and exec init +mknod dev/initctl p +pivot_root . mnt/oldroot +exec chroot . sh -c "umount /mnt/oldroot ; exec /sbin/init $INITARGS" \ + dev/console 2>&1 +fail "pivot_root failed..." diff --git a/target/rescue/contrib/lvm2wrap b/target/rescue/contrib/lvm2wrap new file mode 100644 index 000000000..0b1e561ac --- /dev/null +++ b/target/rescue/contrib/lvm2wrap @@ -0,0 +1,47 @@ +# +# This script (which must be sourced and not executed) +# checks kernel version and modifies PATH to use lvm2 +# when linux-2.6 is detected. +# +# It creates a directory containing symlinks to /sbin/lvm2 +# and inserts it in $PATH as first element. +# +# Thus calling vgscan, vgchange, vgdisplay and so on +# calls the lvm2 binary - when kernel version is 2.6. +# +# Tobias Hintze (c) 2004 +# +# $Revision: 1.4 $ +# + +LVMBINS=" + dumpconfig lvchange lvcreate lvdisplay lvextend + lvmchange lvmdiskscan lvmsadc lvmsar lvreduce + lvremove lvrename lvresize lvs lvscan + pvchange pvcreate pvdata pvdisplay pvmove + pvremove pvresize pvs pvscan vgcfgbackup + vgcfgrestore vgchange vgck vgconvert vgcreate + vgdisplay vgexport vgextend vgimport vgmerge + vgmknodes vgreduce vgremove vgrename vgs + vgscan vgsplit lvm +" + +LVM2WRAPDIR=/sbin/lvm2-wrapper-dir + +if [[ `uname -r` == 2.6.* ]] +then + # create symlink-dir + ( + mkdir -p $LVM2WRAPDIR + cd $LVM2WRAPDIR + for x in $LVMBINS + do + rm -f $x + ln /sbin/lvm2 $x + done + ) + # check kernel/lvm version + PATH=$LVM2WRAPDIR:$PATH +fi +export PATH + diff --git a/target/rescue/contrib/menu.lst-example b/target/rescue/contrib/menu.lst-example new file mode 100644 index 000000000..c649f4c38 --- /dev/null +++ b/target/rescue/contrib/menu.lst-example @@ -0,0 +1,41 @@ +# +# LVM boot cycle: +# Boot device is a small partition with dos-like filesystem. +# Some PC manufacturers always create such partitions for their +# utilities. It can be used to get a rescue stage2 running and thus +# getting up your whole system. There is no need for another partition +# except the LVM physical volume that holds your volume groups. +# +title ROCK Linux productive LVM boot cycle +kernel (hd0,0)/vmlinuz-2.6.7 root=/dev/ram0 overlay_failure=ignore boot=vfat:/dev/discs/disc0/part1 stage2init=/sbin/init-lvm-cycle rootlv=/dev/vg00/lvroot0 panic=10 +initrd (hd0,0)/rescue/initrd.img + +# +# rescue from hdd: +# System location defaults to "/mnt_boot/rescue/system.tar.bz2" here. +# Default boot device is /dev/discs/disc0/part1. +# No rootlv param is given so we will reach stage2 with gettys here. +# +title ROCK Linux advanced rescue system from HDD +kernel (hd0,0)/vmlinuz-2.6.7 root=/dev/ram0 overlay_failure=ignore +initrd (hd0,0)/rescue/initrd.img + +# +# rescue from CDROM (fdemu): +# We pass the boot param to give correct filesystem type and block +# device. +# +title ROCK Linux advanced rescue system from CDROM +kernel (hd0)/vmlinuz root=/dev/ram0 boot=iso9660:/dev/cdroms/cdrom0 panic=30 +initrd (fd0)/initrd.gz + +# +# LVM boot cycle from CDROM: +# We even load or stage2 from CDROM so we need no partition except some +# physical volume to hold our volume groups. +# +title ROCK Linux productive - LVM boot cycle (from CDROM) +kernel (fd0)/vmlinuz root=/dev/ram0 boot=iso9660:/dev/cdroms/cdrom0 stage2init=/sbin/init-lvm-cycle rootlv=/dev/vg00/lvroot0 panic=30 +initrd (fd0)/initrd.gz + + diff --git a/target/rescue/contrib/mkrescueiso.sh b/target/rescue/contrib/mkrescueiso.sh new file mode 100644 index 000000000..ad612b626 --- /dev/null +++ b/target/rescue/contrib/mkrescueiso.sh @@ -0,0 +1,150 @@ +#!/bin/sh +# +# This is a contributed script to create a bootable ISO image from your +# rescue target build. +# +# (C) 2004 Tobias Hintze +# + +GRUBSRC=/usr/share/grub/i386-* +set -e + +usage() { + echo "Usage:" + echo " $0 ISODIR FDDIR" + echo " creates the iso from iso-dir and fd-dir" + echo + echo " $0 -c KERNEL INITRD[.gz] SYSTEM [OVERLAY]" + echo " creates iso-dir and fd-dir" + echo + echo " $0 -C KERNEL INITRD[.gz] SYSTEM [OVERLAY]" + echo " creates the iso from kernel, initrd and system tarball" + echo "" + echo "initrd.img and system.tar.bz2 are generated during the" + echo "rescue-target build." + echo "" + echo "the kernel must have support for devfs and initrd." + echo "" + exit 1 +} + +die() { + echo "$1" + exit 2 +} + +test -z "$1" && usage + +if [ "$1" == "-c" ] ; then + CREATEDIRS=1 +fi +if [ "$1" == "-C" ] ; then + CREATEDIRS=2 +fi +if [ ! -z "$CREATEDIRS" ] +then + shift + TMPDIR=/var/tmp/rescue.$$ + mkdir $TMPDIR || die "failed to create tmp-dir \"$TMPDIR\"." + mkdir -v $TMPDIR/iso $TMPDIR/fd + + # + # prepare fd dir + # + test -z "$1" && usage + KERNEL=$1 ; shift + test -z "$1" && usage + INITRD=$1 ; shift + test -z "$1" && usage + SYSTEM=$1 ; shift + + # kernel to fd + cp -v $KERNEL $TMPDIR/fd/bzImage + + # initrd to fd + if [ "`file -bi $INITRD`" == "application/x-gzip" ] ; then + cp -v $INITRD $TMPDIR/fd/initrd.gz + else + echo "compressing initrd image..." + cat $INITRD | gzip -c > $TMPDIR/fd/initrd.gz + fi + + mkdir $TMPDIR/fd/grub + # menu.lst to fd + cat > $TMPDIR/fd/grub/menu.lst << EOF +timeout 10 +title rescue ramdisk from cdrom +kernel (fd0)/bzImage root=/dev/ram0 boot=iso9660:/dev/cdroms/cdrom0 panic=30 +initrd (fd0)/initrd.gz + +title LVM-boot-cycle +configfile (fd0)/grub/menu.lst-LBC +EOF + cat > $TMPDIR/fd/grub/menu.lst-LBC << EOF + +title lvm boot cycle rootlv=/dev/vg00/lvroot0 +kernel (fd0)/bzImage root=/dev/ram0 boot=iso9660:/dev/cdroms/cdrom0 stage2init=/sbin/init-lvm-cycle rootlv=/dev/vg00/lvroot0 panic=30 +initrd (fd0)/initrd.gz + +title lvm boot cycle rootlv=/dev/vg00/lvroot1 +kernel (fd0)/bzImage root=/dev/ram0 boot=iso9660:/dev/cdroms/cdrom0 stage2init=/sbin/init-lvm-cycle rootlv=/dev/vg00/lvroot1 panic=30 +initrd (fd0)/initrd.gz + +title lvm boot cycle rootlv=/dev/vg00/lv00 +kernel (fd0)/bzImage root=/dev/ram0 boot=iso9660:/dev/cdroms/cdrom0 stage2init=/sbin/init-lvm-cycle rootlv=/dev/vg00/lv00 panic=30 +initrd (fd0)/initrd.gz +EOF + cp -v $GRUBSRC/stage[12] $GRUBSRC/{e2fs,fat,xfs}_stage1_5 $TMPDIR/fd/grub/ + + # + # prepare iso dir + # + mkdir $TMPDIR/iso/rescue/ + cp -v $SYSTEM $TMPDIR/iso/rescue/system.tar.bz2 + + if [ ! -z "$1" ] ; then + OVERLAY=$1 ; shift + cp -v $OVERLAY $TMPDIR/iso/rescue/overlay.tar.bz2 + fi + + if [ "$CREATEDIRS" == "1" ] ; then + echo "ready. you might want to run:" + echo "$0 $TMPDIR/iso $TMPDIR/fd" + elif [ "$CREATEDIRS" == "2" ] ; then + echo "running $0 $TMPDIR/iso $TMPDIR/fd" + $0 $TMPDIR/iso $TMPDIR/fd + rm -rfv $TMPDIR/iso $TMPDIR/fd + rmdir -v $TMPDIR + fi + exit 0 +fi + +ISODIR=$1 ; shift + +test -z "$1" && usage +FDDIR=$1 ; shift + +test -d $ISODIR || die "ISODIR \"$ISODIR\" not a directory." +test -d $FDDIR || die "FDDIR \"$FDDIR\" not a directory." + +e2fsimage -f $ISODIR/fdemu.img -d $FDDIR -v -s 2880 +rm -f $ISODIR/device.map-$$ +echo "(fd0) $ISODIR/fdemu.img" > $ISODIR/device.map-$$ +if [ "`id -u`" == "0" ] +then + die "i don't want to run grub as root. destructive potential too high." +fi +grub --device-map=$ISODIR/device.map-$$ --batch <