Browse Source

Stefan Fiedler:


			
			
				rocklinux
			
			
		
Stefan Fiedler 19 years ago
parent
commit
c0596153aa
4 changed files with 586 additions and 532 deletions
  1. +83
    -24
      target/livecd/build_stage1.sh
  2. +5
    -1
      target/livecd/build_stage2.sh
  3. +0
    -507
      target/livecd/linuxrc.c
  4. +498
    -0
      target/livecd/linuxrc.sh

+ 83
- 24
target/livecd/build_stage1.sh

@ -2,8 +2,8 @@
echo_header "Creating initrd data:" echo_header "Creating initrd data:"
rm -rf $disksdir/initrd rm -rf $disksdir/initrd
mkdir -p $disksdir/initrd/{dev,sys,proc,mnt/{cdrom,floppy,stick,}} mkdir -p $disksdir/initrd/{dev,sys,proc,mnt/{cdrom,floppy,stick,}}
mkdir -p $disksdir/initrd/mnt/{cowfs_ro/{bin,lib},cowfs_rw}
cd $disksdir/initrd; ln -s mnt/cowfs_ro/bin mnt/cowfs_ro/sbin;
mkdir -p $disksdir/initrd/mnt/{cowfs_ro/{etc,home,bin,sbin,opt,usr/{bin,sbin},tmp,var,lib},cowfs_rw}
cd $disksdir/initrd
# #
echo_status "Creating read-only symlinks..." echo_status "Creating read-only symlinks..."
for d in etc home bin sbin opt usr tmp var lib ; do for d in etc home bin sbin opt usr tmp var lib ; do
@ -15,36 +15,60 @@ if [ -L $disksdir/2nd_stage/lib64 ] ; then
ln -s /mnt/cowfs_rw/lib64 lib64 ln -s /mnt/cowfs_rw/lib64 lib64
ln -s /mnt/cowfs_ro/lib64 mnt/cowfs_rw/lib64 ln -s /mnt/cowfs_ro/lib64 mnt/cowfs_rw/lib64
fi fi
#
if [ -x ../../../usr/bin/diet ] ; then
export DIETHOME="../../../usr/dietlibc"
LXRCCC="../../../usr/bin/diet $CC";
elif [ -x /usr/bin/diet ] ; then
echo_status "using host's diet - did the target's dietlibc build fail?"
LXRCCC="/usr/bin/diet $CC";
else
echo_status "diet not found - using glibc -static - initrd may be too big..."
LXRCCC="$CC -static"
fi
echo_status "Create linuxrc binary."
$LXRCCC $base/target/$target/linuxrc.c -Wall \
-DSTAGE_2_IMAGE="\"${ROCKCFG_SHORTID}/2nd_stage.img.z\"" \
-o linuxrc
echo_status "Creating some device nodes"
mknod dev/ram0 b 1 0
mknod dev/null c 1 3
mknod dev/zero c 1 5
mknod dev/tty c 5 0
mknod dev/console c 5 1
echo_status "Create checkisomd5 binary"
cp -r ${base}/misc/isomd5sum ${base}/build/${ROCKCFG_ID}/
cat >${base}/build/${ROCKCFG_ID}/compile_isomd5sum.sh <<EOF
#!/bin/bash
cd /isomd5sum
make clean
make CC=gcc
EOF
chmod +x ${base}/build/${ROCKCFG_ID}/compile_isomd5sum.sh
chroot ${base}/build/${ROCKCFG_ID}/ /compile_isomd5sum.sh
cp ${base}/build/${ROCKCFG_ID}/isomd5sum/checkisomd5 mnt/cowfs_ro/bin/
rm -rf ${base}/build/${ROCKCFG_ID}/compile_isomd5sum.sh ${base}/build/${ROCKCFG_ID}/isomd5sum
echo_status "Copying and adjusting linuxrc scipt"
cp ${base}/target/${target}/linuxrc.sh linuxrc
chmod +x linuxrc
#sed -i -e "s,^STAGE_2_BIG_IMAGE=\"2nd_stage.tar.gz\"$,STAGE_2_BIG_IMAGE=\"${ROCKCFG_SHORTID}/2nd_stage.tar.gz\"," \
# -e "s,^STAGE_2_SMALL_IMAGE=\"2nd_stage_small.tar.gz\"$,STAGE_2_SMALL_IMAGE=\"${ROCKCFG_SHORTID}/2nd_stage_small.tar.gz\"," \
sed -i -e "s,\(^STAGE_2_BIG_IMAGE=\"\)\(2nd_stage.img.z\"$\),\1${ROCKCFG_SHORTID}/\2," \
linuxrc
# #
echo_status "Copy various helper applications." echo_status "Copy various helper applications."
cp ../2nd_stage/bin/{tar,gzip} mnt/cowfs_ro/bin/ cp ../2nd_stage/bin/{tar,gzip} mnt/cowfs_ro/bin/
cp ../2nd_stage/sbin/hwscan mnt/cowfs_ro/bin/
cp ../2nd_stage/sbin/hwscan mnt/cowfs_ro/sbin/
cp ../2nd_stage/usr/bin/gawk mnt/cowfs_ro/bin/ cp ../2nd_stage/usr/bin/gawk mnt/cowfs_ro/bin/
for file in ../2nd_stage/bin/{tar,gzip,bash2,bash,sh,mount,umount,ls,cat,uname,rm,ln,mkdir,rmdir,gawk,awk,grep,sleep,dmesg} \
../2nd_stage/sbin/{ip,hwscan,pivot_root,swapon,swapoff,udev*,losetup} \
../2nd_stage/usr/bin/{wget,find,expand,readlink} \
../2nd_stage/usr/sbin/lspci ; do
programs="${programs} ${file#../2nd_stage}"
cp ${file} mnt/cowfs_ro/${file#../2nd_stage/}
done
cp -a $build_root/etc/udev mnt/cowfs_ro/etc/
for x in modprobe.static modprobe.static.old \ for x in modprobe.static modprobe.static.old \
insmod.static insmod.static.old insmod.static insmod.static.old
do do
if [ -f ../2nd_stage/sbin/${x/.static/} ]; then if [ -f ../2nd_stage/sbin/${x/.static/} ]; then
rm -f mnt/cowfs_ro/bin/${x/.static/} rm -f mnt/cowfs_ro/bin/${x/.static/}
cp -a ../2nd_stage/sbin/${x/.static/} mnt/cowfs_ro/bin/
cp -a ../2nd_stage/sbin/${x/.static/} mnt/cowfs_ro/sbin/
fi fi
if [ -f ../2nd_stage/sbin/$x ]; then if [ -f ../2nd_stage/sbin/$x ]; then
rm -f mnt/cowfs_ro/bin/$x mnt/cowfs_ro/bin/${x/.static/} rm -f mnt/cowfs_ro/bin/$x mnt/cowfs_ro/bin/${x/.static/}
cp -a ../2nd_stage/sbin/$x mnt/cowfs_ro/bin/
cp -a ../2nd_stage/sbin/$x mnt/cowfs_ro/sbin/
ln -sf $x mnt/cowfs_ro/bin/${x/.static/} ln -sf $x mnt/cowfs_ro/bin/${x/.static/}
fi fi
done done
@ -64,9 +88,44 @@ for x in ../2nd_stage/lib/modules/*/modules.{dep,pcimap,isapnpmap} ; do
done done
# #
rm -f mnt/cowfs_ro/lib/modules/[0-9]*/kernel/drivers/net/{dummy,ppp*}.{o,ko} rm -f mnt/cowfs_ro/lib/modules/[0-9]*/kernel/drivers/net/{dummy,ppp*}.{o,ko}
#
echo_status "Adding kiss shell for expert use of the initrd image."
cp $build_root/bin/kiss mnt/cowfs_ro/bin/
echo_status "Copying necessary libraries"
libs="/lib/ld-linux.so.2 /lib/libdl.so.2 /lib/libc.so.6 /lib/librt.so.1 /lib/libpthread.so.0 /usr/lib/libpopt.so.0"
# libpopt from checkisomd5 which is not in build/*
for x in ${programs} ; do
[ -e ./$x ] || continue
file $x | grep -q ELF || continue
libs="$libs `chroot ${base}/build/${ROCKCFG_ID} ldd $x 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '`"
done
while [ -n "$libs" ] ; do
oldlibs=$libs
libs=""
for x in $oldlibs ; do
mkdir -p mnt/cowfs_ro/${x%/*}
if [ ! -e ./$x ] ; then
cp ${base}/build/${ROCKCFG_ID}/$x mnt/cowfs_ro/$x
echo_status "- ${x##*/}"
fi
file $x | grep -q ELF || continue
for y in `chroot ${base}/build/${ROCKCFG_ID} ldd $x 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '` ; do
[ ! -e "./$y" ] && libs="$libs $y"
done
done
done
echo_status "Creating links for identical files."
while read ck fn
do
if [ "$oldck" = "$ck" ] ; then
echo_status "\`- Found $fn -> $oldfn."
rm $fn ; ln -s ${oldfn#.} $fn
else
oldck=$ck ; oldfn=$fn
fi
done < <( find -type f | xargs md5sum | sort )
cd .. cd ..
echo_header "Creating initrd filesystem image: " echo_header "Creating initrd filesystem image: "
@ -89,7 +148,7 @@ fi
echo_status "Using loopback device $tmpdev." echo_status "Using loopback device $tmpdev."
# #
echo_status "Writing initrd image file." echo_status "Writing initrd image file."
mke2fs -m 0 -N 180 -q $tmpdev &> /dev/null
mke2fs -m 0 -N 360 -q $tmpdev &> /dev/null
mount -t ext2 $tmpdev $tmpdir mount -t ext2 $tmpdev $tmpdir
rmdir $tmpdir/lost+found/ rmdir $tmpdir/lost+found/
cp -a initrd/* $tmpdir cp -a initrd/* $tmpdir

+ 5
- 1
target/livecd/build_stage2.sh

@ -36,13 +36,17 @@ cp -f $base/target/$target/fixedfiles/system etc/rc.d/init.d/system
cp -f $base/target/$target/fixedfiles/xorg.conf etc/X11/xorg.conf cp -f $base/target/$target/fixedfiles/xorg.conf etc/X11/xorg.conf
# #
echo_status "Creating home directories and users..." echo_status "Creating home directories and users..."
mkdir home/{rocker,root}
mkdir home/{rocker,root}
chown 1000:100 home/rocker chown 1000:100 home/rocker
sed -i -e 's,root:.*,root:x:0:0:root:/home/root:/bin/bash,' etc/passwd sed -i -e 's,root:.*,root:x:0:0:root:/home/root:/bin/bash,' etc/passwd
sed -i -e 's,root:.*,root:$1$1YssESn0$Y9LvBGGXpsZhjNKZ0x8OM/:12548::::::,' etc/shadow sed -i -e 's,root:.*,root:$1$1YssESn0$Y9LvBGGXpsZhjNKZ0x8OM/:12548::::::,' etc/shadow
sed -i -e 's,sound:x:17:,sound:x:17:rocker,' etc/group sed -i -e 's,sound:x:17:,sound:x:17:rocker,' etc/group
echo 'rocker:x:1000:100:ROCK Live CD User:/home/rocker:/bin/bash' >> etc/passwd echo 'rocker:x:1000:100:ROCK Live CD User:/home/rocker:/bin/bash' >> etc/passwd
echo 'rocker:$1$//TuI8QD$kTxVesUbGLNKuxILuK2UN/:12548:0:99999:7:::' >> etc/shadow echo 'rocker:$1$//TuI8QD$kTxVesUbGLNKuxILuK2UN/:12548:0:99999:7:::' >> etc/shadow
echo 'wheel:x:440:rocker' >> etc/group
echo 'wheel:!::rocker' >> etc/gshadow
# #
echo_status "activating shadowfs through /etc/ld.so.preload" echo_status "activating shadowfs through /etc/ld.so.preload"
echo "/usr/lib/libcowfs.so" > etc/ld.so.preload echo "/usr/lib/libcowfs.so" > etc/ld.so.preload

+ 0
- 507
target/livecd/linuxrc.c

@ -1,507 +0,0 @@
/*
* --- 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/livecd/linuxrc.c
* ROCK Linux is Copyright (C) 1998 - 2006 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 ---
*
* linuxrc.c is Copyright (C) 2003, 2004 Cliford Wolf and Rene Rebe
*
*/
#include <sys/mount.h>
#include <sys/swap.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/klog.h>
#include <sys/utsname.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/ioctl.h>
/* this is actually a file included in dietlibc! */
#include <linux/loop.h>
#ifndef STAGE_2_IMAGE
# define STAGE_2_IMAGE "2nd_stage.img.z"
#endif
#define DEBUG(F...) debug(__LINE__,F)
char mod_loader[50];
char mod_dir[255];
char mod_suffix[3];
int mod_suffix_len=0;
int do_debug=0;
char init2[32] = "/sbin/init";
void debug(int line, const char* format, ...)
{
if(do_debug == 0) return;
va_list ap;
char string[128];
va_start(ap, format);
vsnprintf(string, sizeof(string), format, ap);
fprintf(stderr,"%i: %s\n", line, string);
va_end(ap);
return;
}
void mod_load_info(char *mod_loader, char *mod_dir, char *mod_suffix)
{
struct utsname uts_name;
if(uname(&uts_name) < 0) {
perror("unable to perform uname syscall correctly");
return;
} else if(strcmp(uts_name.sysname, "Linux") != 0) {
printf("Your operating system is not supported ?!\n");
return;
}
strcpy(mod_loader, "/bin/insmod");
strcpy(mod_dir, "/lib/modules/");
strcat(mod_dir, uts_name.release);
/* kernel module suffix for <= 2.4 is .o, .ko if above */
if(uts_name.release[2] > '4') {
strcpy(mod_suffix, ".ko");
} else {
strcpy(mod_suffix, ".o");
}
return;
}
int loop_mount(const char *device, const char* file)
{
DEBUG("loop mounting %s on %s", device, file);
struct loop_info loopinfo;
int fd, ffd;
if ((ffd = open(file, O_RDONLY)) < 0) {
perror(file);
return 1;
}
if ((fd = open(device, O_RDONLY)) < 0) {
perror(device);
return 1;
}
memset(&loopinfo, 0, sizeof(loopinfo));
snprintf(loopinfo.lo_name, LO_NAME_SIZE, "%s", file);
loopinfo.lo_offset = 0;
loopinfo.lo_encrypt_key_size = 0;
loopinfo.lo_encrypt_type = LO_CRYPT_NONE;
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
perror("ioctl: LOOP_SET_FD");
return 1;
}
close(ffd);
if(ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
perror("ioctl: LOOP_SET_STATUS");
(void) ioctl(fd, LOOP_CLR_FD, 0);
close(fd);
return 1;
}
close(fd);
DEBUG("loop mount worked like a charm.");
return 0;
}
void doboot()
{
DEBUG("doboot starting - trying to exec %s",init2);
if ( access(init2, R_OK) ) { perror("Can't access 2nd stage init"); }
else {
/* i get 'bad address' if i don't wait a bit here... */
sleep(1);
execlp(init2,init2,NULL);
perror("execlp init2 failed");
}
DEBUG("doboot returning - oops!");
}
int trymount (const char* source, const char* target)
{
DEBUG("trying to mount %s on %s...", source, target);
if(mount(source, target, "iso9660", MS_RDONLY, NULL) != 0) {
DEBUG("try failed");
return 1;
}
DEBUG("mount succeeded.");
return 0;
}
void trywait(pid)
{
if (pid < 0) perror("fork");
else waitpid(pid, NULL, 0);
}
/* check wether a file is a directory */
int is_dir(const struct dirent *entry)
{
struct stat tmpstat;
lstat(entry->d_name, &tmpstat);
return S_ISDIR(tmpstat.st_mode);
}
/* this is used in the module loading system for sorting dirs before files */
int dirs_first_sort(const struct dirent **a, const struct dirent **b)
{
if(is_dir(*a)) {
if(is_dir(*b)) return 0;
else return 1;
} else if(is_dir(*b)) {
return -1;
} else return 0;
}
/* this is used in the rm -r implementation */
int no_dot_dirs_filter(const struct dirent *entry)
{
if( is_dir(entry) && (!strcmp(entry->d_name,".") || !strcmp(entry->d_name,"..")) ) return 0;
else return 1;
}
/* my own rm -r implementation - :P */
int rm_recursive(char* directory)
{
struct dirent **namelist;
char oldcwd[256];
int n, ret=0;
getcwd(oldcwd, 256);
if(chdir(directory)) {
perror("chdir");
exit(1);
}
n = scandir(".", &namelist, no_dot_dirs_filter, dirs_first_sort);
if (n < 0) {
perror("scandir"); ret = -1;
}
while(n--) {
if(is_dir(namelist[n])){
if(rmdir(namelist[n]->d_name) != 0) {
rm_recursive(namelist[n]->d_name);
}
} else {
if(unlink(namelist[n]->d_name) != 0) {
perror("unable to remove file"); fflush(stdout);
ret = -1;
}
}
free(namelist[n]);
}
free(namelist);
chdir(oldcwd);
if(strcmp(directory,".") && rmdir(directory) != 0) {
perror("could not delete just-left meant-to-be-empty directory");
ret = -1;
}
return ret;
}
int getdevice(char* devstr, int devlen)
{
char devicebase[20] = "/dev/cdroms/cdrom%d";
char *devn[10];
char devicefile[100];
char filename[100];
int tmp_nr, nr=0;
for (tmp_nr = 0; tmp_nr < 10; ++tmp_nr) {
snprintf(devicefile, 100, devicebase, tmp_nr);
DEBUG("checking if %s is still a valid device", devicefile);
if ( access (devicefile, R_OK) ) {
DEBUG("%s first unvalid device, break search", devicefile);
break;
} else {
DEBUG("%s still valid",devicefile);
}
devn[nr++] = strdup (devicefile);
}
if (!nr) {
DEBUG("could not find a suitable cdrom device!\n");
return -2;
}
devn[nr] = NULL;
snprintf(filename,100,"/mnt/cdrom/%s",STAGE_2_IMAGE);
DEBUG("looking for %s on valid devices",STAGE_2_IMAGE);
for (nr=0; devn[nr]; nr++) {
if(trymount(devn[nr], "/mnt/cdrom") == 0) {
if( access(filename, R_OK) ) {
DEBUG("mounted %s, but could not access %s! continuing\n", devn[nr], filename);
if(umount("/mnt/cdrom") != 0) { perror("umount wrong cdrom failed"); break; }
continue;
}
strncpy(devstr, devn[nr], devlen);
DEBUG("found 2nd stage image on %s", devstr);
return 0;
}
}
printf("unable to find a device containing %s!\n", STAGE_2_IMAGE);
return -1;
}
int prepare_root() {
struct dirent **namelist;
char source[256], target[256];
int n, ret=0;
/* we need to fix some things in /dev */
DEBUG("preparing /dev");
if(chdir("/dev") != 0) { perror("could not chdir to /dev!"); ret=-1; }
unlink("fd"); /*no problem if this fails*/
if(symlink("/proc/kcore","core") != 0) { perror("could not symlink /proc/kcore to /dev/core"); ret=-1; }
if(symlink("/proc/self/fd","fd") != 0) { perror("could not symlink /proc/self/fd to /dev/fd"); ret=-1; }
if(symlink("fd/0","stdin") != 0) { perror("could not symlink /dev/fd/0 to /dev/stdin"); ret=-1; }
if(symlink("fd/1","stdout") != 0) { perror("could not symlink /dev/fd/1 to /dev/stdout"); ret=-1; }
if(symlink("fd/2","stderr") != 0) { perror("could not symlink /dev/fd/2 to /dev/stderr"); ret=-1; }
if(chdir("/") != 0) { perror("could not chdir to /!"); ret=-1; }
/* now create symlinks to the ro dir in the ramdisk */
chdir("/mnt/cowfs_ro");
n = scandir(".", &namelist, no_dot_dirs_filter, NULL);
if (n < 0) {
perror("scandir"); ret = -1;
}
while(n--) {
snprintf(source, 256, "/mnt/cowfs_ro/%s",namelist[n]->d_name);
snprintf(target, 256, "/mnt/cowfs_rw/%s",namelist[n]->d_name);
if (symlink(source, target) != 0) {
printf("error in symlinking %s -> %s\n",source,target);
ret = -1;
}
free(namelist[n]);
}
free(namelist);
chdir("/");
umask(00);
unlink("/mnt/cowfs_rw/home");
unlink("/mnt/cowfs_rw/tmp");
mkdir("/mnt/cowfs_rw/home",0755);
mkdir("/mnt/cowfs_rw/tmp",0777);
mkdir("/mnt/cowfs_rw/home/rocker",0755);
mkdir("/mnt/cowfs_rw/home/root",0700);
if(chown("/mnt/cowfs_rw/home/rocker",1000,100) != 0) {
perror("could not chown /mnt/cowfs_rw/home/rocker to rocker:users"); ret=-1;
}
umask(022);
return ret;
}
void load_ramdisk_file() {
char text[120], devicefile[100];
char filename[100];
int ret = 0;
int ro_fd;
strcpy(filename, STAGE_2_IMAGE);
DEBUG("set stage 2 filename to %s",filename);
/* this is retry stuff is needed for my firewire (sbp2) cd drive ... */
do {
ret = getdevice(devicefile, 100);
if (ret == -1) {
printf("getdevice failed: no cd with image found...\n");
return;
} else if (ret == -2) {
sleep(2);
printf("no cdrom drive found - retrying...\n");
}
} while( ret != 0 );
snprintf(text, 120, "/mnt/cdrom/%s", filename);
DEBUG("setting up loop device...");
if(loop_mount("/dev/loop/0",text) != 0) {
DEBUG("loop device setup failed ... :(");
return;
}
DEBUG("saving filedescriptor of /mnt/cowfs_ro");
ro_fd = open("/mnt/cowfs_ro",O_RDONLY); if(ro_fd < 0) { perror("open"); return; }
chdir("/mnt/cowfs_ro");
if(rm_recursive(".") != 0) return;
DEBUG("mounting loop device on /mnt/cowfs_ro ... ");
if( mount("/dev/loop/0", "/mnt/cowfs_ro", "squashfs", MS_RDONLY, NULL) )
{ perror("Can't mount squashfs on /mnt/cowfs_ro!"); return; }
DEBUG("mounting tmpfs on /mnt/cowfs_rw");
if ( mount("none", "/mnt/cowfs_rw", "tmpfs", 0, NULL) )
{ perror("Can't mount /mnt/cowfs_rw"); return; }
/* create symlinks for needed directories, create special files */
if(prepare_root() == 0) doboot();
return;
}
void autoload_modules()
{
DEBUG("autoload modules starting");
char line[200], cmd[200], module[200];
int fd[2], rc;
FILE *f;
int pid;
if (pipe(fd) <0)
{ perror("Can't create pipe"); return; }
if ( (pid = fork()) == 0 ) {
dup2(fd[1],1); close(fd[0]); close(fd[1]);
execlp("gawk", "gawk", "-f", "/bin/hwscan", NULL);
printf("Can't start >>hwscan<< program with gawk!\n");
exit(1);
}
close(fd[1]);
f = fdopen(fd[0], "r");
while ( fgets(line, 200, f) != NULL ) {
if ( sscanf(line, "%s %s", cmd, module) < 2 ) continue;
if ( !strcmp(cmd, "modprobe") || !strcmp(cmd, "insmod") ) {
printf("%s %s\n", cmd, module);
if ( (rc = fork()) == 0 ) {
execlp(cmd, cmd, module, NULL);
perror("Cant run modprobe/insmod");
exit(1);
}
trywait(rc);
}
}
fclose(f);
trywait(pid);
}
void exec_sh()
{
int rc;
printf ("Quit the shell to return to the stage 1 loader!\n");
if ( (rc = fork()) == 0 ) {
execl("/bin/kiss", "kiss", "-E", NULL);
perror("kiss");
_exit(1);
}
trywait(rc);
}
int main(int argc, char** argv)
{
int args;
if(getenv("stage2init") != NULL)
snprintf(init2, 31, "%s", getenv("stage2init"));
if (argc > 1) {
for (args=1; args<argc; args++) {
if (strstr(argv[args],"linuxrc_debug") != NULL)
do_debug = 1;
}
}
if ( mount("devfs", "/dev", "devfs", 0, NULL) && errno != EBUSY )
perror("Can't mount /dev");
if ( mount("sysfs", "/sys", "sysfs", 0, NULL) && errno != EBUSY )
perror("Can't mount /sys (not fatal)");
if ( mount("proc", "/proc", "proc", 0, NULL) && errno != EBUSY )
perror("Can't mount /proc");
if ( mount("devpts", "/dev/pts", "devpts", 0, NULL) && errno != EBUSY )
perror("Can't mount /dev/pts (not too fatal)");
if ( mount("tmpfs", "/dev/shm", "tmpfs", 0, NULL) && errno != EBUSY )
perror("Can't mount /dev/shm (not fatal)");
/* Only print important stuff to console */
if(do_debug == 0)
klogctl(8, NULL, 3);
else
klogctl(8, NULL, 7);
mod_load_info(mod_loader, mod_dir, mod_suffix);
mod_suffix_len = strlen(mod_suffix);
autoload_modules();
printf("\n\
============================================\n\
=== ROCK Linux 1st stage boot system ===\n\
============================================\n\
\n\
The ROCK Linux live CD system boots up in two stages. You are now in\n\
the first of these two stages and if everything goes right you will not\n\
spend much time here. I will just try to load some drivers (if needed)\n\
so the 2nd stage boot system can be loaded.\n");
DEBUG("load_ramdisk_file starting...");
load_ramdisk_file();
DEBUG("load_ramdisk_file returned. bad. bad bad bad :((");
sleep(1);
printf("\n\nYou are still here. that means i couldn't complete the automatic boot of\n");
printf("stage2. Please refer to the errors reported above, you will now be dumped into a\n");
printf("minimalistic static shell so you can have a look at what went wrong...\n");
if(access("/bin/kiss",R_OK) == 0) execl("/bin/kiss", "/bin/kiss", NULL);
printf("\nCan't start a shell!!\n\nPlease send a bug report with your configuration to fake@rocklinux.org\n\n");
return 0;
}

+ 498
- 0
target/livecd/linuxrc.sh

@ -0,0 +1,498 @@
#!/bin/bash
STAGE_2_BIG_IMAGE="2nd_stage.img.z"
#640kB, err, 64 MB should be enought for the tmpfs ;-)
TMPFS_OPTIONS="size=67108864"
mod_load_info () { # {{{
read os host version rest < <( uname -a )
if [ -z "${os}" ] ; then
echo "Can't run \`uname -a\`"
return
elif [ "${os}" != "Linux" ] ; then
echo "Your operating system is not supported ?!"
return
fi
mod_loader="/sbin/insmod"
mod_dir="/lib/modules/"
# kernel module suffix for <= 2.4 is .o, .ko if above
if [ ${version:2:1} -gt 4 ] ; then
mod_suffix=".ko"
mod_suffix_len=3
else
mod_suffix=".o"
mod_suffix_len=2
fi
} # }}}
doboot() { # {{{
echo "doboot starting - trying to exec /sbin/init"
exec /sbin/init
} # }}}
trymount() { # {{{
source=${1}
target=${2}
mount -t iso9600 -o ro ${source} ${target} && return 0
mount -t ext3 -o ro ${source} ${target} && return 0
mount -t ext2 -o ro ${source} ${target} && return 0
mount -t minix -o ro ${source} ${target} && return 0
mount -t vfat -o ro ${source} ${target} && return 0
return -1
} # }}}
httpload() { # {{{
echo -n "Enter base URL (e.g. http://1.2.3.4/rock): "
read baseurl
[ -z "${baseurl}" ] && return
cat <<EOF
Select a stage 2 image file:
0. ${STAGE_2_BIG_IMAGE}
1. ${STAGE_2_SMALL_IMAGE}
EOF
echo -n "Enter number or image file name (default=0): "
read filename
if [ -z "${filename}" ] ; then
filename="${STAGE_2_BIG_IMAGE}"
elif [ "${filename}" == "0" ] ; then
filename=${STAGE_2_BIG_IMAGE}
elif [ "${filename}" == "1" ] ; then
filename="${STAGE_2_SMALL_IMAGE}"
fi
url="${baseurl%/}/${filename}"
echo "[ ${url} ]"
export ROCK_INSTALL_SOURCE_URL=${baseurl}
exit_linuxrc=1;
if ! mkdir /mnt_root ; then
echo "Can't create /mnt_root"
exit_linuxrc=0
fi
if ! mount -t tmpfs -O ${TMPFS_OPTIONS} none /mnt_root ; then
echo "Can't mount /mnt_root"
exit_linuxrc=0
fi
wget -O - ${url} | tar ${STAGE_2_COMPRESS_ARG} -C /mnt_root -xf -
echo "finished ... now booting 2nd stage"
doboot
} # }}}
load_modules() { # {{{
# this starts the module loading shell
directory=${1}
cat <<EOF
module loading shell
you can navigate through the filestem with 'cd'. for loading a module
simply enter the shown name, to exit press enter on a blank line.
EOF
cd ${directory}
while : ; do
echo "Directories:"
count=0
while read inode ; do
[ -d "${inode}" ] || continue
echo -n " [ ${inode} ]"
count=$((${count}+1))
if [ ${count} -gt 3 ] ; then
echo
count=0
fi
done < <( ls ) | expand -t1,3,19,21,23,39,41,43,59,61,63,78
echo
echo "Modules:"
count=0
while read inode ; do
[ -f "${inode}" ] || continue
[ "${inode%${mod_suffix}}" == "${inode}" ] && continue
echo -n " [ ${inode%${mod_suffix}} ]"
count=$((${count}+1))
if [ ${count} -gt 3 ] ; then
echo
count=0
fi
done < <( ls ) | expand -t1,3,19,21,23,39,41,43,59,61,63,78
echo
echo -n "[${PWD##*/} ] > "
read cmd par
if [ "${cmd}" == "cd" ] ; then
cd ${par}
elif [ -f "${cmd}${mod_suffix}" ] ; then
insmod ${PWD%/}/${cmd}${mod_suffix} ${par}
elif [ -z "${cmd}" ] ; then
break
else
echo "No such module: ${cmd}"
fi
done
return
} # }}}
getdevice () { # {{{
while : ; do
echo -en "\nDevice file to use (q to return) : ";
read device;
[ "${device}" == "q" ] && return -1;
if [ ! -e "${device}" ] ; then
echo -e "\nNot a valid device!"
else
devicefile=${device}
return 0;
fi
done
} # }}}
getcdromdevice () { # {{{
cdroms="${1}"
floppies="${2}"
autoboot="${3}"
devicelists="/dev/cdroms/* /dev/hd[a-d] /dev/floppy/*"
[ "${cdroms}" == "0" -a "${floppies}" == "0" ] && return -1
devnr=0
for dev in ${devicelists} ; do
[ -e "${dev}" ] || continue
[[ ${dev} = /dev/cdroms* ]] && [ "${cdroms}" == "0" ] && continue
[[ ${dev} = /dev/floppy* ]] && [ "${floppies}" == "0" ] && continue
eval "device_${devnr}='${dev}'"
devnr=$((${devnr}+1))
done
[ ${devnr} -eq 0 ] && return -1
x=0
floppy=1
cdrom=1
while [ ${x} -lt ${devnr} ] ; do
eval "device=\${device_${x}}"
if [[ ${device} = /dev/cdrom* ]] ; then
echo " ${x}. CD-ROM #${cdrom} (IDE/ATAPI or SCSI)"
cdrom=$((${cdrom}+1))
fi
if [[ ${device} = /dev/floppy* ]] ; then
echo " ${x}. FDD (Floppy Disk Drive) #${floppy}"
floppy=$((${floppy}+1))
fi
if [[ ${device} = /dev/hd[a-d] ]] ; then
echo " ${x}. IDE Drive #${x}"
floppy=$((${floppy}+1))
fi
x=$((${x}+1))
done
echo -en "\nEnter number or device file name (default=0): "
if [ ${autoboot} -eq 1 ] ; then
echo "0"
text=0
else
read text
fi
[ -z "${text}" ] && text=0
while : ; do
if [ -e "${text}" ] ; then
devicefile="${text}"
return 0
fi
eval "text=\"\${device_${text}}\""
if [ -n "${text}" ] ; then
devicefile="${text}"
return 0
fi
echo -n "No such device found. Try again (enter=back): "
read text
[ -z "${text}" ] && return -1
done
return 1;
} # }}}
prepare_root () {
local ret=0 F
echo "preparing /dev"
cd /dev || ret=1
rm -rf fd
ln -svf /proc/kcore core || ret=1
ln -svf /proc/self/fd fd || ret=1
ln -svf fd/0 stdin || ret=1
ln -svf fd/1 stdout || ret=1
ln -svf fd/2 stderr || ret=1
cd / || ret=1
ln -svf /mnt/cowfs_ro/* /mnt/cowfs_rw-new/
rm -rf /mnt/cowfs_rw-new/{home,tmp}
mkdir -p /mnt/cowfs_rw-new/{home,tmp}
mkdir -p /mnt/cowfs_rw-new/home/{rocker,root}
chmod 755 /mnt/cowfs_rw-new/home/rocker
chmod 700 /mnt/cowfs_rw-new/home/root
if ! chown 1000:100 /mnt/cowfs_rw-new/home/rocker ; then
echo "could not chown /mnt/cowfs_rw-new/home/rocker to rocker:users"
ret=1
fi
mount --move /mnt/cowfs_rw-new /mnt/cowfs_rw
rm -rf /mnt/cowfs-rw-new
return $ret
}
load_ramdisk_file() { # {{{
local devicetype=${1} autoboot=${2}
echo -en "Select a device for loading the 2nd stage system from: \n\n"
if [ "${devicetype}" == "cdroms" ] ; then
getcdromdevice 1 1 ${autoboot} || return
else
getdevice || return
fi
cat << EOF
Select a stage 2 image file:
1. ${STAGE_2_BIG_IMAGE}
EOF
echo -n "Enter number or image file name (default=1): "
if [ ${autoboot} -eq 1 ] ; then
text=1
else
read text
fi
if [ -z "${text}" -o "${text}" = "1" ] ; then
filename="${STAGE_2_BIG_IMAGE}"
else
filename="${text}"
fi
exit_linuxrc=1
echo "Using ${devicefile}://${filename}."
if ! mkdir -p /mnt/cdrom ; then
echo "Can't create /mnt/cdrom"
exit_linuxrc=0
fi
if ! mount ${devicefile} "/mnt/cdrom" -o ro ; then
echo "Can't mount /mnt/cdrom"
exit_linuxrc=0
fi
if ! losetup /dev/loop/0 "/mnt/cdrom/${filename}" ; then
echo "Can't losetup /mnt/cdrom/${filename}"
exit_linuxrc=0
fi
# mkdir -p /mnt/cowfs_r{o,w}
if ! mount -t squashfs /dev/loop/0 /mnt/cowfs_ro -o ro ; then
echo "Can't mount squashfs on /mnt/cowfs_ro"
exit_linuxrc=0
fi
if ! mkdir -p /mnt/cowfs_rw-new ; then
echo "Can't mkdir -p /mnt/cowfs_rw-new"
exit_linuxrc=0
fi
if ! mount -t tmpfs -o ${TMPFS_OPTIONS} tmpfs /mnt/cowfs_rw-new ; then
echo "Can't mount tmpfs on /mnt/cowfs_rw-new"
exit_linuxrc=0
fi
export ROCK_INSTALL_SOURCE_DEV=${devicefile}
export ROCK_INSTALL_SOURCE_FILE=${filename}
if prepare_root ; then
rm -rf /mnt/cowfs_rw-new
doboot
fi
} # }}}
activate_swap() { # {{{
echo
echo -n "Enter file name of swap device: "
read text
if [ -n "${text}" ] ; then
swapon ${text}
fi
} # }}}
config_net() { # {{{
ip addr
echo
ip route
echo
echo -n "Enter interface name (eth0): "
read dv
[ -z "${dv}" ] && dv="eth0"
echo -n "Enter ip (192.168.0.254/24): "
read ip
[ -z "${ip}" ] && ip="192.168.0.254/24"
ip addr add ${ip} dev ${dv}
ip link set ${dv} up
echo -n "Enter default gateway (none): "
read gw
[ -n "${gw}" ] && ip route add default via ${gw}
ip addr
echo
ip route
echo
} # }}}
autoload_modules () { # {{{
while read cmd mod rest ; do
[ -n "${rest}" ] && continue
[ -z "${cmd}" ] && continue
if [ "${cmd}" == "modprobe" -o "${cmd}" == "insmod" ] ; then
echo "${cmd} ${mod}"
${cmd} ${mod} 2>&1 >/dev/null
fi
done < <( /bin/gawk -f /sbin/hwscan )
} # }}}
exec_sh() { # {{{
echo "Quit the shell to return to the stage 1 loader!"
/bin/sh
} # }}}
checkisomd5() { # {{{
echo "Select a device for checking: "
getcdromdevice 1 0 0 || return
echo "Running check..."
/bin/checkisomd5 ${devicefile}
echo "done"
echo "Press Return key to continue."
read
} # }}}
input=1
exit_linuxrc=0
[ -z "${autoboot}" ] && autoboot=0
mount -t tmpfs tmpfs /dev || echo "Can't mount a tmpfs on /dev"
mount -t sysfs sysfs /sys || echo "Can't mount sysfs on /sys"
mount -t proc proc /proc || echo "Can't mount /proc"
mount -t tmpfs -o ${TMPFS_OPTIONS} tmpfs /tmp || echo "Can't mount /tmpfs"
cd /dev
rm -rf fd
ln -s /proc/self/fd
cd -
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH"
echo "" > /proc/sys/kernel/hotplug
/sbin/udevd --daemon
# create nodes for devices already in kernel
while read uevent; do
echo 1 > $uevent
done < <( find /sys -name uevent )
udevwait=0
while [ -d /dev/.udev/queue -a $udevwait -lt 300 ] ; do
sleep 1
(( udevwait++ ))
done
mod_load_info
autoload_modules
# some devices (scsi...) need time to settle...
echo "Waiting for devices to settle..."
sleep 5
ip addr add 127.0.0.1 dev lo
ip link set lo up
if [ ${autoboot} -eq 1 ] ; then
load_ramdisk_file cdroms 1
fi
autoboot=0
cat << EOF
============================================
=== ROCK Linux 1st stage boot system ===
============================================
The ROCK Linux install / rescue system boots up in two stages. You
are now in the first of this two stages and if everything goes right
you will not spend much time here. Just load your SCSI and networking
drivers (if needed) and configure the installation source so the
2nd stage boot system can be loaded and you can start the installation.
EOF
while [ ${exit_linuxrc} -eq 0 ] ; do
cat <<EOF
0. Load 2nd stage system from cdrom or floppy drive
1. Load 2nd stage system from any device
2. Load 2nd stage system from network
3. Configure network interfaces (IPv4 only)
4. Load kernel modules from this disk
5. Load kernel modules from another disk
6. Activate already formatted swap device
7. Execute a shell (for experts!)
8. Validate a CD/DVD against its embedded checksum
EOF
echo -n "What do you want to do [0-7] (default=0)? "
read text
[ -z "${text}" ] && text=0
input=${text//[^0-9]/}
case "${input}" in
0)
load_ramdisk_file cdroms 0
;;
1)
load_ramdisk_file any 0
;;
2)
httpload
;;
3)
config_net
;;
4)
load_modules "${mod_dir}"
;;
5)
mkdir "/mnt_floppy" || echo "Can't create /mnt_floppy"
trymount "/dev/floppy/0" "/mnt_floppy" && load_modules "/mnt_floppy"
umount "/mnt_floppy" || echo "Can't umount /mnt_floppy"
rmdir "/mnt_floppy" || echo "Can't remove /mnt_floppy"
;;
6)
activate_swap
;;
7)
exec_sh
;;
8)
checkisomd5
;;
*)
echo "No such option present!"
esac
done
exec /linuxrc
echo "Can't start /linuxrc!! Life sucks.\n\n"

Loading…
Cancel
Save