📄 modules.c
字号:
} modLoaded->mods[num].firstDevNum = deviceCount; modLoaded->mods[num].lastDevNum = scsiDiskCount(); } } } else { modLoaded->mods[num].major = DRIVER_NONE; modLoaded->mods[num].minor = DRIVER_MINOR_NONE; } if (args) { for (i=0, arg = args; *arg; arg++, i++); newArgs = malloc(sizeof(*newArgs) * (i + 1)); for (i = 0, arg = args; *arg; arg++, i++) newArgs[i] = strdup(*arg); newArgs[i] = NULL; } else { newArgs = NULL; } modLoaded->mods[modLoaded->numModules++].args = newArgs; } if (popWindow) { sleep(1); newtPopWindow(); } return rc;}/* * This takes the list of modules we're going to load and sorts * some to be at the end on an arbitrary criteria (eg, fiberchannel). * This should help the problems where people's FC controller ends up being * sda and they then can't boot or otherwise have things being strange. * And yes, this is a hack. *sigh* */static char ** lateModuleSort(char **allmods, int num) { int i, j, k, l; char ** modList; /* the qlogic drivers are usually for fibrechannel according to coughlan * as is lpfc. ibmvscsic needs to be sure to be loaded after ipr on * power5 due to bug #137920 */ char * lateList[] = { "qla2100", "qla2200", "qla2300", "qla2322", "qla6312", "qla6322", "qla2400", "qla2xxx", "lpfc", "ibmvscsic", "pata_pcmcia", NULL }; char ** lateMods; for (i=0; allmods[i]; i++) {} modList = malloc(sizeof(*modList) * (num + i + 1)); lateMods = alloca(sizeof(*lateMods) * 10); lateMods = memset(lateMods, 0, 10); i = j = k = l = 0; for (; allmods[i]; i++) { int late = 0; for (j = 0; lateList[j]; j++) { if (!strcmp(allmods[i], lateList[j])) { lateMods[l++] = allmods[i]; late = 1; break; } } if (!late) modList[k++] = allmods[i]; } for (i = 0; i < l; i++) { modList[k++] = lateMods[i]; } modList[k] = NULL; return modList;}/* handle loading a set of modules including their dependencies. also has * a nasty evil hack for handling usb-storage removal/reloading for scsi * device ordering. *//* JKFIXME: the location argument is a hack to handle modules * without module-info that I know need to be loaded from other than * /modules/modules.cgz. should module-info be extended to cover * *ALL* modules? this would probably want for auto module-info generation */static int doLoadModules(const char * origModNames, moduleList modLoaded, moduleDeps modDeps, moduleInfoSet modInfo, const char * argModule, char ** args, struct moduleBallLocation * modLocation) { char * modNames; char * start, * next, * end; char ** initialList; char ** list, ** l; char items[1024] = ""; /* 1024 characters should be enough... */ struct extractedModule * paths, * p; struct moduleBallLocation *location = NULL; struct loadedModuleInfo * mod; int i; int reloadUsbStorage; struct moduleInfo * mi; start = modNames = alloca(strlen(origModNames) + 1); strcpy(modNames, origModNames); next = start; i = 1; while (*next) { if (*next == ':') i++; next++; } initialList = alloca(sizeof(*initialList) * (i + 1)); i = 0; while (start) { next = end = strchr(start, ':'); if (next) { *end = '\0'; next++; } if (mlModuleInList(start, modLoaded)) { /* already loaded, we don't need to load it again */ start = next; continue; } initialList[i++] = start; start = next; } initialList[i] = NULL; list = tsortModules(modLoaded, modDeps, initialList, 0, NULL, NULL); if (!list) { logMessage(ERROR, "loop in module dependencies; not inserting"); return 1; } list = lateModuleSort(list, i); for (i = 0; list[i]; i++) { strcat(items, " "); strcat(items, list[i]); } logMessage(INFO, "modules to insert%s", items); paths = NULL; reloadUsbStorage = 0; if (modInfo) { for (i = 0; list[i]; i++) { mi = findModuleInfo(modInfo, list[i]); if (mi && mi->locationID) { location = mi->locationID; } if (mi && (mi->major == DRIVER_SCSI) && (mod = getLoadedModuleInfo(modLoaded, "usb-storage")) && (mod->firstDevNum != mod->lastDevNum)) { reloadUsbStorage = 1; } } } /* JKFIXME: this is a hack to handle an explicit location for modules */ if (!location && modLocation) location = modLocation; paths = extractModules(list, paths, location); i = 0; if (!paths) { logMessage(ERROR, "no modules found -- aborting insertion"); return i; } *items = '\0'; for (l = list, p = paths; *l && p; l++, p++) { if (!p->path) { if (*items) strcat(items, " "); strcat(items, *l); i++; } } if (*items) logMessage(DEBUGLVL, "module(s) %s not found", items); if (reloadUsbStorage) { mod = getLoadedModuleInfo(modLoaded, "usb-storage"); if (!mod) { fprintf(stderr, "ERROR: %s was in module list, but can't be found now", "usb-storage"); exit(1); } if (mod->lastDevNum != scsiDiskCount()) { logMessage(WARNING, "usb-storage isn't claiming the last scsi dev (%d vs %d)", modLoaded->mods[i].lastDevNum, scsiDiskCount()); /* JKFIXME: return? or not, because of firewire */ } /* here we need to save the state of stage2 */ removeLoadedModule("usb-storage", modLoaded); /* JKFIXME: here are the big hacks... for now, just described. * 1) figure out which scsi devs are claimed by usb-storage. * if lastScsiDev == usb-storage->lastDev, * lastScsiDev = usb->firstDev. else, log that we're screwed. * 2) if stage2 is cdrom and mounted, umount stage2, umount cdrom * 3) rmmod usb-storage */ } /* insert the modules now */ for(l = list, p = paths; paths && *l; l++, p++) { if (!p->path) /* no path for this module */ continue; if (loadModule(*l, p, modLoaded, (argModule && !strcmp(argModule, *l)) ? args : NULL, modInfo)) { logMessage(ERROR, "failed to insert %s", p->path); } else { logMessage(INFO, "inserted %s", p->path); } } if (reloadUsbStorage) { mlLoadModule("usb-storage", modLoaded, modDeps, modInfo, NULL); /* JKFIXME: here's the rest of the hacks. basically do the reverse * of what we did before. */ } if (!FL_TESTING(flags)) writeModulesConf(modLoaded, "/tmp/modprobe.conf"); for (p = paths; p->path; p++) { unlink(p->path); free(p->path); if (p->location) free(p->location); } free(paths); free(list); logMessage(INFO, "load module set done"); return i;}/* load a module with a given list of arguments */int mlLoadModule(const char * module, moduleList modLoaded, moduleDeps modDeps, moduleInfoSet modInfo, char ** args) { return doLoadModules(module, modLoaded, modDeps, modInfo, module, args, NULL);}/* loads a : separated list of modules */int mlLoadModuleSet(const char * modNames, moduleList modLoaded, moduleDeps modDeps, moduleInfoSet modInfo) { return doLoadModules(modNames, modLoaded, modDeps, modInfo, NULL, NULL, NULL);}static int removeHostAdapter(char *conf, char *name) { FILE *in = NULL, *out = NULL; int nhbas = 0; char *newconf = NULL; int ret = 0; if (asprintf(&newconf, "%s.new", conf) < 0) return ret; if (!(out = fopen(newconf, "w+"))) { free(newconf); return ret; } if (!(in = fopen(conf, "r"))) { fclose(out); unlink(newconf); free(newconf); return ret; } do { size_t n = 0; char *buf = NULL; int d = 0, m = 0; if (getline(&buf, &n, in) < 0) break; if (ret || strncmp(buf, "alias scsi_hostadapter", 22)) { fputs(buf, out); free(buf); continue; } if (buf[22] != ' ') sscanf(buf+22, "%d %n", &d, &m); else sscanf(buf+22, " %n", &m); if (!ret) { if (strncmp(buf+22+m, name, strlen(name))) { if (nhbas) fprintf(out, "alias scsi_hostadapter%d %s", nhbas, buf+22+m); else fprintf(out, "alias scsi_hostadapter %s", buf+22+m); nhbas++; } else { logMessage(INFO, "removed usb-storage from modprobe.conf"); ret++; } } free(buf); } while (1); fclose(in); fclose(out); unlink(conf); rename(newconf, conf); free(newconf); return ret;}static int writeModulesConf(moduleList list, char *conf) { int i, ret; struct loadedModuleInfo * lm; int ethNum; int scsiNum; char buf[16384], buf2[512]; /* these will be enough for anyone... */ char * tmp, ** arg; int fd; static int once = 0; if (!once) once = removeHostAdapter(conf, "usb-storage"); scsiNum = scsiCount(conf); if (!list) return 0; fd = open("/tmp/modprobe.conf", O_WRONLY | O_CREAT | O_APPEND, 0666); if (fd == -1) { logMessage(ERROR, "error appending to /tmp/modprobe.conf: %s\n", strerror(errno)); return 0; } for (i = 0, lm = list->mods; i < list->numModules; i++, lm++) { if (!lm->weLoaded) continue; if (lm->written) continue; if (lm->major != DRIVER_NONE) { strcpy(buf, "alias "); switch (lm->major) { case DRIVER_SCSI: /* originally set to # of scsi_hostadapter already in * /tmp/modprobe.conf. then we increment ourselves */ if (scsiNum) sprintf(buf2, "scsi_hostadapter%d ", scsiNum); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -