summaryrefslogtreecommitdiffstats
path: root/loader/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader/init.c')
-rw-r--r--loader/init.c832
1 files changed, 0 insertions, 832 deletions
diff --git a/loader/init.c b/loader/init.c
deleted file mode 100644
index 8eaed3af2..000000000
--- a/loader/init.c
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * init.c
- *
- * This is the install type init
- *
- * Erik Troan (ewt@redhat.com)
- *
- * Copyright 1996 - 2002 Red Hat Software
- *
- * This software may be freely redistributed under the terms of the GNU
- * public license.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#if USE_MINILIBC
-#include "minilibc.h"
-#ifndef SOCK_STREAM
-# define SOCK_STREAM 1
-#endif
-#else
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/klog.h>
-#include <sys/mount.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/reboot.h>
-#include <termios.h>
-
-/* Need to tell loop.h what the actual dev_t type is. */
-#undef dev_t
-#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__))
-#define dev_t unsigned int
-#else
-#define dev_t unsigned short
-#endif
-#include <linux/loop.h>
-#undef dev_t
-#define dev_t dev_t
-
-#define syslog klogctl
-#endif
-
-struct unmountInfo {
- char * name;
- int mounted;
- int loopDevice;
- enum { FS, LOOP } what;
-} ;
-
-#include <linux/cdrom.h>
-
-#define KICK_FLOPPY 1
-#define KICK_BOOTP 2
-
-#define MS_REMOUNT 32
-
-#define ENV_PATH 0
-#define ENV_LD_LIBRARY_PATH 1
-#define ENV_HOME 2
-#define ENV_TERM 3
-#define ENV_DEBUG 4
-
-char * env[] = {
- "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:"
- "/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin",
- /* we set a nicer ld library path specifically for bash -- a full
- one makes anaconda unhappy */
- "LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib",
- "HOME=/",
- "TERM=linux",
- "DEBUG=",
- "TERMINFO=/etc/linux-terminfo",
- "PYTHONPATH=/tmp/updates",
- NULL
-};
-
-
-/*
- * this needs to handle the following cases:
- *
- * 1) run from a CD root filesystem
- * 2) run from a read only nfs rooted filesystem
- * 3) run from a floppy
- * 4) run from a floppy that's been loaded into a ramdisk
- *
- */
-
-int testing=0;
-
-void printstr(char * string) {
- write(1, string, strlen(string));
-}
-
-void fatal_error(int usePerror) {
-/* FIXME */
-#if 0
- if (usePerror)
- perror("failed:");
- else
-#endif
- printf("failed.\n");
-
- printf("\nI can't recover from this.\n");
- if (testing) exit(0);
-#if !defined(__s390__) && !defined(__s390x__)
- while (1) ;
-#endif
-}
-
-int doMke2fs(char * device, char * size) {
- char * args[] = { "/usr/sbin/mke2fs", NULL, NULL, NULL };
- int pid, status;
-
- args[1] = device;
- args[2] = size;
-
- if (!(pid = fork())) {
- /* child */
- execve("/usr/sbin/mke2fs", args, env);
- fatal_error(1);
- }
-
- wait4(-1, &status, 0, NULL);
-
- return 0;
-}
-
-int hasNetConfiged(void) {
- int rc;
- int s;
- struct ifconf configs;
- struct ifreq devs[10];
-
- #ifdef __i386__
- return 0;
- #endif
-
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- /* FIXME was perror*/
- printf("error creating socket: %d\n", errno);
- return 0;
- } else {
- /* this is just good enough to tell us if we have anything
- configured */
- configs.ifc_len = sizeof(devs);
- configs.ifc_buf = (void *) devs;
-
- rc = ioctl(s, SIOCGIFCONF, &configs);
- if (rc < 0) {
- /* FIXME was perror*/
- printstr("SIOCGIFCONF");
- return 0;
- }
- if (configs.ifc_len == 0) {
- return 0;
- }
-
- return 1;
- }
-
- return 0;
-}
-
-void doklog(char * fn) {
- fd_set readset, unixs;
- int in, out, i;
- int log;
- int s;
- int sock = -1;
- struct sockaddr_un sockaddr;
- char buf[1024];
- int readfd;
-
- in = open("/proc/kmsg", O_RDONLY,0);
- if (in < 0) {
- /* FIXME: was perror */
- printstr("open /proc/kmsg");
- return;
- }
-
- out = open(fn, O_WRONLY, 0);
- if (out < 0)
- printf("couldn't open %s for syslog -- still using /tmp/syslog\n", fn);
-
- log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644);
- if (log < 0) {
- /* FIXME: was perror */
- printstr("error opening /tmp/syslog");
- sleep(5);
-
- close(in);
- return;
- }
-
- /* if we get this far, we should be in good shape */
-
- if (fork()) {
- /* parent */
- close(in);
- close(out);
- close(log);
- return;
- }
- close(0);
- close(1);
- close(2);
-
- dup2(1, log);
-
-#if defined(USE_LOGDEV)
- /* now open the syslog socket */
- sockaddr.sun_family = AF_UNIX;
- strcpy(sockaddr.sun_path, "/dev/log");
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
- printf("error creating socket: %d\n", errno);
- sleep(5);
- }
- printstr("got socket\n");
- if (bind(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr.sun_family) +
- strlen(sockaddr.sun_path))) {
- printf("bind error: %d\n", errno);
- sleep(5);
- }
- printstr("bound socket\n");
- chmod("/dev/log", 0666);
- if (listen(sock, 5)) {
- printf("listen error: %d\n", errno);
- sleep(5);
- }
-#endif
-
- syslog(8, NULL, 1);
-
- FD_ZERO(&unixs);
- while (1) {
- memcpy(&readset, &unixs, sizeof(unixs));
-
- if (sock >= 0) FD_SET(sock, &readset);
- FD_SET(in, &readset);
-
- i = select(20, &readset, NULL, NULL, NULL);
- if (i <= 0) continue;
-
- if (FD_ISSET(in, &readset)) {
- i = read(in, buf, sizeof(buf));
- if (i > 0) {
- if (out >= 0) write(out, buf, i);
- write(log, buf, i);
- }
- }
-
- for (readfd = 0; readfd < 20; ++readfd) {
- if (FD_ISSET(readfd, &readset) && FD_ISSET(readfd, &unixs)) {
- i = read(readfd, buf, sizeof(buf));
- if (i > 0) {
- if (out >= 0) {
- write(out, buf, i);
- write(out, "\n", 1);
- }
-
- write(log, buf, i);
- write(log, "\n", 1);
- } else if (i == 0) {
- /* socket closed */
- close(readfd);
- FD_CLR(readfd, &unixs);
- }
- }
- }
-
- if (sock >= 0 && FD_ISSET(sock, &readset)) {
- s = sizeof(sockaddr);
- readfd = accept(sock, (struct sockaddr *) &sockaddr, &s);
- if (readfd < 0) {
- if (out >= 0) write(out, "error in accept\n", 16);
- write(log, "error in accept\n", 16);
- close(sock);
- sock = -1;
- } else {
- FD_SET(readfd, &unixs);
- }
- }
- }
-}
-
-int setupTerminal(int fd) {
- struct winsize winsize;
-
- if (ioctl(fd, TIOCGWINSZ, &winsize)) {
- printf("failed to get winsize");
- fatal_error(1);
- }
-
- winsize.ws_row = 24;
- winsize.ws_col = 80;
-
- if (ioctl(fd, TIOCSWINSZ, &winsize)) {
- printf("failed to set winsize");
- fatal_error(1);
- }
-
- env[ENV_TERM] = "TERM=vt100";
-
- return 0;
-}
-
-void undoLoop(struct unmountInfo * fs, int numFs, int this);
-
-void undoMount(struct unmountInfo * fs, int numFs, int this) {
- int len = strlen(fs[this].name);
- int i;
-
- if (!fs[this].mounted) return;
- fs[this].mounted = 0;
-
- /* unmount everything underneath this */
- for (i = 0; i < numFs; i++) {
- if (fs[i].name[len] == '/' &&
- !strncmp(fs[this].name, fs[i].name, len)) {
- if (fs[i].what == LOOP)
- undoLoop(fs, numFs, i);
- else
- undoMount(fs, numFs, i);
- }
- }
-
- printf("\t%s", fs[this].name);
- /* don't need to unmount /tmp. it is busy anyway. */
- if (!testing) {
- if (umount2(fs[this].name, 0) < 0) {
- printf(" umount failed (%d)", errno);
- } else {
- printf(" done");
- }
- }
- printf("\n");
-}
-
-void undoLoop(struct unmountInfo * fs, int numFs, int this) {
- int i;
- int fd;
-
- if (!fs[this].mounted) return;
- fs[this].mounted = 0;
-
- /* find the device mount */
- for (i = 0; i < numFs; i++) {
- if (fs[i].what == FS && (fs[i].loopDevice == fs[this].loopDevice))
- break;
- }
-
- if (i < numFs) {
- /* the device is mounted, unmount it (and recursively, anything
- * underneath) */
- undoMount(fs, numFs, i);
- }
-
- unlink("/tmp/loop");
- mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | fs[this].loopDevice);
- printf("\tdisabling /dev/loop%d", fs[this].loopDevice);
- if ((fd = open("/tmp/loop", O_RDONLY, 0)) < 0) {
- printf(" failed to open device: %d", errno);
- } else {
- if (!testing && ioctl(fd, LOOP_CLR_FD, 0))
- printf(" LOOP_CLR_FD failed: %d", errno);
- close(fd);
- }
-
- printf("\n");
-}
-
-void unmountFilesystems(void) {
- int fd, size;
- char buf[65535]; /* this should be big enough */
- char * chptr, * start;
- struct unmountInfo filesystems[500];
- int numFilesystems = 0;
- int i;
- struct loop_info li;
- char * device;
- struct stat sb;
-
- fd = open("/proc/mounts", O_RDONLY, 0);
- if (fd < 1) {
- /* FIXME: was perror */
- printstr("failed to open /proc/mounts");
- sleep(2);
- return;
- }
-
- size = read(fd, buf, sizeof(buf) - 1);
- buf[size] = '\0';
-
- close(fd);
-
- chptr = buf;
- while (*chptr) {
- device = chptr;
- while (*chptr != ' ') chptr++;
- *chptr++ = '\0';
- start = chptr;
- while (*chptr != ' ') chptr++;
- *chptr++ = '\0';
-
- if (strcmp(start, "/") && strcmp(start, "/tmp")) {
- filesystems[numFilesystems].name = alloca(strlen(start) + 1);
- strcpy(filesystems[numFilesystems].name, start);
- filesystems[numFilesystems].what = FS;
- filesystems[numFilesystems].mounted = 1;
-
- stat(start, &sb);
- if ((sb.st_dev >> 8) == 7) {
- filesystems[numFilesystems].loopDevice = sb.st_dev & 0xf;
- } else {
- filesystems[numFilesystems].loopDevice = -1;
- }
-
- numFilesystems++;
- }
-
- while (*chptr != '\n') chptr++;
- chptr++;
- }
-
- for (i = 0; i < 7; i++) {
- unlink("/tmp/loop");
- mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | i);
- if ((fd = open("/tmp/loop", O_RDONLY, 0)) >= 0) {
- if (!ioctl(fd, LOOP_GET_STATUS, &li) && li.lo_name[0]) {
- filesystems[numFilesystems].name = alloca(strlen(li.lo_name)
- + 1);
- strcpy(filesystems[numFilesystems].name, li.lo_name);
- filesystems[numFilesystems].what = LOOP;
- filesystems[numFilesystems].mounted = 1;
- filesystems[numFilesystems].loopDevice = i;
- numFilesystems++;
- }
-
- close(fd);
- }
- }
-
- for (i = 0; i < numFilesystems; i++) {
- if (filesystems[i].what == LOOP) {
- undoLoop(filesystems, numFilesystems, i);
- }
- }
-
- for (i = 0; i < numFilesystems; i++) {
- if (filesystems[i].mounted) {
- undoMount(filesystems, numFilesystems, i);
- }
- }
-}
-
-void disableSwap(void) {
- int fd;
- char buf[4096];
- int i;
- char * start;
- char * chptr;
-
- if ((fd = open("/proc/swaps", O_RDONLY, 0)) < 0) return;
-
- i = read(fd, buf, sizeof(buf) - 1);
- close(fd);
- if (i < 0) return;
- buf[i] = '\0';
-
- start = buf;
- while (*start) {
- while (*start != '\n' && *start) start++;
- if (!*start) return;
-
- start++;
- if (*start != '/') return;
- chptr = start;
- while (*chptr && *chptr != ' ') chptr++;
- if (!(*chptr)) return;
- *chptr = '\0';
- printf("\t%s", start);
- if (swapoff(start))
- printf(" failed (%d)", errno);
- printf("\n");
-
- start = chptr + 1;
- }
-}
-
-void ejectCdrom(void) {
- int ejectfd;
- struct stat sb;
-
- stat("/tmp/cdrom", &sb);
-
- if ((sb.st_mode & S_IFBLK) == S_IFBLK) {
- printf("ejecting /tmp/cdrom...");
- if ((ejectfd = open("/tmp/cdrom", O_RDONLY | O_NONBLOCK, 0)) >= 0) {
- if (ioctl(ejectfd, CDROMEJECT, 0))
- printf("eject failed %d ", errno);
- close(ejectfd);
- } else {
- printf("eject failed %d ", errno);
- }
- printf("\n");
- }
-}
-
-int mystrstr(char *str1, char *str2) {
- char *p;
- int rc=0;
-
- for (p=str1; *p; p++) {
- if (*p == *str2) {
- char *s, *t;
-
- rc = 1;
- for (s=p, t=str2; *s && *t; s++, t++)
- if (*s != *t) {
- rc = 0;
- p++;
- }
-
- if (rc)
- return rc;
- }
- }
- return rc;
-}
-
-
-
-int main(int argc, char **argv) {
- pid_t installpid, childpid;
- int waitStatus;
- int fd;
- int nfsRoot = 0;
- int roRoot = 0;
- int cdRoot = 0;
- int doReboot = 0;
- int doShutdown =0;
- int isSerial = 0;
- int noKill = 0;
-#ifdef __alpha__
- char * kernel;
-#endif
- char * argvc[15];
- char ** argvp = argvc;
- char twelve = 12;
- int i;
- char buf[500];
- int len;
-
-
-#if !defined(__s390__) && !defined(__s390x__)
- testing = (getppid() != 0) && (getppid() != 1);
-#endif
-
- if (!testing) {
- /* turn off screen blanking */
- printstr("\033[9;0]");
- printstr("\033[8]");
- } else {
- printstr("(running in test mode).\n");
- }
-
-#if 0
- printf("unmounting filesystems...\n");
- unmountFilesystems();
- exit(0);
-#endif
-
- umask(022);
-
- printstr("Greetings.\n");
-
- printf("Red Hat install init version %s starting\n", VERSION);
-
- printf("mounting /proc filesystem... ");
- if (!testing) {
- if (mount("/proc", "/proc", "proc", 0, NULL))
- fatal_error(1);
- }
- printf("done\n");
-
- printf("mounting /dev/pts (unix98 pty) filesystem... ");
- if (!testing) {
- if (mount("/dev/pts", "/dev/pts", "devpts", 0, NULL))
- fatal_error(1);
- }
- printf("done\n");
-
- signal(SIGINT, SIG_IGN);
- signal(SIGTSTP, SIG_IGN);
-
- /* these args are only for testing from commandline */
- for (i = 1; i < argc; i++)
- if (!strcmp (argv[i], "serial")) {
- isSerial = 1;
- break;
- }
-
- /* look through /proc/cmdline for special options */
- if ((fd = open("/proc/cmdline", O_RDONLY,0)) > 0) {
- len = read(fd, buf, sizeof(buf) - 1);
- close(fd);
- if (len > 0 && mystrstr(buf, "nokill"))
- noKill = 1;
- }
-
-#if !defined(__s390__) && !defined(__s390x__)
- if (ioctl (0, TIOCLINUX, &twelve) < 0)
- isSerial = 2;
-
- if (isSerial) {
- char *device = "/dev/ttyS0";
-
- printf("Red Hat install init version %s using a serial console\n",
- VERSION);
-
- printf("remember, cereal is an important part of a nutritionally "
- "balanced breakfast.\n\n");
-
- if (isSerial == 2)
- device = "/dev/console";
- fd = open(device, O_RDWR, 0);
- if (fd < 0)
- device = "/dev/tts/0";
-
- if (fd < 0) {
- printf("failed to open %s\n", device);
- fatal_error(1);
- }
-
- setupTerminal(fd);
- } else {
- fd = open("/dev/tty1", O_RDWR, 0);
- if (fd < 0)
- fd = open("/dev/vc/1", O_RDWR, 0);
-
- if (fd < 0) {
- printf("failed to open /dev/tty1 and /dev/vc/1");
- fatal_error(1);
- }
- }
-
- if (testing)
- exit(0);
-
- dup2(fd, 0);
- dup2(fd, 1);
- dup2(fd, 2);
- close(fd);
-#endif
-
- setsid();
- if (ioctl(0, TIOCSCTTY, NULL)) {
- printf("could not set new controlling tty\n");
- }
-
- if (!testing) {
- sethostname("localhost.localdomain", 21);
- /* the default domainname (as of 2.0.35) is "(none)", which confuses
- glibc */
- setdomainname("", 0);
- }
-
- printf("checking for NFS root filesystem...");
- if (hasNetConfiged()) {
- printf("yes\n");
- roRoot = nfsRoot = 1;
- } else {
- printf("no\n");
- }
-
- if (!nfsRoot) {
- printf("trying to remount root filesystem read write... ");
- if (mount("/", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, NULL)) {
- printf("failed (but that's okay)\n");
-
- roRoot = 1;
- } else {
- printf("done\n");
-
- /* 2.0.18 (at least) lets us remount a CD r/w!! */
- printf("checking for writeable /tmp... ");
- fd = open("/tmp/tmp", O_WRONLY | O_CREAT, 0644);
- if (fd < 0) {
- printf("no (probably a CD rooted install)\n");
- roRoot = 1;
- } else {
- close(fd);
- unlink("/tmp/tmp");
- printf("yes\n");
- }
- }
- }
-
-#if !defined(__s390__) && !defined(__s390x__)
-#define RAMDISK_DEVICE "/dev/ram"
-#else
-#define RAMDISK_DEVICE "/dev/ram2"
-#endif
-
- if (!testing && roRoot) {
- printf("creating 300k of ramdisk space... ");
- if (doMke2fs(RAMDISK_DEVICE, "300"))
- fatal_error(0);
-
- printf("done\n");
-
- printf("mounting /tmp from ramdisk... ");
- if (mount(RAMDISK_DEVICE, "/tmp", "ext2", 0, NULL))
- fatal_error(1);
-
- printf("done\n");
-
- if (!nfsRoot) cdRoot = 1;
- }
-
- /* Now we have some /tmp space set up, and /etc and /dev point to
- it. We should be in pretty good shape. */
-
- if (!testing)
- doklog("/dev/tty4");
-
- /* Go into normal init mode - keep going, and then do a orderly shutdown
- when:
-
- 1) /bin/install exits
- 2) we receive a SIGHUP
- */
-
- printf("running install...\n");
-
- setsid();
-
- if (!(installpid = fork())) {
- /* child */
- *argvp++ = "/sbin/loader";
- *argvp++ = NULL;
-
- printf("running %s\n", argvc[0]);
- execve(argvc[0], argvc, env);
-
- exit(0);
- }
-
- while (!doShutdown) {
- childpid = wait4(-1, &waitStatus, 0, NULL);
-
- if (childpid == installpid)
- doShutdown = 1;
- }
-
- if (!WIFEXITED(waitStatus) || WEXITSTATUS(waitStatus)) {
- printf("install exited abnormally ");
- if (WIFSIGNALED(waitStatus)) {
- printf("-- received signal %d", WTERMSIG(waitStatus));
- }
- printf("\n");
- } else {
- doReboot = 1;
- }
-
- if (testing)
- exit(0);
-
- sync(); sync();
-
- if (!testing && !noKill) {
- printf("sending termination signals...");
- kill(-1, 15);
- sleep(2);
- printf("done\n");
-
- printf("sending kill signals...");
- kill(-1, 9);
- sleep(2);
- printf("done\n");
- }
-
- printf("disabling swap...\n");
- disableSwap();
-
- printf("unmounting filesystems...\n");
- unmountFilesystems();
-
- ejectCdrom();
-
- if (doReboot) {
- printf("rebooting system\n");
- sleep(2);
-
-#if USE_MINILIBC
- reboot(0xfee1dead, 672274793, 0x1234567);
-#else
-# ifdef __alpha__
- reboot(RB_HALT_SYSTEM);
-# else
- reboot(RB_AUTOBOOT);
-# endif
-#endif
- } else {
- printf("you may safely reboot your system\n");
- while (1);
- }
-
- exit(0);
-
- return 0;
-}