📄 modules.c
字号:
strcpy(buf2, "scsi_hostadapter "); scsiNum++; strcat(buf, buf2); strcat(buf, lm->name); strcat(buf, "\n"); ret = write(fd, buf, strlen(buf)); lm->written = 1; break; case DRIVER_NET: switch(lm->minor) { case DRIVER_MINOR_ETHERNET: tmp = "eth"; break; case DRIVER_MINOR_TR: tmp = "tr"; break; default: logMessage(WARNING, "got net driver that's not ethernet or tr"); tmp = ""; } if (lm->firstDevNum > lm->lastDevNum) break; for (ethNum = lm->firstDevNum; ethNum <= lm->lastDevNum; ethNum++) { sprintf(buf2, "%s%d ", tmp, ethNum); if (ethNum != lm->lastDevNum) { strcat(buf2, lm->name); strcat(buf2, "\nalias "); } strcat(buf, buf2); } strcat(buf, lm->name); strcat(buf, "\n"); ret = write(fd, buf, strlen(buf)); lm->written = 1; break; default: break; } } if (lm->args) { strcpy(buf, "options "); strcat(buf, lm->name); for (arg = lm->args; *arg; arg++) { strcat(buf, " "); strcat(buf, *arg); } strcat(buf, "\n"); ret = write(fd, buf, strlen(buf)); lm->written = 1; } } close(fd); return 0;}/* writes out /tmp/scsidisks with a scsi disk / module correspondence. * format is sd%c adapter */void writeScsiDisks(moduleList list) { int i, fd, num, ret; struct loadedModuleInfo * lm; char buf[512]; if (!list) return; if ((fd = open("/tmp/scsidisks", O_WRONLY | O_CREAT, 0666)) == -1) { logMessage(ERROR, "error opening /tmp/scsidisks: %s", strerror(errno)); return; } for (i = 0, lm = list->mods; i < list->numModules; i++, lm++) { if (!lm->weLoaded) continue; if (lm->major != DRIVER_SCSI) continue; for (num = lm->firstDevNum; num < lm->lastDevNum; num++) { if (num < 26) sprintf(buf, "sd%c\t%s\n", 'a' + num, lm->name); else { unsigned int one, two; one = num / 26; two = num % 26; sprintf(buf, "sd%c%c\t%s\n", 'a' + one - 1, 'a' + two, lm->name); } ret = write(fd, buf, strlen(buf)); } } close(fd); return;}char * getModuleLocation(int version) { struct utsname u; static char * arch = NULL; const char * archfile = "/etc/arch"; char * ret; int rc; uname(&u); if (!arch && !access(archfile, R_OK)) { struct stat sb; int fd; stat(archfile, &sb); arch = malloc(sb.st_size + 1); fd = open(archfile, O_RDONLY); rc = read(fd, arch, sb.st_size); if (arch[sb.st_size -1 ] == '\n') sb.st_size--; arch[sb.st_size] = '\0'; close(fd); } else if (!arch) { logMessage(WARNING, "can't find arch file %s, defaulting to %s", archfile, u.machine); arch = strdup(u.machine); } if (version == 1) { ret = malloc(strlen(u.release) + strlen(arch) + 2); sprintf(ret, "%s/%s", u.release, arch); } else { ret = malloc(strlen(u.release) + 1); strcpy(ret, u.release); } logMessage(DEBUGLVL, "getModuleLocation: %s", ret); return ret;}/* JKFIXME: needs a way to know about module locations. also, we should * extract them to a ramfs instead of /tmp */static struct extractedModule * extractModules (char * const * modNames, struct extractedModule * oldPaths, struct moduleBallLocation * location) { gzFile fd; char * ballPath; struct cpioFileMapping * map; int i, numMaps, rc; char * const * m; char fn[255]; const char * failedFile; struct stat sb; char * modpath; if (!location) { ballPath = strdup("/modules/modules.cgz"); modpath = getModuleLocation(CURRENT_MODBALLVER); } else { ballPath = strdup(location->path); modpath = getModuleLocation(location->version); } fd = gunzip_open(ballPath); if (!fd) { logMessage(ERROR, "failed to open %s", ballPath); free(ballPath); return NULL; } for(m = modNames, i = 0; *m; i++, m++); map = alloca(sizeof(*map) * i); memset(map, 0, sizeof(*map) * i); if (!oldPaths) /* +1 NULL to terminate the list */ oldPaths = calloc(i + 1, sizeof(*oldPaths)); for (m = modNames, i = 0, numMaps = 0; *m; m++, i++) { /* if we don't know the path of this module yet, "figure" it out */ if (!oldPaths[i].path) { map[numMaps].archivePath = alloca(strlen(modpath) + strlen(*m) + 25); sprintf(map[numMaps].archivePath, "%s/%s.ko", modpath, *m); map[numMaps].fsPath = alloca(10 + strlen(*m)); sprintf(map[numMaps].fsPath, "/tmp/%s.ko", *m); unlink(map[numMaps].fsPath); map[numMaps].mapFlags = CPIO_MAP_PATH; numMaps++; } } if (!numMaps) { gunzip_close(fd); free(ballPath); free(modpath); return oldPaths; } qsort(map, numMaps, sizeof(*map), myCpioFileMapCmp); rc = myCpioInstallArchive(fd, map, numMaps, NULL, NULL, &failedFile); gunzip_close(fd); for (m = modNames, i = 0, numMaps = 0; *m; m++, i++) { if (!oldPaths[i].path) { sprintf(fn, "/tmp/%s.ko", modNames[i]); if (!stat(fn, &sb)) { oldPaths[i].path = strdup(fn); /* JKFIXME: this is copied from the old stuff -- do we really need it? */ if (location && location->path) { oldPaths[i].location = strdup(location->path); if (location->title) logMessage(INFO, "module %s found on driver disk %s", modNames[i], location->title); logMessage(INFO, "loaded %s from %s", modNames[i], location->path); } else logMessage(INFO, "loaded %s from /modules/modules.cgz", modNames[i]); } numMaps++; } } free(ballPath); free(modpath); return oldPaths;}/* remove a module which has been loaded, including removal from the * modLoaded struct */int removeLoadedModule(const char * modName, moduleList modLoaded) { int status, rc = 0; pid_t child; struct loadedModuleInfo * mod; mod = getLoadedModuleInfo(modLoaded, modName); if (!mod) return 0; /* since we're unloading, set the devs to 0. this should hopefully only * ever happen with things at the end */ mod->firstDevNum = 0; mod->lastDevNum = 0; if (FL_TESTING(flags)) { logMessage(INFO, "would have rmmod %s", modName); rc = 0; } else { logMessage(INFO, "going to rmmod %s", modName); if (!(child = fork())) { int fd = open("/dev/tty3", O_RDWR); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); execl("/sbin/rmmod", "/sbin/rmmod", modName, NULL); _exit(rc); } waitpid(child, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status)) { rc = 1; } else { int found = -1; int i; /* find our module. once we've found it, shutffle everything * else back one */ for (i = 0; i < modLoaded->numModules; i++) { if (found > -1) { modLoaded->mods[i - 1] = modLoaded->mods[i]; } else if (!strcmp(modLoaded->mods[i].name, modName)) { found = i; free(modLoaded->mods[i].name); free(modLoaded->mods[i].path); } } modLoaded->numModules--; rc = 0; } } return rc;}void loadKickstartModule(struct loaderData_s * loaderData, int argc, char ** argv) { char * opts = NULL; char * module = NULL; char * type = NULL; char ** args = NULL; poptContext optCon; int rc; struct poptOption ksDeviceOptions[] = { { "opts", '\0', POPT_ARG_STRING, &opts, 0, NULL, NULL }, { 0, 0, 0, 0, 0, 0, 0 } }; optCon = poptGetContext(NULL, argc, (const char **) argv, ksDeviceOptions, 0); if ((rc = poptGetNextOpt(optCon)) < -1) { startNewt(); newtWinMessage(_("Kickstart Error"), _("OK"), _("Bad argument to device kickstart method " "command %s: %s"), poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); return; } type = (char *) poptGetArg(optCon); module = (char *) poptGetArg(optCon); if (!type || !module) { startNewt(); newtWinMessage(_("Kickstart Error"), _("OK"), _("Both module type and name must be specified for " "the kickstart device command.")); return; } if (opts) { int numAlloced = 5, i = 0; char * start; char * end; args = malloc((numAlloced + 1) * sizeof(args)); start = opts; while (start && *start) { end = start; while (!isspace(*end) && *end) end++; *end = '\0'; (args)[i++] = strdup(start); start = end + 1; *end = ' '; start = strchr(end, ' '); if (start) start++; if (i >= numAlloced) { numAlloced += 5; args = realloc(args, sizeof(args) * (numAlloced + 1)); } } args[i] = NULL; } mlLoadModule(module, loaderData->modLoaded, *(loaderData->modDepsPtr), loaderData->modInfo, args);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -