summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--loader2/Makefile2
-rw-r--r--loader2/cdinstall.c4
-rw-r--r--loader2/cdinstall.h5
-rw-r--r--loader2/hdinstall.c413
-rw-r--r--loader2/hdinstall.h10
-rw-r--r--loader2/loader.c18
-rw-r--r--loader2/method.c2
7 files changed, 438 insertions, 16 deletions
diff --git a/loader2/Makefile b/loader2/Makefile
index 116d46b5f..5655c5f48 100644
--- a/loader2/Makefile
+++ b/loader2/Makefile
@@ -20,7 +20,7 @@ MODULELINKAGE :=-lmodutils -lmodutilutil -lmodutilobj
BINS = init
HWOBJS = pcmcia.o usb.o firewire.o
-METHOBJS = method.o cdinstall.o nfsinstall.o urlinstall.o
+METHOBJS = method.o cdinstall.o hdinstall.o nfsinstall.o urlinstall.o
OBJS = log.o moduleinfo.o loadermisc.o modules.o moduledeps.o windows.o \
lang.o kbd.o modules.o modstubs.o driverdisk.o \
md5.o mediacheck.o \
diff --git a/loader2/cdinstall.c b/loader2/cdinstall.c
index 07be5e8ee..5a4b4b0fb 100644
--- a/loader2/cdinstall.c
+++ b/loader2/cdinstall.c
@@ -314,6 +314,10 @@ char * setupCdrom(char * location,
sprintf(buf, "cdrom://%s/mnt/source", kd->known[i].name);
return buf;
}
+
+ /* this wasnt the CD we were looking for, clean up and */
+ /* try the next CD drive */
+ umount("/mnt/source");
unlink("/tmp/cdrom");
}
}
diff --git a/loader2/cdinstall.h b/loader2/cdinstall.h
index ed30be0c8..fe49437d9 100644
--- a/loader2/cdinstall.h
+++ b/loader2/cdinstall.h
@@ -4,6 +4,11 @@
#include "../isys/probe.h"
#include "modules.h"
+char * mountCdromImage(struct installMethod * method,
+ char * location, struct knownDevices * kd,
+ moduleInfoSet modInfo, moduleList modLoaded,
+ moduleDeps * modDepsPtr, int flags);
+
char * findRedHatCD(char * location,
struct knownDevices * kd,
moduleInfoSet modInfo,
diff --git a/loader2/hdinstall.c b/loader2/hdinstall.c
new file mode 100644
index 000000000..b2108b26f
--- /dev/null
+++ b/loader2/hdinstall.c
@@ -0,0 +1,413 @@
+/*
+ * hdinstall.c - code to set up hard drive installs
+ *
+ * Erik Troan <ewt@redhat.com>
+ * Matt Wilson <msw@redhat.com>
+ * Michael Fulbright <msf@redhat.com>
+ * Jeremy Katz <katzj@redhat.com>
+ *
+ * Copyright 1997 - 2002 Red Hat, Inc.
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * General 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.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <unistd.h>
+
+#include "driverdisk.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "log.h"
+#include "lang.h"
+#include "modules.h"
+#include "method.h"
+#include "mediacheck.h"
+
+#include "../isys/probe.h"
+#include "../isys/imount.h"
+#include "../isys/isys.h"
+
+
+/* see if this is a partition name or not */
+int isPartitionName(char *pname) {
+
+ /* if it doesnt start with a alpha its not one */
+ if (!isalpha(*pname))
+ return 0;
+
+ /* if it has a '/' in it then treat it specially */
+ if (strchr(pname, '/')) {
+ /* assume its either a /dev/ida/ or /dev/cciss device */
+ /* these have form of c?d?p? if its a partition */
+ return strchr(pname, 'p') != NULL;
+ } else {
+ /* if it ends with a digit we're ok */
+ return isdigit(pname[strlen(pname)-1]);
+ }
+}
+
+/* return NULL terminated array of pointers to names of partitons in
+ * /proc/partitions
+ */
+static char **getPartitionsList(void) {
+ FILE *f;
+ int numfound = 0;
+ char **rc=NULL;
+
+ f = fopen("/proc/partitions", "r");
+ if (!f) {
+ logMessage("getPartitionsList: could not open /proc/partitions");
+ return NULL;
+ }
+
+ /* read through /proc/partitions and parse out partitions */
+ while (1) {
+ char *tmpptr;
+ char tmpstr[4096];
+
+ tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
+
+ if (tmpptr) {
+ char *a, *b;
+ int toknum = 0;
+
+ a = tmpstr;
+ while (1) {
+ b = strsep(&a, " \n");
+
+ /* if no fields left abort */
+ if (!b)
+ break;
+
+ /* if field was empty means we hit another delimiter */
+ if (!*b)
+ continue;
+
+ /* make sure this is a valid partition line, should start */
+ /* with a numeral */
+ if (toknum == 0) {
+ if (!isdigit(*b))
+ break;
+ } else if (toknum == 2) {
+ /* if size is exactly 1 then ignore it as an extended */
+ if (!strcmp(b, "1"))
+ break;
+ } else if (toknum == 3) {
+ /* this should be the partition name */
+ /* now we need to see if this is the block device or */
+ /* actually a partition name */
+ if (!isPartitionName(b))
+ break;
+
+ /* we found a partition! */
+ if (!rc)
+ rc = (char **) malloc(sizeof(char *));
+ else
+ rc = (char **) realloc(rc, (numfound+1)*sizeof(char *));
+ rc[numfound] = (char *) malloc(strlen(b) + 7);
+ sprintf(rc[numfound], "/dev/%s", b);
+
+ numfound++;
+ break;
+ }
+ toknum++;
+ }
+ } else {
+ break;
+ }
+ }
+
+ fclose(f);
+
+ return rc;
+}
+
+/* returns length of partitionlist */
+int lenPartitionsList(char **list) {
+ char **part;
+ int rc;
+
+ for (rc = 0, part = list; *part; rc++, part++);
+
+ return rc;
+}
+
+/* frees partition list */
+void freePartitionsList(char **list) {
+ char **part;
+
+ if (!list)
+ return;
+
+ for (part = list; *part; part++)
+ if (*part)
+ free(*part);
+
+ free(list);
+}
+
+/* pull in second stage image for hard drive install */
+static int loadHDImages(char * prefix, char * dir, int flags,
+ char * device, char * mntpoint) {
+ int fd, rc;
+ char * path;
+
+ setupRamdisk();
+
+ path = alloca(50 + strlen(prefix) + (dir ? strlen(dir) : 2));
+
+ sprintf(path, "%s/%s/RedHat/base/hdstg1.img", prefix, dir ? dir : "");
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ logMessage("failed to open %s: %s", path, strerror(errno));
+ return 1;
+ }
+
+ /* handle updates.img now before we copy stage2 over... this allows
+ * us to keep our ramdisk size as small as possible */
+ sprintf(path, "%s/%s/RedHat/base/updates.img", prefix, dir ? dir : "");
+ copyUpdatesImg(path);
+
+ rc = copyFileAndLoopbackMount(fd, "/tmp/ramfs/hdstg1.img", flags,
+ device, mntpoint);
+ close(fd);
+
+ return rc;
+}
+
+/* given a partition device and directory, tries to mount hd install image */
+static char * setupIsoImages(char * device, char * dirName, int flags) {
+ int rc;
+ char * url;
+ char filespec[1024];
+ char * path;
+ char *typetry[] = {"ext2", "vfat", NULL};
+ char **type;
+
+ logMessage("mounting device %s for hard drive install %s", device);
+
+ if (!FL_TESTING(flags)) {
+ /* +5 skips over /dev/ */
+ if (devMakeInode(device, "/tmp/hddev"))
+ logMessage("devMakeInode failed!");
+
+ /* XXX try to mount as ext2 and then vfat */
+ for (type=typetry; *type; type++)
+ if (doPwMount("/tmp/hddev", "/tmp/hdimage", *type, 1, 0, NULL, NULL))
+ break;
+
+ if (!type)
+ return NULL;
+
+ sprintf(filespec, "/tmp/hdimage/%s", dirName);
+
+ if ((path = validIsoImages(filespec))) {
+ logMessage("Path to valid iso is %s", path);
+ copyUpdatesImg("/mnt/source/updates.img");
+
+ rc = mountLoopback(path, "/tmp/loopimage", "loop0");
+ if (!rc) {
+ rc = loadHDImages("/tmp/loopimage", "/", flags, "loop1",
+ "/mnt/runtime");
+ if (rc) {
+ newtWinMessage(_("Error"), _("OK"),
+ _("An error occured reading the install "
+ "from the ISO images. Please check your ISO "
+ "images and try again."));
+ } else {
+ queryIsoMediaCheck(path, flags);
+ }
+ }
+ umountLoopback("/tmp/loopimage", "loop0");
+
+ } else {
+ rc = 1;
+ }
+
+ umount("/tmp/hdimage");
+
+ if (rc)
+ return NULL;
+ } else {
+ /* in test mode I dont know what to do - just pretend I guess */
+ type = typetry;
+ }
+
+ url = malloc(50 + strlen(dirName ? dirName : ""));
+ sprintf(url, "hd://%s:%s/%s", device, *type, dirName ? dirName : ".");
+
+ return url;
+}
+
+
+/* setup hard drive based install from a partition with a filesystem and
+ * ISO images on that filesystem
+ */
+char * mountHardDrive(struct installMethod * method,
+ char * location, struct knownDevices * kd,
+ moduleInfoSet modInfo, moduleList modLoaded,
+ moduleDeps * modDepsPtr, int flags) {
+ int rc;
+ int i;
+
+ newtComponent listbox, label, dirEntry, form, okay, back, text;
+ struct newtExitStruct es;
+ newtGrid entryGrid, grid, buttons;
+
+ int done = 0;
+ char * dir = strdup("");
+ char * tmpDir;
+ char * url = NULL;
+ char * buf;
+ int numPartitions;
+
+ char **partition_list;
+ char *selpart;
+
+ partition_list = NULL;
+ while (!done) {
+ /* if we're doing another pass free this up first */
+ if (partition_list)
+ freePartitionsList(partition_list);
+
+ partition_list = getPartitionsList();
+ numPartitions = lenPartitionsList(partition_list);
+
+ logMessage("partitionslist: %d", numPartitions);
+ for (i=0; i<numPartitions; i++)
+ logMessage("%s", partition_list[i]);
+
+ /* no partitions found, try to load a device driver disk for storage */
+ if (!numPartitions) {
+ rc = newtWinChoice(_("Hard Drives"), _("Yes"), _("Back"),
+ _("You don't seem to have any hard drives on "
+ "your system! Would you like to configure "
+ "additional devices?"));
+ if (rc == 2)
+ return NULL;
+
+ rc = loadDriverFromMedia(CLASS_HD, modLoaded, modDepsPtr,
+ modInfo, kd, flags);
+ if (rc == LOADER_BACK)
+ return NULL;
+
+ continue;
+ }
+
+
+ /* now find out which partition has the hard drive install images */
+ buf = sdupprintf(_("What partition and directory on that "
+ "partition hold the CD (iso9660) images "
+ "for %s? If you don't see the disk drive "
+ "you're using listed here, press F2 "
+ "to configure additional devices."), PRODUCTNAME);
+ text = newtTextboxReflowed(-1, -1, buf, 62, 5, 5, 0);
+ free(buf);
+
+ listbox = newtListbox(-1, -1, numPartitions > 5 ? 5 : numPartitions,
+ NEWT_FLAG_RETURNEXIT |
+ (numPartitions > 5 ? NEWT_FLAG_SCROLL : 0));
+
+ for (i = 0; i < numPartitions; i++)
+ newtListboxAppendEntry(listbox, partition_list[i], partition_list[i]);
+
+ label = newtLabel(-1, -1, _("Directory holding images:"));
+
+ dirEntry = newtEntry(28, 11, dir, 28, &tmpDir, NEWT_ENTRY_SCROLL);
+
+ entryGrid = newtGridHStacked(NEWT_GRID_COMPONENT, label,
+ NEWT_GRID_COMPONENT, dirEntry,
+ NEWT_GRID_EMPTY);
+
+ buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
+
+ grid = newtCreateGrid(1, 4);
+ newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
+ 0, 0, 0, 1, 0, 0);
+ newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox,
+ 0, 0, 0, 1, 0, 0);
+ newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, entryGrid,
+ 0, 0, 0, 1, 0, 0);
+ newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
+ 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+ newtGridWrappedWindow(grid, _("Select Partition"));
+
+ form = newtForm(NULL, NULL, 0);
+ newtFormAddHotKey(form, NEWT_KEY_F2);
+ newtFormAddHotKey(form, NEWT_KEY_F12);
+
+ newtGridAddComponentsToForm(grid, form, 1);
+ newtGridFree(grid, 1);
+
+ newtFormRun(form, &es);
+
+ selpart = newtListboxGetCurrent(listbox);
+
+ free(dir);
+ if (tmpDir && *tmpDir) {
+ /* Protect from form free. */
+ dir = strdup(tmpDir);
+ } else {
+ dir = strdup("");
+ }
+
+ newtFormDestroy(form);
+ newtPopWindow();
+
+ if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) {
+ return NULL;
+ } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) {
+ rc = loadDriverFromMedia(CLASS_HD, modLoaded, modDepsPtr,
+ modInfo, kd, flags);
+ if (rc == LOADER_BACK)
+ return NULL;
+
+ continue;
+ }
+
+ logMessage("partition %s selected", selpart);
+
+ url = setupIsoImages(selpart, dir, flags);
+ if (!url) {
+ newtWinMessage(_("Error"), _("OK"),
+ _("Device %s does not appear to contain "
+ "Red Hat CDROM images."), selpart);
+ continue;
+ }
+
+ done = 1;
+
+ umount("/tmp/hdimage");
+ rmdir("/tmp/hdimage");
+ }
+
+ free(dir);
+
+ return url;
+}
+
+/* use for testing */
+#if 0
+int main() {
+ char **rc, **p;
+
+ rc = getPartitionsList();
+
+ printf("rc: %d\n", lenPartitionsList(rc));
+ for (p=rc; *p; p++)
+ printf("%s\n", *p);
+ freePartitionsList(rc);
+}
+#endif
diff --git a/loader2/hdinstall.h b/loader2/hdinstall.h
new file mode 100644
index 000000000..578fd94b7
--- /dev/null
+++ b/loader2/hdinstall.h
@@ -0,0 +1,10 @@
+#ifndef H_HDINSTALL
+#define H_HDINSTALL
+
+
+char * mountHardDrive(struct installMethod * method,
+ char * location, struct knownDevices * kd,
+ moduleInfoSet modInfo, moduleList modLoaded,
+ moduleDeps * modDepsPtr, int flags);
+
+#endif
diff --git a/loader2/loader.c b/loader2/loader.c
index ec6db8b38..7054e67c8 100644
--- a/loader2/loader.c
+++ b/loader2/loader.c
@@ -78,14 +78,8 @@ static int newtRunning = 0;
/* JKFIXME: just temporarily here. need to move to header files for
* each install method */
#ifdef INCLUDE_LOCAL
-char * mountCdromImage(struct installMethod * method,
- char * location, struct knownDevices * kd,
- moduleInfoSet modInfo, moduleList modLoaded,
- moduleDeps * modDepsPtr, int flags);
-char * mountHardDrive(struct installMethod * method,
- char * location, struct knownDevices * kd,
- moduleInfoSet modInfo, moduleList modLoaded,
- moduleDeps * modDepsPtr, int flags);
+#include "cdinstall.h"
+#include "hdinstall.h"
#endif
#ifdef INCLUDE_NETWORK
char * mountNfsImage(struct installMethod * method,
@@ -101,17 +95,13 @@ char * mountUrlImage(struct installMethod * method,
static struct installMethod installMethods[] = {
#if defined(INCLUDE_LOCAL)
{ N_("Local CDROM"), 0, CLASS_CDROM, mountCdromImage },
+ { N_("Hard drive"), 0, CLASS_HD, mountHardDrive },
#endif
#if defined(INCLUDE_NETWORK)
{ N_("NFS image"), 1, CLASS_NETWORK, mountNfsImage },
{ "FTP", 1, CLASS_NETWORK, mountUrlImage },
{ "HTTP", 1, CLASS_NETWORK, mountUrlImage },
#endif
-#if 0
-#if defined(INCLUDE_LOCAL)
- { N_("Hard drive"), 0, CLASS_HD, mountHardDrive },
-#endif
-#endif
};
static int numMethods = sizeof(installMethods) / sizeof(struct installMethod);
@@ -676,6 +666,7 @@ static char *doLoaderMain(char * location,
* vs network install methods here. do we still want to do that or
* just nuke that code? */
for (i = 0; i < numMethods; i++) {
+ logMessage("Adding %s", _(installMethods[i].name));
installNames[numValidMethods] = _(installMethods[i].name);
validMethods[numValidMethods++] = i;
}
@@ -752,7 +743,6 @@ static char *doLoaderMain(char * location,
kd->known[i].class)
found = 1;
}
- found = 0;
if (found) {
step = STEP_URL;
diff --git a/loader2/method.c b/loader2/method.c
index e84fb9a1b..787c2d1ee 100644
--- a/loader2/method.c
+++ b/loader2/method.c
@@ -240,7 +240,7 @@ int readStampFileFromIso(char *file, char **timestamp, char **releasedescr) {
/* readtime stamp line */
tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
- if (tmpstr)
+ if (tmpptr)
tstamp = strdup(tmpstr);
/* now read OS description line */