示例#1
0
int kickstartFromBD(char *kssrc) {
    int rc;
    char *p, *np = NULL, *r = NULL, *tmpstr, *ksdev, *kspath, *biosksdev;

    logMessage(INFO, "getting kickstart file from biosdrive");

    /* format is bd:[device]:/path/to/ks.cfg */
    /* split of pieces */
    tmpstr = strdup(kssrc);
    p = strchr(tmpstr, ':');
    if (p)
        np = strchr(p+1, ':');
    
    if (!p || !np) {
        logMessage(WARNING, "Format of command line is ks=bd:device:/path/to/ks.cfg");
        free(tmpstr);
        return 1;
    }

    *np = '\0';
    kspath = np+1;

    r = strchr(p+1,'p');
    if(!r){
        logMessage(INFO, "Format of biosdisk is 80p1");
        free(tmpstr);
        return 1;
    }                                                          

    *r = '\0';
    biosksdev = getBiosDisk((p + 1));
    if(!biosksdev){
        startNewt();
        newtWinMessage(_("Error"), _("OK"),
                       _("Cannot find hard drive for BIOS disk %s"),
                       p + 1);
        return 1;
    }


    ksdev = malloc(strlen(biosksdev) + 3);
    sprintf(ksdev, "%s%s", biosksdev, r + 1);
    logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath);
    if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) {
        if (rc == 3) {
            startNewt();
            newtWinMessage(_("Error"), _("OK"),
                           _("Cannot find kickstart file on hard drive."));
        }
        return 1;
    }

    return 0;
}
示例#2
0
void loadKickstartModule(struct loaderData_s * loaderData,
                         int argc, char **argv) {
    gchar *opts = NULL;
    gchar *module = NULL;
    gchar **args = NULL, **remaining = NULL;
    gboolean rc;
    GOptionContext *optCon = g_option_context_new(NULL);
    GError *optErr = NULL;
    GOptionEntry ksDeviceOptions[] = {
        { "opts", 0, 0, G_OPTION_ARG_STRING, &opts, NULL, NULL },
        {   G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
            NULL, NULL
        },
        { NULL },
    };

    g_option_context_set_help_enabled(optCon, FALSE);
    g_option_context_add_main_entries(optCon, ksDeviceOptions, NULL);

    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Bad argument to device kickstart method "
                         "command: %s"), optErr->message);
        g_error_free(optErr);
        g_option_context_free(optCon);
        return;
    }

    g_option_context_free(optCon);

    if ((remaining != NULL) && (g_strv_length(remaining) == 1)) {
        module = remaining[0];
    }

    if (!module) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("A module name must be specified for "
                         "the kickstart device command."));
        return;
    }

    if (opts) {
        args = g_strsplit(opts, " ", 0);
    }

    rc = mlLoadModule(module, args);
    g_strfreev(args);
    return;
}
示例#3
0
void setKickstartHD(struct loaderData_s * loaderData, int argc,
                     char ** argv) {
    char *p;
    gchar *biospart = NULL, *partition = NULL, *dir = NULL;
    GOptionContext *optCon = g_option_context_new(NULL);
    GError *optErr = NULL;
    GOptionEntry ksHDOptions[] = {
        { "biospart", 0, 0, G_OPTION_ARG_STRING, &biospart, NULL, NULL },
        { "partition", 0, 0, G_OPTION_ARG_STRING, &partition, NULL, NULL },
        { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL },
        { NULL },
    };

    logMessage(INFO, "kickstartFromHD");

    g_option_context_set_help_enabled(optCon, FALSE);
    g_option_context_add_main_entries(optCon, ksHDOptions, NULL);

    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Bad argument to HD kickstart method "
                         "command: %s"), optErr->message);
        g_error_free(optErr);
        g_option_context_free(optCon);
        return;
    }

    g_option_context_free(optCon);

    if (biospart) {
        char * dev;

        p = strchr(biospart,'p');
        if(!p){
            logMessage(ERROR, "Bad argument for --biospart");
            return;
        }
        *p = '\0';
        dev = getBiosDisk(biospart);
        if (dev == NULL) {
            logMessage(ERROR, "Unable to location BIOS partition %s", biospart);
            return;
        }
        partition = malloc(strlen(dev) + strlen(p + 1) + 2);
        sprintf(partition, "%s%s", dev, p + 1);
    }

    loaderData->method = METHOD_HD;
    loaderData->stage2Data = calloc(sizeof(struct hdInstallData *), 1);
    if (partition)
        ((struct hdInstallData *)loaderData->stage2Data)->partition = partition;
    if (dir)
        ((struct hdInstallData *)loaderData->stage2Data)->directory = dir;

    logMessage(INFO, "results of hd ks, partition is %s, dir is %s", partition,
               dir);
}
示例#4
0
void setKickstartNfs(struct loaderData_s * loaderData, int argc,
                     char ** argv) {
    char * host = NULL, * dir = NULL, * mountOpts = NULL;
    char *substr = NULL;
    poptContext optCon;
    int rc;
    struct poptOption ksNfsOptions[] = {
        { "server", '\0', POPT_ARG_STRING, &host, 0, NULL, NULL },
        { "dir", '\0', POPT_ARG_STRING, &dir, 0, NULL, NULL },
        { "opts", '\0', POPT_ARG_STRING, &mountOpts, 0, NULL, NULL},
        { 0, 0, 0, 0, 0, 0, 0 }
    };

    logMessage(INFO, "kickstartFromNfs");
    optCon = poptGetContext(NULL, argc, (const char **) argv, ksNfsOptions, 0);
    if ((rc = poptGetNextOpt(optCon)) < -1) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Bad argument to NFS kickstart method "
                         "command %s: %s"),
                       poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
                       poptStrerror(rc));
        return;
    }

    if (!host || !dir) {
        logMessage(ERROR, "host and directory for nfs kickstart not specified");
        return;
    }

    loaderData->method = METHOD_NFS;

    substr = strstr(dir, ".img");
    if (!substr || (substr && *(substr+4) != '\0')) {
        if (asprintf(&(loaderData->instRepo), "nfs:%s:%s", host, dir) == -1) {
            logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
            abort();
        }

        logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
                   host, dir, mountOpts);
    } else {
        loaderData->stage2Data = calloc(sizeof(struct nfsInstallData *), 1);
        ((struct nfsInstallData *)loaderData->stage2Data)->host = host;
        ((struct nfsInstallData *)loaderData->stage2Data)->directory = dir;
        ((struct nfsInstallData *)loaderData->stage2Data)->mountOpts = mountOpts;

        logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
                   ((struct nfsInstallData *) loaderData->stage2Data)->host,
                   ((struct nfsInstallData *) loaderData->stage2Data)->directory,
                   ((struct nfsInstallData *) loaderData->stage2Data)->mountOpts);
    }
}
示例#5
0
int kickstartFromRemovable(char *kssrc) {
    struct device ** devices;
    char *p, *kspath;
    int i, rc;

    logMessage(INFO, "doing kickstart from removable media");
    devices = getDevices(DEVICE_DISK);
    /* usb can take some time to settle, even with the various hacks we
     * have in place. some systems use portable USB CD-ROM drives, try to
     * make sure there really isn't one before bailing. */
    for (i = 0; !devices && i < 10; ++i) {
        logMessage(INFO, "sleeping to wait for a USB disk");
        sleep(2);
        devices = getDevices(DEVICE_DISK);
    }
    if (!devices) {
        logMessage(ERROR, "no disks");
        return 1;
    }

    for (i = 0; devices[i]; i++) {
        if (devices[i]->priv.removable == 1) {
            logMessage(INFO, "first removable media is %s", devices[i]->device);
            break;
        }
    }

    if (!devices[i] || (devices[i]->priv.removable == 0)) {
        logMessage(ERROR, "no removable devices");
        return 1;
    }

    /* format is floppy:[/path/to/ks.cfg] */
    kspath = "";
    p = strchr(kssrc, ':');
    if (p)
	kspath = p + 1;

    if (!p || strlen(kspath) < 1)
	kspath = "/ks.cfg";

    if ((rc=getKickstartFromBlockDevice(devices[i]->device, kspath))) {
	if (rc == 3) {
	    startNewt();
	    newtWinMessage(_("Error"), _("OK"),
			   _("Cannot find ks.cfg on removable media."));
	}
	return 1;
    }

    return 0;
}
示例#6
0
void setKickstartUrl(struct loaderData_s * loaderData, int argc,
		    char ** argv) {

    char *url = NULL, *substr = NULL;
    poptContext optCon;
    int rc;
    struct poptOption ksUrlOptions[] = {
        { "url", '\0', POPT_ARG_STRING, &url, 0, NULL, NULL },
        { 0, 0, 0, 0, 0, 0, 0 }
    };

    logMessage(INFO, "kickstartFromUrl");
    optCon = poptGetContext(NULL, argc, (const char **) argv, ksUrlOptions, 0);
    if ((rc = poptGetNextOpt(optCon)) < -1) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Bad argument to Url kickstart method "
                         "command %s: %s"),
                       poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
                       poptStrerror(rc));
        return;
    }

    if (!url) {
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Must supply a --url argument to Url kickstart method."));
        return;
    }

    /* determine install type */
    if (strstr(url, "http://") || strstr(url, "ftp://"))
	loaderData->method = METHOD_URL;
    else {
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Unknown Url method %s"), url);
        return;
    }

    substr = strstr(url, ".img");
    if (!substr || (substr && *(substr+4) != '\0')) {
        loaderData->instRepo = strdup(url);
    } else {
        if ((loaderData->stage2Data = calloc(sizeof(struct urlInstallData *), 1)) == NULL)
            return;

        ((struct urlInstallData *)loaderData->stage2Data)->url = url;
    }

    logMessage(INFO, "results of url ks, url %s", url);
}
int kickstartFromCD(char *kssrc) {
    int rc, i;
    char *p, *kspath;
    struct device ** devices;

    logMessage(INFO, "getting kickstart file from first CDROM");

    devices = probeDevices(CLASS_CDROM, BUS_UNSPEC, 0);
    /* usb can take some time to settle, even with the various hacks we
     * have in place.  some systems use portable USB CD-ROM drives, try to
     * make sure there really isn't one before bailing */
    for (i = 0; !devices && i < 10; ++i) {
        logMessage(DEBUGLVL, "sleeping to wait for a USB CD-ROM");
        sleep(2);
        devices = probeDevices(CLASS_CDROM, BUS_UNSPEC, 0);
    }

    if (!devices) {
        logMessage(ERROR, "No CDROM devices found!");
        return 1;
    }

    /* format is cdrom:[/path/to/ks.cfg] */
    kspath = "";
    p = strchr(kssrc, ':');
    if (p)
        kspath = p + 1;

    if (!p || strlen(kspath) < 1)
        kspath = "/ks.cfg";

    for (i=0; devices[i]; i++) {
        if (!devices[i]->device)
            continue;

        rc = getKickstartFromBlockDevice(devices[i]->device, kspath);
        if (rc == 0)
            return 0;
    }

    startNewt();
    newtWinMessage(_("Error"), _("OK"),
                   _("Cannot find kickstart file on CDROM."));
    return 1;
}
示例#8
0
int kickstartFromHD(char *kssrc) {
    int rc;
    char *p, *np = NULL, *tmpstr, *ksdev, *kspath;

    logMessage(INFO, "getting kickstart file from harddrive");

    /* format is hd:[device]:/path/to/ks.cfg */
    /* split up pieces */
    tmpstr = strdup(kssrc);
    p = strchr(tmpstr, ':');
    if (p)
        np = strchr(p+1, ':');
    
    /* no second colon, assume its the old format of                     */
    /*        hd:[device]/path/to/ks.cfg                                 */
    /* this format is bad however because some devices have '/' in them! */
    if (!np)
        np = strchr(p+1, '/');

    if (!p || !np) {
        logMessage(WARNING, "Format of command line is ks=hd:[device]:/path/to/ks.cfg");
        free(tmpstr);
        return 1;
    }

    *np = '\0';
    ksdev = p+1;
    kspath = np+1;

    logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath);
    if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) {
        if (rc == 3) {
            startNewt();
            newtWinMessage(_("Error"), _("OK"),
                           _("Cannot find kickstart file on hard drive."));
        }
        return 1;
    }

    return 0;
}
示例#9
0
static char *newKickstartLocation(const char *origLocation) {
    const char *location;
    char *retval = NULL;
    newtComponent f, okay, cancel, answer, locationEntry;
    newtGrid grid, buttons;

    startNewt();

    locationEntry = newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL);
    newtEntrySet(locationEntry, origLocation, 1);

    /* button bar at the bottom of the window */
    buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL);

    grid = newtCreateGrid(1, 3);

    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT,
                     newtTextboxReflowed(-1, -1, _("Unable to download the kickstart file.  Please modify the kickstart parameter below or press Cancel to proceed as an interactive installation."), 60, 0, 0, 0),
                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry,
                     0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
                     0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);

    f = newtForm(NULL, NULL, 0);
    newtGridAddComponentsToForm(grid, f, 1);
    newtGridWrappedWindow(grid, _("Error downloading kickstart file"));
    newtGridFree(grid, 1);

    /* run the form */
    answer = newtRunForm(f);

    if (answer != cancel)
        retval = strdup(location);

    newtFormDestroy(f);
    newtPopWindow();

    return retval;
}
示例#10
0
void setKickstartNfs(struct loaderData_s * loaderData, int argc,
                     char ** argv) {
    char * host = NULL, * dir = NULL, * mountOpts = NULL;
    poptContext optCon;
    int rc;
    struct poptOption ksNfsOptions[] = {
        { "server", '\0', POPT_ARG_STRING, &host, 0, NULL, NULL },
        { "dir", '\0', POPT_ARG_STRING, &dir, 0, NULL, NULL },
        { "opts", '\0', POPT_ARG_STRING, &mountOpts, 0, NULL, NULL},
        { 0, 0, 0, 0, 0, 0, 0 }
    };

    logMessage(INFO, "kickstartFromNfs");
    optCon = poptGetContext(NULL, argc, (const char **) argv, ksNfsOptions, 0);
    if ((rc = poptGetNextOpt(optCon)) < -1) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Bad argument to NFS kickstart method "
                         "command %s: %s"),
                       poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
                       poptStrerror(rc));
        return;
    }

    if (!host || !dir) {
        logMessage(ERROR, "host and directory for nfs kickstart not specified");
        return;
    }

    loaderData->method = METHOD_NFS;
    loaderData->methodData = calloc(sizeof(struct nfsInstallData *), 1);
    if (host)
        ((struct nfsInstallData *)loaderData->methodData)->host = host;
    if (dir)
        ((struct nfsInstallData *)loaderData->methodData)->directory = dir;
    if (mountOpts)
        ((struct nfsInstallData *)loaderData->methodData)->mountOpts = mountOpts;

    logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'", host, dir, mountOpts);
}
示例#11
0
static void setShutdown(struct loaderData_s * loaderData, int argc, 
                    char ** argv) {
    gint eject = 0, reboot = 0, halt = 0, poweroff = 0;
    GOptionContext *optCon = g_option_context_new(NULL);
    GError *optErr = NULL;
    GOptionEntry ksOptions[] = {
        { "eject", 'e', 0, G_OPTION_ARG_INT, &eject, NULL, NULL },
        { "reboot", 'r', 0, G_OPTION_ARG_INT, &reboot, NULL, NULL },
        { "halt", 'h', 0, G_OPTION_ARG_INT, &halt, NULL, NULL },
        { "poweroff", 'p', 0, G_OPTION_ARG_INT, &poweroff, NULL, NULL },
        { NULL },
    };

    g_option_context_set_help_enabled(optCon, FALSE);
    g_option_context_add_main_entries(optCon, ksOptions, NULL);

    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Bad argument to shutdown kickstart method "
                         "command: %s"), optErr->message);
        g_error_free(optErr);
        g_option_context_free(optCon);
        return;
    }

    g_option_context_free(optCon);

    if (FL_NOKILL(flags)) {
        flags |= LOADER_FLAGS_HALT;
    } else  {
        if (poweroff)
            flags |= LOADER_FLAGS_POWEROFF;
        if ((!poweroff && !reboot) || (halt))
            flags |= LOADER_FLAGS_HALT;
    }
}
/* JKFIXME: Assumes CD is mounted as /mnt/source                      */
static void queryCDMediaCheck(char *dev) {
    int rc;
    char mediasum[33];
    int isostatus;

    /* dont bother to test in automated installs */
    if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags))
        return;

    /* see what status is */
    isostatus = getISOStatusFromCDROM(dev, mediasum);
    writeISOStatus(isostatus, mediasum);

    /* see if we should check image(s) */
    /* in rescue mode only test if they explicitly asked to */
    if ((!isostatus && !FL_RESCUE(flags)) || FL_MEDIACHECK(flags)) {
        startNewt();
        rc = newtWinChoice(_("CD Found"), _("OK"), _("Skip"), 
             _("To begin testing the CD media before installation press %s.\n\n"
               "Choose %s to skip the media test and start the installation."),
             _("OK"), _("Skip"));

        if (rc != 2) {
            /* unmount CD now we've identified */
            /* a valid disc #1 is present */
            umountStage2();
            umount("/mnt/source");
      
            /* test CD(s) */
            mediaCheckCdrom(dev);
      
            /* remount stage2 from CD #1 and proceed */
            mountCdromStage2(dev);
        }
    }
}
示例#13
0
int ksReadCommands(char * cmdFile) {
    int fd;
    char * buf;
    struct stat sb;
    char * start, * end, * chptr;
    char oldch;
    int line = 0;
    gint argc = 0;
    gchar **argv = NULL;
    GError *optErr = NULL;
    int inSection = 0; /* in a section such as %post, %pre or %packages */
    struct ksCommandNames * cmd;
    int commandsAlloced = 5;

    if ((fd = open(cmdFile, O_RDONLY)) < 0) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Error opening kickstart file %s: %m"),
                       cmdFile);
        return LOADER_ERROR;
    }

    fstat(fd, &sb);
    buf = alloca(sb.st_size + 1);
    if (read(fd, buf, sb.st_size) != sb.st_size) {
        startNewt();
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Error reading contents of kickstart file %s: %m"),
                       cmdFile);
        close(fd);
        return LOADER_ERROR;
    }

    close(fd);

    buf[sb.st_size] = '\0';

    commands = malloc(sizeof(*commands) * commandsAlloced);

    start = buf;
    while (*start && !inSection) {
        line++;
        if (!(end = strchr(start, '\n')))
            end = start + strlen(start);

        oldch = *end;
        *end = '\0';

        while (*start && isspace(*start)) start++;

        chptr = end - 1;
        while (chptr > start && isspace(*chptr)) chptr--;
        
        if (isspace(*chptr)) 
            *chptr = '\0';
        else
            *(chptr + 1) = '\0';

        if (!*start || *start == '#' || !strncmp(start, "%include", 8)) {
            /* keep parsing the file */
        } else if (*start == '%') {
            /* assumed - anything starting with %something is a section */
            inSection = 1;
#ifdef  STACKI
        } else if (!*start || *start == '<') {
            /* do nothing */
            /* this makes anaconda ignore our XML statements in the */
            /* kickstart file */
            ;
#endif
        } else if  (*chptr == '\\') {
            /* JKFIXME: this should be handled better, but at least we 
             * won't segfault now */
        } else {
            if (!g_shell_parse_argv(start, &argc, &argv, &optErr) && argc) {
                newtWinMessage(_("Kickstart Error"), _("OK"),
                               _("Error in %s on line %d of kickstart "
                                 "file %s."), argv[0], line, cmdFile);
                g_error_free(optErr);
            } else if (!argc) {
                newtWinMessage(_("Kickstart Error"), _("OK"),
                               _("Missing options on line %d of kickstart "
                                 "file %s."), line, cmdFile);
            } else {
                for (cmd = ksTable; cmd->name; cmd++)
                    if (!strcmp(cmd->name, argv[0])) break;
                
                if (cmd->name) {
                    if (numCommands == commandsAlloced) {
                        commandsAlloced += 5;
                        commands = realloc(commands,
                                           sizeof(*commands) * commandsAlloced);
                    }
                    
                    commands[numCommands].code = cmd->code;
                    commands[numCommands].argc = argc;
                    commands[numCommands].argv = argv;
                    numCommands++;
                }
            }
        }
        
        if (oldch)
            start = end + 1;
        else
            start = end;
    }
    
    return 0;
}
示例#14
0
/* this copies the contents of the driver disk to a ramdisk and loads
 * the moduleinfo, etc.  assumes a "valid" driver disk mounted at mntpt */
static int loadDriverDisk(struct loaderData_s *loaderData, char *mntpt) {
    moduleDeps *modDepsPtr = loaderData->modDepsPtr;
    moduleInfoSet modInfo = loaderData->modInfo;
    char file[200], dest[200];
    char * title;
    struct moduleBallLocation * location;
    struct stat sb;
    static int disknum = 0;
    int version = 1;
    int fd, ret;

    /* check for both versions */
    sprintf(file, "%s/rhdd", mntpt);
    if (access(file, R_OK)) {
        version = 0;
        sprintf(file, "%s/rhdd-6.1", mntpt);
        if (access(file, R_OK)) {
            /* this can't happen, we already verified it! */
            return LOADER_BACK;
        } 
    }
    stat(file, &sb);
    title = malloc(sb.st_size + 1);

    fd = open(file, O_RDONLY);
    ret = read(fd, title, sb.st_size);
    if (title[sb.st_size - 1] == '\n')
        sb.st_size--;
    title[sb.st_size] = '\0';
    close(fd);

    sprintf(file, "/tmp/ramfs/DD-%d", disknum);
    mkdirChain(file);

    if (!FL_CMDLINE(flags)) {
        startNewt();
        winStatus(40, 3, _("Loading"), _("Reading driver disk..."));
    }

    sprintf(dest, "/tmp/ramfs/DD-%d", disknum);
    copyDirectory(mntpt, dest);

    location = malloc(sizeof(struct moduleBallLocation));
    location->title = strdup(title);
    location->path = sdupprintf("/tmp/ramfs/DD-%d/modules.cgz", disknum);
    location->version = version;

    char *fwdir = sdupprintf("/tmp/ramfs/DD-%d/firmware", disknum);
    if (!access(fwdir, R_OK|X_OK)) {
        add_fw_search_dir(loaderData, fwdir);
        stop_fw_loader(loaderData);
        start_fw_loader(loaderData);
    }
    free(fwdir);

    sprintf(file, "%s/modinfo", mntpt);
    readModuleInfo(file, modInfo, location, 1);

    sprintf(file, "%s/modules.dep", mntpt);
    mlLoadDeps(modDepsPtr, file);

    sprintf(file, "%s/modules.alias", mntpt);
    pciReadDrivers(file);

    if (!FL_CMDLINE(flags))
        newtPopWindow();

    disknum++;
    return 0;
}