From 9770fb1de1911f7ceeabe647ce6b446415163bed Mon Sep 17 00:00:00 2001 From: Mike Fulbright Date: Tue, 3 Dec 2002 06:13:24 +0000 Subject: added hd install support --- loader2/hdinstall.c | 413 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 loader2/hdinstall.c (limited to 'loader2/hdinstall.c') 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 + * Matt Wilson + * Michael Fulbright + * Jeremy Katz + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#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 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 -- cgit