void start_httpd() { /* * the first two NULLs are place holders for the 'nextServer' info */ char *args[] = { "/lighttpd/sbin/lighttpd", "-f", "/lighttpd/conf/lighttpd.conf", "-D", NULL }; int pid; int i; struct device **devs; /* * try to mount the CD */ devs = probeDevices(CLASS_CDROM, BUS_UNSPEC, 0); if (devs) { for (i = 0; devs[i]; i++) { if (!devs[i]->device) { continue; } devMakeInode(devs[i]->device, "/tmp/rocks-cdrom"); logMessage(INFO, "start_httpd:trying to mount device %s", devs[i]->device); if (doPwMount("/tmp/rocks-cdrom", "/mnt/cdrom", "iso9660", IMOUNT_RDONLY, NULL)) { logMessage(ERROR, "start_httpd:doPwMount failed\n"); } else { /* * if there are multiple CD drives, exit this * loop after the first successful mount */ break; } } } /* * start the service */ pid = fork(); if (pid != 0) { #ifdef LATER /* * don't close stdin or stdout. this causes problems * with mini_httpd as it uses these file descriptors for * it's CGI processing */ close(2); #endif execv(args[0], args); logMessage(ERROR, "start_httpd:lighttpd failed\n"); } }
static PyObject * doMount(PyObject * s, PyObject * args) { char *err = NULL, *fs, *device, *mntpoint, *flags = NULL; int rc; if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint, &flags)) return NULL; rc = doPwMount(device, mntpoint, fs, flags, &err); if (rc == IMOUNT_ERR_ERRNO) PyErr_SetFromErrno(PyExc_SystemError); else if (rc) { PyObject *tuple = PyTuple_New(2); PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); if (err == NULL) { Py_INCREF(Py_None); PyTuple_SetItem(tuple, 1, Py_None); } else { PyTuple_SetItem(tuple, 1, PyString_FromString(err)); } PyErr_SetObject(PyExc_SystemError, tuple); } if (rc) return NULL; Py_INCREF(Py_None); return Py_None; }
/* JKFIXME: Assumes CD is mounted as /mnt/source */ static void mountCdromStage2(char *cddev) { int gotcd1=0; int rc; devMakeInode(cddev, "/tmp/cdrom"); do { do { if (doPwMount("/tmp/cdrom", "/mnt/source", "iso9660", IMOUNT_RDONLY, NULL)) { if (!FL_NOEJECT(flags)) ejectCdrom(); else logMessage(INFO, "noeject in effect, not ejecting cdrom"); wrongCDMessage(); } else { break; } } while (1); rc = mountStage2("/mnt/source/images/stage2.img"); /* if we failed, umount /mnt/source and keep going */ if (rc) { umount("/mnt/source"); if (!FL_NOEJECT(flags)) ejectCdrom(); else logMessage(INFO, "noeject in effect, not ejecting cdrom"); wrongCDMessage(); } else { gotcd1 = 1; } } while (!gotcd1); }
static int mountRocksDevice (char *device, int major, int minor, char *marker) { mode_t mode; char devicepath[128]; char markerpath[128]; char *fstype[10]; char *mountpoint = "/mnt/rocks-disk"; int rc, i=0; if (ignoreCert()) return 1; sprintf(devicepath, "/tmp/rocks-%s", device); mode = S_IFBLK | S_IRUSR | S_IWUSR; if (mknod(devicepath, mode, makedev(major, minor)) < 0) { logMessage(ERROR, "mountRocksDevice:mknod failed: %s", strerror(errno)); return 1; } mkdirChain(mountpoint); /* Mount the partition. I dont like this exhaustive search. */ fstype[i++] = "ext3"; fstype[i++] = "ext2"; fstype[i++] = "vfat"; fstype[i++] = "xfs"; fstype[i++] = 0; for (i=0; fstype[i]; i++) { rc = doPwMount(devicepath, mountpoint, fstype[i], 0, NULL); if (!rc) break; } if (!fstype[i]) goto error; snprintf(markerpath, 128, "%s/%s", mountpoint, marker); if (!access(markerpath, F_OK)) { logMessage(INFO, "mountRocksDevice: found rocks device " "at %s, mounted on %s", devicepath, mountpoint); return 0; } error: unlink(devicepath); umount(mountpoint); return 1; }
int doMultiMount(char *dev, char *where, char **fstypes, char *options, char **err) { int retval = 0, i; for (i = 0; fstypes[i]; i++) { /* If we made a previous call to mount and it returned an error message, * get rid of it now. We only want to preserve the error from the last * fstype. */ if (err && *err && **err) { free(*err); *err = NULL; } retval = doPwMount(dev, where, fstypes[i], options, err); if (!retval) return retval; } return retval; }
/* Error codes: 1 - could not create device node 2 - could not mount device as ext2, vfat, or iso9660 3 - kickstart file named path not there */ int getKickstartFromBlockDevice(char *device, char *path) { #ifdef STACKI int rc; rc = getFileFromBlockDevice(device, path, "/tmp/ks.cfg"); /* * make sure /mnt/cdrom is the mount point for the Stacki bits */ if (!rc) { logMessage(INFO, "STACKI:getKickstartFromBlockDevice:trying to mount device %s", device); if (doPwMount(device, "/mnt/cdrom", "iso9660", "ro", NULL)) { logMessage(ERROR, "STACKI:start_httpd:doPwMount failed\n"); } } return(rc); #else return getFileFromBlockDevice(device, path, "/tmp/ks.cfg"); #endif }
int usbInitialize(moduleList modLoaded, moduleDeps modDeps, moduleInfoSet modInfo) { struct device ** devices; char * buf; int i; char * loadUsbStorage = NULL; if (FL_NOUSB(flags)) return 0; logMessage(INFO, "looking for usb controllers"); devices = probeDevices(CLASS_USB, BUS_PCI, 0); if (!devices) { logMessage(DEBUGLVL, "no usb controller found"); return 0; } /* JKFIXME: if we looked for all of them, we could batch this up and it * would be faster */ for (i=0; devices[i]; i++) { if (!devices[i]->driver) continue; logMessage(INFO, "found USB controller %s", devices[i]->driver); if (mlLoadModuleSet(devices[i]->driver, modLoaded, modDeps, modInfo)) { /* dont return, just keep going. */ /* may have USB built into kernel */ /* return 1; */ } } free(devices); if (FL_TESTING(flags)) return 0; if (doPwMount("/proc/bus/usb", "/proc/bus/usb", "usbfs", 0, NULL)) logMessage(ERROR, "failed to mount device usbfs: %s", strerror(errno)); /* sleep so we make sure usb devices get properly enumerated. that way we should block when initializing each usb driver until the device is ready for use */ sleepUntilUsbIsStable(); if (!FL_NOUSBSTORAGE(flags)) { devices = probeDevices(CLASS_HD | CLASS_FLOPPY | CLASS_CDROM, BUS_USB, PROBE_ALL); if (devices) { if (FL_UB(flags)) loadUsbStorage = ":ub"; else loadUsbStorage = ":usb-storage"; free(devices); } } buf = alloca(40); sprintf(buf, "hid:keybdev%s", (loadUsbStorage ? loadUsbStorage : "")); mlLoadModuleSet(buf, modLoaded, modDeps, modInfo); sleep(1); return 0; }
int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { char * host = NULL, *path = NULL, * file = NULL, * opts = NULL; char * chk = NULL, *ip = NULL; int failed = 0; iface_t iface; if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "unable to bring up network"); return 1; } /* if they just did 'linux ks', they want us to figure it out from * the dhcp/bootp information */ /* XXX: fixme NetworkManager integration */ /* if (url == NULL) { char ret[47]; ip_addr_t *tip; if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) { logMessage(ERROR, "no bootserver was found"); return 1; } tip = &(netCfg.dev.nextServer); if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); if (asprintf(&url, "%s:%s", ret, "/kickstart/") == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } logMessage(ERROR, "bootp: no bootfile received"); } else { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); if (asprintf(&url, "%s:%s", ret, netCfg.dev.bootFile) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile); } } */ /* get the IP of the target system */ if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) { logMessage(ERROR, "nl_ip2str returned NULL"); return 1; } logMessage(INFO, "url is %s", url); getHostandPath(url, &host, &path, ip); opts = strchr(host, ':'); if (opts && (strlen(opts) > 1)) { char * c = opts; opts = host; host = c + 1; *c = '\0'; } else { opts = NULL; } /* nfs has to be a little bit different... split off the last part as * the file and then concatenate host + dir path */ file = strrchr(path, '/'); if (!file) { file = path; } else { *file++ ='\0'; chk = host + strlen(host)-1; if (*chk == '/' || *path == '/') { if (asprintf(&host, "%s%s", host, path) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } } else { if (asprintf(&host, "%s/%s", host, path) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } } } logMessage(INFO, "file location: nfs:%s/%s", host, file); if (!doPwMount(host, "/tmp/mnt", "nfs", opts, NULL)) { char * buf; if (asprintf(&buf, "/tmp/mnt/%s", file) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } if (copyFile(buf, dest)) { logMessage(ERROR, "failed to copy file to %s", dest); failed = 1; } free(buf); } else { logMessage(ERROR, "failed to mount nfs source"); failed = 1; } free(host); free(path); if (ip) free(ip); umount("/tmp/mnt"); unlink("/tmp/mnt"); return failed; }
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; }
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; }
int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { char ret[47]; char * host = NULL, *path = NULL, * file = NULL, * opts = NULL; int failed = 0; struct networkDeviceConfig netCfg; ip_addr_t *tip, *u; if (kickstartNetworkUp(loaderData, &netCfg)) { logMessage(ERROR, "unable to bring up network"); return 1; } /* if they just did 'linux ks', they want us to figure it out from * the dhcp/bootp information */ if (url == NULL) { if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) { logMessage(ERROR, "no bootserver was found"); return 1; } tip = &(netCfg.dev.nextServer); if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); url = sdupprintf("%s:%s", ret, "/kickstart/"); logMessage(ERROR, "bootp: no bootfile received"); } else { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); url = sdupprintf("%s:%s", ret, netCfg.dev.bootFile); logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile); } } /* get the IP of the target system */ if (FL_HAVE_CMSCONF(flags)) { if (loaderData->ip == NULL) { logMessage(ERROR, "getFileFromNfs: no client IP information"); return 1; } else { sprintf(ret, "%s", loaderData->ip); } } else { tip = &(netCfg.dev.ipv4); u = &(netCfg.dev.ip); if ((inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)) == NULL) && (inet_ntop(u->sa_family, IP_ADDR(u), ret, IP_STRLEN(u)) == NULL)) { logMessage(ERROR, "getFileFromNfs: no client IP information"); return 1; } } logMessage(INFO, "url is %s", url); getHostandPath(url, &host, &path, ret); opts = strchr(host, ':'); if (opts && (strlen(opts) > 1)) { char * c = opts; opts = host; host = c + 1; *c = '\0'; } else { opts = NULL; } /* nfs has to be a little bit different... split off the last part as * the file and then concatenate host + dir path */ file = strrchr(path, '/'); if (!file) { file = path; } else { *file++ ='\0'; host = sdupprintf("%s/%s", host, path); } logMessage(INFO, "file location: nfs://%s/%s", host, file); if (!doPwMount(host, "/tmp/mnt", "nfs", IMOUNT_RDONLY, opts)) { char * buf; buf = alloca(strlen(file) + 10); sprintf(buf, "/tmp/mnt/%s", file); if (copyFile(buf, dest)) { logMessage(ERROR, "failed to copy file to %s", dest); failed = 1; } } else { logMessage(ERROR, "failed to mount nfs source"); failed = 1; } umount("/tmp/mnt"); unlink("/tmp/mnt"); return failed; }
/* given a partition device and directory, tries to mount hd install image */ static char * setupIsoImages(char * device, char * dirName, char * location) { int rc = 0; char *url = NULL, *dirspec, *updpath, *path; logMessage(INFO, "mounting device %s for hard drive install", device); if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL)) return NULL; checked_asprintf(&dirspec, "/mnt/isodir%.*s", (int) (strrchr(dirName, '/') - dirName), dirName); checked_asprintf(&path, "/mnt/isodir%s", dirName); if (path) { logMessage(INFO, "Path to stage2 image is %s", path); rc = copyFile(path, "/tmp/install.img"); rc = mountStage2("/tmp/install.img"); free(path); if (rc) { umountLoopback("/mnt/runtime", "/dev/loop0"); umount("/mnt/isodir"); goto err; } checked_asprintf(&updpath, "%s/updates.img", dirspec); logMessage(INFO, "Looking for updates for HD in %s", updpath); copyUpdatesImg(updpath); free(updpath); checked_asprintf(&updpath, "%s/product.img", dirspec); logMessage(INFO, "Looking for product for HD in %s", updpath); copyProductImg(updpath); free(updpath); free(dirspec); umount("/mnt/isodir"); checked_asprintf(&url, "hd:%s:/%s", device, dirName ? dirName : "."); return url; } else { free(dirspec); free(path); if (rc) { umount("/mnt/isodir"); return NULL; } } err: newtWinMessage(_("Error"), _("OK"), _("An error occured finding the installation image " "on your hard drive. Please check your images and " "try again.")); return NULL; }
/* set up a cdrom, nominally for installation * * location: where to mount the cdrom at JKFIXME: ignored * interactive: whether or not to prompt about questions/errors (1 is yes) * * loaderData is the kickstart info, can be NULL meaning no info * * requirepkgs=1 means CD should have packages, otherwise we just find stage2 * * side effect: found cdrom is mounted as /mnt/source. stage2 mounted * as /mnt/runtime. */ char * setupCdrom(char * location, struct loaderData_s * loaderData, moduleInfoSet modInfo, moduleList modLoaded, moduleDeps modDeps, int interactive, int requirepkgs) { int i, r, rc; int foundinvalid = 0; int stage2inram = 0; char * buf; char *stage2img; struct device ** devices; devices = probeDevices(CLASS_CDROM, BUS_UNSPEC, 0); if (!devices) { logMessage(ERROR, "got to setupCdrom without a CD device"); return NULL; } /* JKFIXME: ASSERT -- we have a cdrom device when we get here */ do { for (i = 0; devices[i]; i++) { if (!devices[i]->device) continue; logMessage(INFO,"trying to mount CD device %s", devices[i]->device); if (devMakeInode(devices[i]->device, "/tmp/cdrom") != 0) { logMessage(ERROR, "unable to create device node for %s", devices[i]->device); continue; } if (!doPwMount("/tmp/cdrom", "/mnt/source", "iso9660", IMOUNT_RDONLY, NULL)) { if (!access("/mnt/source/images/stage2.img", R_OK) && (!requirepkgs || !access("/mnt/source/.discinfo", R_OK))) { /* if in rescue mode lets copy stage 2 into RAM so we can */ /* free up the CD drive and user can have it avaiable to */ /* aid system recovery. */ if (FL_RESCUE(flags) && !FL_TEXT(flags) && totalMemory() > 128000) { rc = copyFile("/mnt/source/images/stage2.img", "/tmp/ramfs/stage2.img"); stage2img = "/tmp/ramfs/stage2.img"; stage2inram = 1; } else { stage2img = strdup("/mnt/source/images/stage2.img"); stage2inram = 0; } rc = mountStage2(stage2img); /* if we failed, umount /mnt/source and keep going */ if (rc) { logMessage(INFO, "mounting stage2 failed"); umount("/mnt/source"); if (rc == -1) foundinvalid = 1; continue; } /* do the media check */ queryCDMediaCheck(devices[i]->device); /* if in rescue mode and we copied stage2 to RAM */ /* we can now unmount the CD */ if (FL_RESCUE(flags) && stage2inram) { umount("/mnt/source"); unlink("/tmp/cdrom"); } r = asprintf(&buf, "cdrom://%s:/mnt/source", devices[i]->device); if (r == -1) return NULL; else return buf; } /* this wasnt the CD we were looking for, clean up and */ /* try the next CD drive */ umount("/mnt/source"); } } if (interactive) { char * buf; if (foundinvalid) buf = sdupprintf(_("No %s CD was found which matches your " "boot media. Please insert the %s CD " "and press %s to retry."), getProductName(), getProductName(), _("OK")); else buf = sdupprintf(_("The %s CD was not found in any of your " "CDROM drives. Please insert the %s CD " "and press %s to retry."), getProductName(), getProductName(), _("OK")); if (!FL_NOEJECT(flags)) { ejectCdrom(); unlink("/tmp/cdrom"); } else { logMessage(INFO, "noeject in effect, not ejecting cdrom"); } rc = newtWinChoice(_("CD Not Found"), _("OK"), _("Back"), buf, _("OK")); free(buf); if (rc == 2) return NULL; } else { /* we can't ask them about it, so just return not found */ return NULL; } } while (1); return NULL; }