Пример #1
0
char * mountNfsImage(struct installMethod * method,
                     char * location, struct loaderData_s * loaderData) {
    char * host = NULL;
    char * directory = NULL;
    char * mountOpts = NULL;
    char * fullPath = NULL;
    char * url = NULL;

    enum { NFS_STAGE_NFS, NFS_STAGE_MOUNT, NFS_STAGE_DONE,
           NFS_STAGE_UPDATES } stage = NFS_STAGE_NFS;

    int rc;

    /* JKFIXME: ASSERT -- we have a network device setup when we get here */
    while (stage != NFS_STAGE_DONE) {
        switch (stage) {
        case NFS_STAGE_NFS:
            logMessage(INFO, "going to do nfsGetSetup");
            if (loaderData->method == METHOD_NFS && loaderData->stage2Data) {
                host = ((struct nfsInstallData *)loaderData->stage2Data)->host;
                directory = ((struct nfsInstallData *)loaderData->stage2Data)->directory;

                if (((struct nfsInstallData *)
                    loaderData->stage2Data)->mountOpts == NULL) {
                    mountOpts = strdup("ro");
                } else {
                    if (asprintf(&mountOpts, "ro,%s",
                                 ((struct nfsInstallData *)
                                 loaderData->stage2Data)->mountOpts) == -1) {
                        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                        abort();
                    }
                }

                logMessage(INFO, "host is %s, dir is %s, opts are '%s'", host, directory, mountOpts);

                if (!host || !directory) {
                    logMessage(ERROR, "missing host or directory specification");

                    if (loaderData->inferredStage2)
                        loaderData->invalidRepoParam = 1;

                    loaderData->method = -1;
                    break;
                } else {
                    host = strdup(host);
                    directory = strdup(directory);
                }
            } else {
                char *substr, *tmp;

                if (nfsGetSetup(&host, &directory) == LOADER_BACK)
                    return NULL;

                /* If the user-provided URL points at a repo instead of a
                 * stage2 image, fix that up now.
                 */
                substr = strstr(directory, ".img");
                if (!substr || (substr && *(substr+4) != '\0')) {
                    if (asprintf(&(loaderData->instRepo), "nfs:%s:%s",
                                 host, directory) == -1) {
                        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                        abort();
                    }

                    if (asprintf(&tmp, "nfs:%s:%s/images/install.img",
                                 host, directory) == -1) {
                        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                        abort();
                    }

                    setStage2LocFromCmdline(tmp, loaderData);
                    free(host);
                    free(directory);
                    free(tmp);
                    continue;
                }

                loaderData->invalidRepoParam = 1;
            }

            stage = NFS_STAGE_MOUNT;
            break;

        case NFS_STAGE_MOUNT: {
            char *buf;

            if (asprintf(&fullPath, "%s:%.*s", host,
                         (int) (strrchr(directory, '/')-directory),
                         directory) == -1) {
                logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                abort();
            }

            logMessage(INFO, "mounting nfs path %s", fullPath);

            if (FL_TESTING(flags)) {
                stage = NFS_STAGE_DONE;
                break;
            }

            stage = NFS_STAGE_NFS;

            if (!doPwMount(fullPath, "/mnt/stage2", "nfs", mountOpts, NULL)) {
                if (asprintf(&buf, "/mnt/stage2/%s",
                             strrchr(directory, '/')) == -1) {
                    logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                    abort();
                }

                if (!access(buf, R_OK)) {
                    logMessage(INFO, "can access %s", buf);
                    rc = mountStage2(buf);

                    if (rc == 0) {
                        stage = NFS_STAGE_UPDATES;

                        if (asprintf(&url, "nfs:%s:%s", host,
                                     directory) == -1) {
                            logMessage(CRITICAL, "%s: %d: %m", __func__,
                                       __LINE__);
                            abort();
                        }

                        free(buf);
                        break;
                    } else {
                        logMessage(WARNING, "unable to mount %s", buf);
                        free(buf);
                        break;
                    }
                } else {
                    logMessage(WARNING, "unable to access %s", buf);
                    free(buf);
                    umount("/mnt/stage2");
                }
            } else {
                newtWinMessage(_("Error"), _("OK"),
                               _("That directory could not be mounted from "
                                 "the server."));
                if (loaderData->method >= 0)
                    loaderData->method = -1;

                if (loaderData->inferredStage2)
                    loaderData->invalidRepoParam = 1;

                break;
            }

            if (asprintf(&buf, _("That directory does not seem to "
                                 "contain a %s installation image."),
                         getProductName()) == -1) {
                logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                abort();
            }

            newtWinMessage(_("Error"), _("OK"), buf);
            free(buf);

            if (loaderData->method >= 0)
                loaderData->method = -1;

            if (loaderData->inferredStage2)
                loaderData->invalidRepoParam = 1;

            break;
        }

        case NFS_STAGE_UPDATES: {
            char *buf;

            if (asprintf(&buf, "%.*s/RHupdates",
                         (int) (strrchr(fullPath, '/')-fullPath),
                         fullPath) == -1) {
                logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                abort();
            }

            logMessage(INFO, "mounting nfs path %s for updates", buf);

            if (!doPwMount(buf, "/tmp/update-disk", "nfs", mountOpts, NULL)) {
                logMessage(INFO, "Using RHupdates/ for NFS install");
                copyDirectory("/tmp/update-disk", "/tmp/updates", NULL, NULL);
                umount("/tmp/update-disk");
                unlink("/tmp/update-disk");
            } else {
                logMessage(INFO, "No RHupdates/ directory found, skipping");
            }

            stage = NFS_STAGE_DONE;
            break;
        }

        case NFS_STAGE_DONE:
            break;
        }
    }

    free(host);
    free(directory);
    if (fullPath)
        free(fullPath);

    return url;
}
Пример #2
0
char * mountNfsImage(struct installMethod * method,
                     char * location, struct loaderData_s * loaderData,
                     moduleInfoSet modInfo, moduleList modLoaded,
                     moduleDeps * modDepsPtr) {
    char * host = NULL;
    char * directory = NULL;
    char * mountOpts = NULL;
    char * fullPath = NULL;
    char * path;
    char * url = NULL;

    enum { NFS_STAGE_NFS, NFS_STAGE_MOUNT, 
           NFS_STAGE_DONE } stage = NFS_STAGE_NFS;

    int rc;
    int dir = 1;

    /* JKFIXME: ASSERT -- we have a network device setup when we get here */
    while (stage != NFS_STAGE_DONE) {
        switch (stage) {
        case NFS_STAGE_NFS:
            logMessage(INFO, "going to do nfsGetSetup");
            if (loaderData->method == METHOD_NFS && loaderData->methodData) {
                host = ((struct nfsInstallData *)loaderData->methodData)->host;
                directory = ((struct nfsInstallData *)loaderData->methodData)->directory;
                mountOpts = ((struct nfsInstallData *)loaderData->methodData)->mountOpts;

                logMessage(INFO, "host is %s, dir is %s, opts are '%s'", host, directory, mountOpts);

                if (!host || !directory) {
                    logMessage(ERROR, "missing host or directory specification");
                    loaderData->method = -1;
                    break;
                } else {
                    host = strdup(host);
                    directory = strdup(directory);
                    if (mountOpts) {
                        mountOpts = strdup(mountOpts);
                    }
                }
            } else if (nfsGetSetup(&host, &directory, &mountOpts) == LOADER_BACK) {
                return NULL;
            }
             
            stage = NFS_STAGE_MOUNT;
            dir = 1;
            break;

        case NFS_STAGE_MOUNT: {
            int foundinvalid = 0;
            char * buf;
            struct in_addr ip;

            if (loaderData->noDns && !(inet_pton(AF_INET, host, &ip))) {
                newtWinMessage(_("Error"), _("OK"),
                               _("Hostname specified with no DNS configured"));
                if (loaderData->method >= 0) {
                    loaderData->method = -1;
                }
                break;
            }

            fullPath = alloca(strlen(host) + strlen(directory) + 2);
            sprintf(fullPath, "%s:%s", host, directory);

            logMessage(INFO, "mounting nfs path %s, options '%s'", fullPath, mountOpts);

            if (FL_TESTING(flags)) {
                stage = NFS_STAGE_DONE;
                dir = 1;
                break;
            }

            stage = NFS_STAGE_NFS;

            if (!doPwMount(fullPath, "/mnt/source", "nfs", 
                           IMOUNT_RDONLY, mountOpts)) {
                if (!access("/mnt/source/images/stage2.img", R_OK)) {
                    logMessage(INFO, "can access /mnt/source/images/stage2.img");
                    rc = mountStage2("/mnt/source/images/stage2.img");
                    logMessage(DEBUGLVL, "after mountStage2, rc is %d", rc);
                    if (rc) {
                        if (rc == -1) { 
                            foundinvalid = 1; 
                            logMessage(WARNING, "not the right one"); 
                        }
                    } else {
                        stage = NFS_STAGE_DONE;
                        url = "nfs://mnt/source/.";
                        break;
                    }
                } else {
                    logMessage(WARNING, "unable to access /mnt/source/images/stage2.img");
                }

                if ((path = validIsoImages("/mnt/source", &foundinvalid))) {
		    foundinvalid = 0;
		    logMessage(INFO, "Path to valid iso is %s", path);
                    copyUpdatesImg("/mnt/source/updates.img");

                    if (mountLoopback(path, "/mnt/source2", "loop1")) 
                        logMessage(WARNING, "failed to mount iso %s loopback", path);
                    else {
                        rc = mountStage2("/mnt/source2/images/stage2.img");
                        if (rc) {
                            umountLoopback("/mnt/source2", "loop1");
                            if (rc == -1)
				foundinvalid = 1;
                        } else {
                            /* JKFIXME: hack because /mnt/source is hard-coded
                             * in mountStage2() */
                            copyUpdatesImg("/mnt/source2/images/updates.img");
                            copyProductImg("/mnt/source2/images/product.img");

                            queryIsoMediaCheck(path);

                            stage = NFS_STAGE_DONE;
                            url = "nfsiso:/mnt/source";
                            break;
                        }
                    }
                }

		/* if we fell through to here we did not find a valid NFS */
		/* source for installation.                               */
		umount("/mnt/source");
                if (foundinvalid) 
                    buf = sdupprintf(_("The %s installation tree in that "
                                       "directory does not seem to match "
                                       "your boot media."), getProductName());
                else
                    buf = sdupprintf(_("That directory does not seem to "
                                       "contain a %s installation tree."),
                                     getProductName());
                newtWinMessage(_("Error"), _("OK"), buf);
                if (loaderData->method >= 0) {
                    loaderData->method = -1;
                }

		
                break;
            } else {
                newtWinMessage(_("Error"), _("OK"),
                               _("That directory could not be mounted from "
                                 "the server."));
                if (loaderData->method >= 0) {
                    loaderData->method = -1;
                }
                break;
            }
        }

        case NFS_STAGE_DONE:
            break;
        }
    }

    free(host);
    free(directory);
    free(mountOpts);

    return url;
}