@ -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; |
|||
} |
|||
|
@ -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" |