⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modules.c

📁 linux 安装程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * modules.c - module loading functionality * * Erik Troan <ewt@redhat.com> * Matt Wilson <msw@redhat.com> * Michael Fulbright <msf@redhat.com> * Jeremy Katz <katzj@redhat.com> * * Copyright 1999 - 2003 Red Hat, Inc. * * This software may be freely redistributed under the terms of the GNU * General Public License. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <kudzu/kudzu.h>#include <newt.h>#include <popt.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/utsname.h>#include <sys/wait.h>#include <unistd.h>#include "loader.h"#include "log.h"#include "modules.h"#include "modstubs.h"#include "windows.h"#include "usb.h"#include "../isys/cpio.h"/* boot flags */extern int flags;static int writeModulesConf(moduleList list, char *conf);static struct extractedModule * extractModules (char * const * modNames,                                                struct extractedModule * oldPaths,                                                struct moduleBallLocation * location);/* pass in the type of device (eth or tr) that you're looking for */static int ethCount(const char * type) {    int fd;    char buf[16384];    int i;    char * chptr;    int count = 0;    fd = open("/proc/net/dev", O_RDONLY);    i = read(fd, buf, sizeof(buf) - 1);    buf[i] = '\0';    /* skip first two header lines */    chptr = strchr(buf, '\n') + 1;    chptr = strchr(chptr, '\n') + 1;    while (chptr) {        while (*chptr && isspace(*chptr)) chptr++;        if (!strncmp(chptr, type, strlen(type)))            count++;        chptr = strchr(chptr, '\n');        if (chptr) chptr++;    }    return count;}static int scsiCount(char *conf) {    FILE *f;    int count = 0;        f = fopen(conf, "r");    if (!f)        return 0;    do {        char *buf = NULL;        size_t n = 0;        if (getline(&buf, &n, f) < 0)            break;        if (!strncmp(buf, "alias scsi_hostadapter", 22))            count++;        free(buf);    } while (1);    fclose(f);    return count;}static int scsiDiskCount(void) {    struct device ** devices;    int i = 0;    devices = probeDevices(CLASS_HD, BUS_SCSI, PROBE_LOADED);    if (devices) {        for (; devices[i]; i++);        free(devices);    }    /* have to probe for usb floppies too */    devices = probeDevices(CLASS_FLOPPY, BUS_SCSI, PROBE_LOADED);    if (devices) {        for (; devices[i]; i++);        free(devices);    }    /* have to probe for usb cdrom too */    devices = probeDevices(CLASS_CDROM, BUS_SCSI, PROBE_LOADED);    if (devices) {        for (; devices[i]; i++);        free(devices);    }    return i;}int mlReadLoadedList(moduleList * mlp) {    int fd;    char * start;    char * end;    char buf[4096];    struct stat sb;    int i;    moduleList ml;    if ((fd = open("/proc/modules", O_RDONLY)) < 0)        return -1;    fstat(fd, &sb);    i = read(fd, buf, sizeof(buf));    buf[i] = '\0';    close(fd);    ml = malloc(sizeof(*ml));    ml->numModules = 0;    start = buf;    while (start && *start) {        end = start;        while (!isspace(*end) && *end != '\n') end++;        *end = '\0';        ml->mods[ml->numModules].name = strdup(start);        ml->mods[ml->numModules].args = NULL;        ml->mods[ml->numModules].path = NULL;        ml->mods[ml->numModules].weLoaded = 0;        *end = ' ';        ml->numModules++;        start = strchr(end, '\n');        if (start) start++;    }    *mlp = ml;    return 0;}/* this leaks memory if their is a loop in the modules. oh well. */char ** tsortModules(moduleList modLoaded, moduleDeps ml, char ** args,                      int depth, char *** listPtr, int * listSizePtr) {    int listSize;    char ** list;    char ** next;    char ** deps;        if (!depth) {        int count;        listSize = 5;        list = malloc((listSize + 1) * sizeof(*list));        *list = NULL;        listPtr = &list;        listSizePtr = &listSize;        for (deps = args, count = 0; *deps; deps++, count++);    } else {        list = *listPtr;        listSize = *listSizePtr;    }    if (depth++ > 100) {        return NULL;    }    while (*args) {        /* don't load it twice */        next = list;        while (*next && strcmp(*next, *args)) next++;        if (*next || mlModuleInList(*args, modLoaded)) {            args++;            continue;        }        /* load everything this depends on */        deps = mlGetDeps(ml, *args);        if (deps) {            if (!tsortModules(modLoaded, ml, deps, depth,                               listPtr, listSizePtr))                return NULL;                        list = *listPtr;            listSize = *listSizePtr;        }                   /* add this to the list */        next = list;        while (*next) next++;        if ((next - list) >= listSize) {            int count = next - list;            listSize += 10;            /* leave room for a NULL */            list = realloc(list, sizeof(*list) * (listSize + 1));            *listSizePtr = listSize;            *listPtr = list;            next = list + count;        }        next[0] = *args;        next[1] = NULL;        args++;    }    return list;}int mlModuleInList(const char * modName, moduleList list) {    int i;    if (!list) return 0;    for(i = 0; i < list->numModules; i++)         if (!strcmp(list->mods[i].name, modName)) return 1;    return 0;}static struct loadedModuleInfo * getLoadedModuleInfo(moduleList modLoaded,                                                      const char * modName) {    int i = 0;    for (i = 0; i < modLoaded->numModules; i++)         if (!strcmp(modLoaded->mods[i].name, modName))            return &modLoaded->mods[i];        return NULL;}/* load a single module.  this is the real workhorse of loading modules */static int loadModule(const char * modName, struct extractedModule * path,                      moduleList modLoaded, char ** args,                       moduleInfoSet modInfo) {    char fileName[300];    char ** argPtr, ** newArgs, ** arg;    struct moduleInfo * mi = NULL;    int deviceCount = -1;    int popWindow = 0;    int rc, child, i, status;    static int usbWasLoaded = 0;     /* don't need to load a module that's already loaded */    if (mlModuleInList(modName, modLoaded))        return 0;    if (modInfo && (mi = findModuleInfo(modInfo, modName))) {        if ((mi->major == DRIVER_NET) && (mi->minor == DRIVER_MINOR_ETHERNET)) {            deviceCount = ethCount("eth");        } else if ((mi->major == DRIVER_NET) && (mi->minor == DRIVER_MINOR_TR)) {            deviceCount = ethCount("tr");        }        if (mi->major == DRIVER_SCSI) {            deviceCount = scsiDiskCount();            if (!FL_CMDLINE(flags)) {                startNewt();                scsiWindow(modName);                popWindow = 1;            }        }    }    if (!strcmp(modName, "libata") && FL_IGNOREHPA(flags)) {        logMessage(INFO, "Ignoring host protected area");        args = malloc(sizeof(*args) * 2);        args[0] = strdup("ignore_hpa=1");        args[1] = NULL;    }    sprintf(fileName, "%s.ko", modName);    for (argPtr = args; argPtr && *argPtr; argPtr++) {        strcat(fileName, " ");        strcat(fileName, *argPtr);    }    if (FL_TESTING(flags)) {        logMessage(INFO, "would have insmod %s (%s)", path->path, fileName);        rc = 0;    } else {        if (!(child = fork())) {            int fd = open("/dev/tty3", O_RDWR);            dup2(fd, 0);            dup2(fd, 1);            dup2(fd, 2);            close(fd);                        rc = insmod(path->path, NULL, args);            _exit(rc);        }        waitpid(child, &status, 0);        if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {            rc = 1;        } else {            rc = 0;        }    }    if (!rc) {        int num = modLoaded->numModules;        modLoaded->mods[num].name = strdup(modName);        modLoaded->mods[num].weLoaded = 1;        modLoaded->mods[num].path =            path->location ? strdup(path->location) : NULL;        modLoaded->mods[num].firstDevNum = -1;        modLoaded->mods[num].lastDevNum = -1;        modLoaded->mods[num].written = 0;                if (mi) {            modLoaded->mods[num].major = mi->major;            modLoaded->mods[num].minor = mi->minor;                        if (deviceCount >= 0) {                if ((mi->major == DRIVER_NET) &&                     (mi->minor == DRIVER_MINOR_ETHERNET)) {                    modLoaded->mods[num].firstDevNum = deviceCount;                    modLoaded->mods[num].lastDevNum = ethCount("eth") - 1;                } else if ((mi->major == DRIVER_NET) &&                            (mi->minor == DRIVER_MINOR_TR)) {                    modLoaded->mods[num].firstDevNum = deviceCount;                    modLoaded->mods[num].lastDevNum = ethCount("tr") - 1;                } else if (mi->major == DRIVER_SCSI) {                    /* FIXME: this is a hack, but usb-storage seems to                     * like to take forever to enumerate.  try to                      * give it some time */                    if (!strcmp(modName, "usb-storage") && !usbWasLoaded) {                        int slp;                        usbWasLoaded = 1;                        for (slp = 0; slp < 10; slp++) {                            if (scsiDiskCount() > deviceCount) break;                            sleep(2);                        }                        logMessage(DEBUGLVL, "slept %d seconds", slp * 2);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -