summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Nottingham <notting@redhat.com>2007-12-19 14:58:02 -0500
committerBill Nottingham <notting@redhat.com>2007-12-19 14:58:02 -0500
commitd209bc9a3dadcc666fd365f431eb40bce5e75e66 (patch)
treee55359cedf6dc7a234415d8a3f31a3d8ae553adb
parentc5f05bd14aafee4bbca5627ae84c77f3abb83340 (diff)
downloadanaconda-d209bc9a3dadcc666fd365f431eb40bce5e75e66.tar.gz
anaconda-d209bc9a3dadcc666fd365f431eb40bce5e75e66.tar.xz
anaconda-d209bc9a3dadcc666fd365f431eb40bce5e75e66.zip
Don't handle all aspects of module loading ourselves - just wrap modprobe.
This includes: - removal of the moddeps code - removal of the module list tracking For handling passed options in the installed system, write a /etc/modprobe.d files with: 1) any options passed on the installer command line 2) any modules blacklisted via the command line 3) any options directly specified for modules
-rw-r--r--loader2/modstubs.c269
-rw-r--r--loader2/modstubs.h28
-rw-r--r--loader2/moduledeps.c202
-rw-r--r--loader2/moduledeps.h34
-rw-r--r--loader2/modules.c1151
-rw-r--r--loader2/modules.h42
6 files changed, 165 insertions, 1561 deletions
diff --git a/loader2/modstubs.c b/loader2/modstubs.c
deleted file mode 100644
index bfd7d8b85..000000000
--- a/loader2/modstubs.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * modstubs.c - stubs around modutils commands
- *
- * Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@redhat.com>
- * Matt Wilson <msw@redhat.com>
- * Michael Fulbright <msf@redhat.com>
- * Jeremy Katz <katzj@redhat.com>
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-
-#include "log.h"
-#include "modstubs.h"
-#include "modules.h"
-
-#include "../isys/cpio.h"
-#include "../isys/stubs.h"
-
-extern long init_module(void *, unsigned long, const char *);
-extern long delete_module(const char *, unsigned int);
-
-static int usage() {
- fprintf(stderr, "usage: insmod [-p <path>] <module>.ko\n");
- return 1;
-}
-
-static int rmmod_usage() {
- fprintf(stderr, "usage: rmmod <module>\n");
- return 1;
-}
-
-static char * extractModule(char * file, char * ballPath, int version,
- int *rmObj) {
- gzFile fd;
- /* Make finaleName and fullName REALLY static, otherwise they get dropped
- from the stack after the function returns and the addresses are no
- longer valid. */
- static char finalName[100], fullName[100];
- char * chptr = NULL;
- char *loc = NULL;
-
- if (access(file, R_OK)) {
- /* it might be having a ball */
- fd = gunzip_open(ballPath);
- if (!fd)
- return NULL;
-
- chptr = strrchr(file, '/');
- if (chptr) file = chptr + 1;
- sprintf(finalName, "/tmp/%s", file);
-
- loc = getModuleLocation(version);
- sprintf(fullName, "%s/%s", loc, file);
- free(loc);
-
- int ret = installCpioFile(fd, fullName, finalName, 0);
- gunzip_close(fd);
- if (ret)
- return NULL;
-
- *rmObj = 1;
- file = finalName;
- }
-
- return file;
-}
-
-int ourInsmodCommand(int argc, char ** argv) {
- char * file;
- int rc, rmObj = 0;
- char * ballPath = NULL;
- int version = 1;
- int fd;
- void * modbuf = NULL;
- struct stat sb;
- int i;
- char *options = NULL, *tmp = NULL;
-
- if (argc < 2) {
- return usage();
- }
-
- while (argc > 2) {
- if (!strcmp(argv[1], "-p")) {
- ballPath = malloc(strlen(argv[2]) + 30);
- if (!ballPath) {
- logMessage(ERROR, "cannot allocate memory for ballPath: %m");
- return 1;
- }
- sprintf(ballPath, "%s/modules.cgz", argv[2]);
- argv += 2;
- argc -= 2;
- } else if (!strcmp(argv[1], "--modballversion")) {
- version = atoi(argv[2]);
- argv += 2;
- argc -= 2;
- } else if (!strncmp(argv[1], "-", 1)) { /* ignore all other options */
- argc -= 1;
- argv += 1;
- } else {
- break;
- }
- }
-
- if (!ballPath) {
- ballPath = strdup("/modules/modules.cgz");
- }
-
- file = extractModule(argv[1], ballPath, version, &rmObj);
- free(ballPath);
-
- if (file == NULL)
- return 1;
-
- if (stat(file, &sb) == -1) {
- logMessage(ERROR, "unable to stat file %s: %s", file, strerror(errno));
- return 1;
- }
-
- fd = open(file, O_RDONLY);
- if (fd < 0) {
- logMessage(ERROR, "unable to open file %s: %s", file, strerror(errno));
- return 1;
- }
-
- modbuf = mmap(0, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
- if (modbuf == NULL) {
- logMessage(ERROR, "error reading file %s: %s", file, strerror(errno));
- close(fd);
- return 1;
- }
-
- options = strdup("");
- if (!options) {
- logMessage(ERROR, "cannot allocate memory for module options: %m");
- munmap(modbuf, sb.st_size);
- close(fd);
- return 1;
- }
- for (i = 2; i < argc; i++) {
- tmp = realloc(options, strlen(options) + 1 + strlen(argv[i]) + 1);
- if (!tmp) {
- logMessage(ERROR, "cannot allocate memory for module options: %m");
- free(options);
- munmap(modbuf, sb.st_size);
- close(fd);
- return 1;
- }
- options = tmp;
- strcat(options, argv[i]);
- strcat(options, " ");
- }
-
- while ((rc = init_module(modbuf, sb.st_size, options)) == -1 &&
- errno == EINTR)
- ;
- if (rc != 0)
- logMessage(WARNING, "failed to insert module (%d)", errno);
- free(options);
- munmap(modbuf, sb.st_size);
- close(fd);
- return rc;
-}
-
-int ourRmmodCommand(int argc, char ** argv) {
- if (argc < 2) {
- return rmmod_usage();
- }
-
- return rmmod(argv[1]);
-}
-
-static char * modNameMunge(char * mod) {
- unsigned int i;
-
- for (i = 0; mod[i]; i++) {
- if (mod[i] == '-')
- mod[i] = '_';
- }
- return mod;
-}
-
-int rmmod(char * modName) {
- pid_t child;
- int status;
- int rc = 0;
-
- modName = modNameMunge(modName);
- if ((child = fork()) == 0) {
- rc = delete_module(modName, O_NONBLOCK|O_EXCL);
- exit(rc);
- }
-
- waitpid(child, &status, 0);
-
- if (WIFEXITED(status))
- rc = WEXITSTATUS(status);
- else
- rc = -1;
-
- return rc;
-}
-
-int insmod(char * modName, char * path, char ** args) {
- int argc;
- char ** argv;
- int rc = 0;
- pid_t child;
- int status;
- int count;
-
- argc = 0;
- for (argv = args; argv && *argv; argv++, argc++);
-
- argv = alloca(sizeof(*argv) * (argc + 5));
- argv[0] = "/bin/insmod";
- count = 1;
- if (path) {
- argv[1] = "-p";
- argv[2] = path;
- count += 2;
- }
-
- argv[count] = modName;
- count++;
-
- if (args)
- memcpy(argv + count, args, sizeof(*args) * argc);
-
- argv[argc + count] = NULL;
-
- argc += count;
-
- if ((child = fork()) == 0) {
- exit(ourInsmodCommand(argc, argv));
- }
-
- waitpid(child, &status, 0);
-
- if (WIFEXITED(status))
- rc = WEXITSTATUS(status);
- else
- rc = -1;
-
- return rc;
-}
diff --git a/loader2/modstubs.h b/loader2/modstubs.h
deleted file mode 100644
index f66cc9eba..000000000
--- a/loader2/modstubs.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * modstubs.h
- *
- * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_MODSTUBS
-#define H_MODSTUBS
-
-int ourInsmodCommand(int argc, char ** argv);
-int ourRmmodCommand(int argc, char ** argv);
-int rmmod(char * modName);
-int insmod(char * modName, char * path, char ** args);
-
-#endif
diff --git a/loader2/moduledeps.c b/loader2/moduledeps.c
deleted file mode 100644
index e720beab4..000000000
--- a/loader2/moduledeps.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * moduledeps.c - module dependency determination
- *
- * Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@redhat.com>
- * Matt Wilson <msw@redhat.com>
- * Michael Fulbright <msf@redhat.com>
- * Jeremy Katz <katzj@redhat.com>
- */
-
-#include <alloca.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <newt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "moduledeps.h"
-
-moduleDeps mlNewDeps(void) {
- moduleDeps md;
-
- md = malloc(sizeof(*md));
- md->name = NULL;
- md->deps = NULL;
-
- return md;
-}
-
-/* JKFIXME: if we have a new module with different deps, this doesn't
- * handle it correctly */
-int mlLoadDeps(moduleDeps * moduleDepListPtr, const char * path) {
- int fd;
- char * buf;
- struct stat sb;
- char * start, * end, * chptr;
- int i, numItems;
- moduleDeps nextDep;
- moduleDeps moduleDepList = *moduleDepListPtr;
- int ret;
-
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- return -1;
- }
-
- fstat(fd, &sb);
- buf = alloca(sb.st_size + 1);
- ret = read(fd, buf, sb.st_size);
- buf[sb.st_size] = '\0';
- close(fd);
-
- start = buf;
- numItems = 0;
- while (start) {
- numItems++;
- start = strchr(start + 1, '\n');
- }
-
- for (nextDep = moduleDepList; nextDep->name; nextDep++) numItems++;
-
- moduleDepList = realloc(moduleDepList, sizeof(*moduleDepList) * numItems);
- for (nextDep = moduleDepList; nextDep->name; nextDep++) ;
-
- /* We have to remove `\' first. */
- start = buf;
- start = strchr(start, '\\');
- while (start) {
- /* Replace `\\' with a space. */
- *start++ = ' ';
- /* Replace the following `\n' and `\r' with a space. */
- if (*start == '\n') {
- *start++ = ' ';
- if (*start == '\r')
- *start++ = ' ';
- }
- else if (*start == '\r') {
- *start++ = ' ';
- if (*start == '\n')
- *start++ = ' ';
- }
- start = strchr(start, '\\');
-
- }
-
- start = buf;
- while (start < (buf + sb.st_size) && *start) {
- end = strchr(start, '\n');
- *end = '\0';
-
- chptr = strchr(start, ':');
- if (!chptr) {
- start = end + 1;
- continue;
- }
-
- *chptr++ = '\0';
- while (*chptr && isspace(*chptr)) chptr++;
- if (!*chptr) {
- start = end + 1;
- continue;
- }
-
- /* found something */
- nextDep->name = strdup(start);
- nextDep->deps = malloc(sizeof(char *) * (strlen(chptr) + 1));
- start = chptr, i = 0;
- while (start && *start) {
- chptr = strchr(start, ' ');
- if (chptr) *chptr = '\0';
- nextDep->deps[i++] = strdup(start);
- if (chptr)
- start = chptr + 1;
- else
- start = NULL;
- while (start && *start && isspace(*start)) start++;
- }
- nextDep->deps[i] = NULL;
- nextDep->deps = realloc(nextDep->deps, sizeof(char *) * (i + 1));
- nextDep++;
-
- start = end + 1;
- }
-
- nextDep->name = NULL;
- nextDep->deps = NULL;
- moduleDepList = realloc(moduleDepList, sizeof(*moduleDepList) *
- (nextDep - moduleDepList + 1));
-
- *moduleDepListPtr = moduleDepList;
-
- return 0;
-}
-
-char ** mlGetDeps(moduleDeps modDeps, const char * modName) {
- moduleDeps dep;
-
- for (dep = modDeps; dep && dep->name && strcmp(dep->name, modName); dep++);
-
- if (dep) return dep->deps;
-
- return NULL;
-}
-
-/* fun test cases... */
-#ifdef TESTING
-
-void printDeps(moduleDeps modDeps) {
- moduleDeps dep;
- char buf[1024];
- char **foo;
-
- for (dep = modDeps; dep && dep->name; dep++) {
- if (strcmp(dep->name, "pcnet32"))
- continue;
- if (!dep->deps)
- printf("module: %s, no deps\n", dep->name);
- else {
- buf[0] = '\0';
- for (foo = dep->deps; *foo; foo++) {
- strcat(buf, *foo);
- strcat(buf, " ");
- }
- printf("module: %s, deps: %s\n", dep->name, buf);
- }
- }
-}
-
-int main(int argc, char ** argv) {
- moduleDeps deps;
-
- deps = mlNewDeps();
- printDeps(deps);
- mlLoadDeps(&deps, "modules.dep.1");
- printDeps(deps);
-
- printf("----------------------------------------\n");
- printf("Loading second set\n");
- mlLoadDeps(&deps, "modules.dep.2");
- printDeps(deps);
-
- return 0;
-}
-#endif
diff --git a/loader2/moduledeps.h b/loader2/moduledeps.h
deleted file mode 100644
index e33cdc768..000000000
--- a/loader2/moduledeps.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * moduledeps.h
- *
- * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MODULEDEPS_H
-#define MODULEDEPS_H
-
-typedef struct moduleDependency_s * moduleDeps;
-
-struct moduleDependency_s {
- char * name;
- char ** deps;
-};
-
-moduleDeps mlNewDeps(void);
-int mlLoadDeps(moduleDeps * moduleDepListPtr, const char * path);
-char ** mlGetDeps(moduleDeps modDeps, const char * modName);
-
-#endif
diff --git a/loader2/modules.c b/loader2/modules.c
index dcd1aafac..4b49f2a9d 100644
--- a/loader2/modules.c
+++ b/loader2/modules.c
@@ -26,12 +26,12 @@
#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/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
@@ -41,238 +41,116 @@
#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 uint64_t 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);
- close(fd);
- 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, count = 0;
+static int writeModulesConf(char *conf);
+struct moduleOptions {
+ char *name;
+ int numopts;
+ char **options;
+};
- devices = probeDevices(CLASS_HD, BUS_SCSI, PROBE_LOADED);
- if (devices) {
- for (i=0; devices[i]; i++, count++);
- free(devices);
- }
- /* have to probe for usb floppies too */
- devices = probeDevices(CLASS_FLOPPY, BUS_SCSI, PROBE_LOADED);
- if (devices) {
- for (i=0; devices[i]; i++, count++);
- free(devices);
- }
- /* have to probe for usb cdrom too */
- devices = probeDevices(CLASS_CDROM, BUS_SCSI, PROBE_LOADED);
- if (devices) {
- for (i=0; devices[i]; i++, count++);
- free(devices);
- }
+static struct moduleOptions * modopts = NULL;
+static int nummodopts = -1;
- return count;
-}
+static char ** blacklists = NULL;
+static int numblacklists = 0;
-int mlReadLoadedList(moduleList * mlp) {
+static void readBlacklist() {
int fd;
- char * start;
- char * end;
- char buf[4096];
- struct stat sb;
- int i;
- moduleList ml;
+ size_t len = 0;
+ char buf[1024];
+ char *start, *end;
- if ((fd = open("/proc/modules", O_RDONLY)) < 0)
- return -1;
+ if ((fd = open("/proc/cmdline", O_RDONLY)) < 0)
+ return;
- fstat(fd, &sb);
- i = read(fd, buf, sizeof(buf));
- buf[i] = '\0';
+ len = read(fd, buf, sizeof(buf) - 1);
close(fd);
-
- ml = malloc(sizeof(*ml));
- ml->numModules = 0;
-
+ buf[len] = '\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 there 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++;
+ while (start) {
+ end = strstr(start, " ");
+ if (end)
+ *end = '\0';
+ if (strncmp(start,"blacklist=",10)) {
+ if (!end)
+ break;
+ start = end + 1;
continue;
}
+ printf("found %s\n",start);
- /* 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;
- }
+ blacklists = realloc(blacklists, sizeof(*blacklists) * (numblacklists + 1));
+ blacklists[numblacklists] = strdup(start+10);
+ numblacklists++;
- /* 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++;
+ if (!end)
+ break;
+ start = end + 1;
}
-
- 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;
+static void addOption(const char *module, const char *option) {
+ int found = 0, i;
- return 0;
+ found = 0;
+ for (i = 0; i < nummodopts; i++) {
+ if (strncmp(modopts[i].name, module, strlen(modopts[i].name)))
+ continue;
+ modopts[i].numopts++;
+ found = 1;
+ break;
+ }
+ if (found == 0) {
+ modopts = realloc(modopts, sizeof(*modopts) * (nummodopts + 1));
+ modopts[nummodopts].name = strdup(module);
+ modopts[nummodopts].numopts = 1;
+ modopts[nummodopts++].options = NULL;
+ }
+ modopts[i].options = realloc(modopts[i].options,
+ sizeof(modopts[i].options) *
+ (modopts[i].numopts + 1));
+ modopts[i].options[modopts[i].numopts - 1] = strdup(option);
+ modopts[i].options[modopts[i].numopts] = NULL;
}
-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];
+static int isValidModule(char *module) {
+ char mod_name[64], path[512];
+ struct utsname utsbuf;
+ struct stat sbuf;
+ char *buf;
- return NULL;
-}
-
-struct moduleOptions {
- char *name;
- int numopts;
- char **options;
-};
+ uname(&utsbuf);
+ snprintf(path, 512, "/lib/modules/%s/modules.dep", utsbuf.release);
+ if (!stat(path, &sbuf)) {
+ int fd;
-static struct moduleOptions * modopts = NULL;
-static int nummodopts = -1;
+ fd = open(path, O_RDONLY);
+ buf = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (!buf || buf == MAP_FAILED)
+ return 0;
+ close(fd);
+ snprintf(mod_name, 64, "/%s.ko.gz:", module);
+ if (strstr(buf, mod_name)) {
+ munmap(buf, sbuf.st_size);
+ return 1;
+ }
+ snprintf(mod_name, 64, "/%s.ko:", module);
+ if (strstr(buf, mod_name)) {
+ munmap(buf, sbuf.st_size);
+ return 1;
+ }
+ munmap(buf, sbuf.st_size);
+ }
+ return 0;
+}
/* read module options out of /proc/cmdline and into a structure */
static void readModuleOpts() {
@@ -280,7 +158,6 @@ static void readModuleOpts() {
size_t len = 0;
char buf[1024];
char *start, *end, *sep;
- int found = 0, i;
nummodopts = 0;
if ((fd = open("/proc/cmdline", O_RDONLY)) < 0)
@@ -311,830 +188,126 @@ static void readModuleOpts() {
}
*sep = '\0'; sep++;
- found = 0;
- for (i = 0; i < nummodopts; i++) {
- if (strncmp(modopts[i].name, start, strlen(modopts[i].name)))
- continue;
- modopts[i].numopts++;
- found = 1;
- break;
- }
- if (found == 0) {
- modopts = realloc(modopts, sizeof(*modopts) * (nummodopts + 1));
- modopts[nummodopts].name = strdup(start);
- modopts[nummodopts].numopts = 1;
- modopts[nummodopts++].options = NULL;
- }
- modopts[i].options = realloc(modopts[i].options,
- sizeof(modopts[i].options) *
- (modopts[i].numopts + 1));
- modopts[i].options[modopts[i].numopts - 1] = strdup(sep);
+ if (isValidModule(start))
+ addOption(start, sep);
if (!end)
break;
start = end + 1;
}
-
- /* null-terminate options for each module */
- for (i = 0; i < nummodopts; i++) {
- modopts[i].options[modopts[i].numopts] = NULL;
- }
-}
-
-/* look for options for a specific module from the command line */
-static char ** cmdLineModuleOpts(const char *modName) {
- int i;
-
- if (nummodopts == -1)
- readModuleOpts();
- for (i = 0; i < nummodopts; i++) {
- if (strncmp(modName, modopts[i].name, strlen(modName)))
- continue;
- return modopts[i].options;
- }
- return NULL;
}
+static int doLoadModule(const char *module, char ** args) {
+ int child;
+ int status;
-/* 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, ** cmdlineArgs;
- struct moduleInfo * mi = NULL;
- int deviceCount = -1;
- int popWindow = 0;
- int rc, child, i, status;
- static int usbWasLoaded = 0;
+ if (!(child = fork())) {
+ int i, rc;
+ char **argv = malloc(3 * sizeof(*argv));
+ int fd = open("/dev/tty3", O_RDWR);
- /* 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");
- }
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ close(fd);
- if (mi->major == DRIVER_SCSI) {
- deviceCount = scsiDiskCount();
- if (!FL_CMDLINE(flags)) {
- startNewt();
- scsiWindow(modName);
- popWindow = 1;
+ argv[0] = "/sbin/modprobe";
+ argv[1] = strdup(module);
+ argv[2] = NULL;
+ if (args) {
+ for (i = 0; args[i] ; i++) {
+ addOption(module, args[i]);
}
+ writeModulesConf("/etc/modprobe.d/anaconda");
}
+ rc = execv("/sbin/modprobe", argv);
+ _exit(rc);
}
- /* look to see if there are options for this module specified on
- * the command line. should be specified in the form of
- * module.option=value
- */
- cmdlineArgs = cmdLineModuleOpts(modName);
- if (!args && cmdlineArgs) {
- args = cmdlineArgs;
- } else if (cmdlineArgs) {
- for (i=0, arg = args; *arg; arg++, i++);
- for (arg = cmdlineArgs; *arg; arg++, i++);
- args = realloc(args, sizeof(*newArgs) * (i + 1));
- for (i=0, arg = args; *arg; arg++, i++);
- for (arg = cmdlineArgs; *arg; arg++, i++)
- args[i] = strdup(*arg);
- args[i] = NULL;
- }
-
- sprintf(fileName, "%s.ko", modName);
- for (argPtr = args; argPtr && *argPtr; argPtr++) {
- strcat(fileName, " ");
- strcat(fileName, *argPtr);
- }
+ waitpid(child, &status, 0);
- if (FL_TESTING(flags)) {
- logMessage(INFO, "would have insmod %s (%s)", path->path, fileName);
- rc = 0;
+ if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
+ return 1;
} 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);
- }
- 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];
+ return 0;
}
- 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) {
- char * modNames;
- char * start, * next, * end;
- char ** initialList;
- char ** list, ** l;
- char items[1024] = ""; /* 1024 characters should be enough... */
- struct extractedModule * paths, * p;
- struct loadedModuleInfo * mod;
+void mlRemoveBlacklist(char *module) {
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) {
- if (mi->locationID)
- paths = extractModules(list, paths, mi->locationID);
-
- if (mi->major == DRIVER_SCSI) {
- if ((mod = getLoadedModuleInfo(modLoaded, "usb-storage")) &&
- mod->firstDevNum != mod->lastDevNum) {
- logMessage(DEBUGLVL, "setting reloadUsbStorage");
- reloadUsbStorage = 1;
- }
- }
-
- }
- }
- }
-
- paths = extractModules(list, paths, NULL);
-
- 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 */
- logMessage(INFO, "unloading module usb-storage");
- 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) {
- logMessage(INFO, "reloading module usb-storage");
- 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);
+ for (i = 0 ; i < numblacklists ; i++) {
+ if (!strcmp(blacklists[i], module))
+ blacklists[i] = NULL;
}
+}
- free(paths);
- free(list);
-
- logMessage(INFO, "load module set done");
-
- return i;
+void mlInitModuleConfig() {
+ readModuleOpts();
+ readBlacklist();
+ writeModulesConf("/etc/modprobe.d/anaconda");
}
/* 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);
+int mlLoadModule(const char * module, char ** args) {
+ return doLoadModule(module, args);
}
/* 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);
-}
-
-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);
+int mlLoadModuleSet(const char * modNames) {
+ char *ptr, *name;
+ int rc = 0;
+
+ if (!modNames) return 1;
+ name = strdup(modNames); while (name) {
+ ptr = strchr(name, ':');
+ if (ptr) *ptr = '\0';
+ rc |= doLoadModule(name, NULL);
+ if (ptr)
+ name = ptr+1;
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;
+ name = NULL;
+ }
+ return rc;
}
-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);
+static int writeModulesConf(char *conf) {
+ int i;
+ char buf[16384];
+ int fd, rc;
- if (!list) return 0;
+ if (!conf)
+ conf = "/tmp/modprobe.conf";
- fd = open("/tmp/modprobe.conf", O_WRONLY | O_CREAT | O_APPEND, 0666);
+ fd = open(conf, O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
- logMessage(ERROR, "error appending to /tmp/modprobe.conf: %s\n",
- strerror(errno));
+ logMessage(ERROR, "error opening to %s: %s\n",
+ conf, strerror(errno));
return 0;
}
+ strcat(buf, "# Module options and blacklists written by anaconda\n");
+ for (i = 0; i < nummodopts ; i++) {
+ int j;
- 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
- 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++;
+ strcat(buf, "options ");
+ strcat(buf, modopts[i].name);
+ for (j = 0; j < modopts[i].numopts ; j++) {
+ strcat(buf, " ");
+ strcat(buf, modopts[i].options[j]);
}
+ strcat(buf, "\n");
}
-
- 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++;
+ for (i = 0; i < numblacklists ; i++) {
+ if (blacklists[i]) {
+ strcat(buf, "blacklist ");
+ strcat(buf, blacklists[i]);
+ strcat(buf, "\n");
}
}
-
- 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;
+ rc = write(fd, buf, strlen(buf));
+ close(fd);
+ return (rc != strlen(buf));
}
void loadKickstartModule(struct loaderData_s * loaderData, int argc,
@@ -1197,7 +370,5 @@ void loadKickstartModule(struct loaderData_s * loaderData, int argc,
}
- mlLoadModule(module, loaderData->modLoaded, *(loaderData->modDepsPtr),
- loaderData->modInfo, args);
+ mlLoadModule(module, args);
}
-
diff --git a/loader2/modules.h b/loader2/modules.h
index 6d0bcbcf3..b276ce4ea 100644
--- a/loader2/modules.h
+++ b/loader2/modules.h
@@ -21,43 +21,9 @@
#define H_MODULES
#include "moduleinfo.h"
-#include "moduledeps.h"
-
-typedef struct moduleList_s * moduleList;
-
-struct loadedModuleInfo {
- char * name;
- char ** args;
- int weLoaded;
- int written;
- char * path;
- int firstDevNum, lastDevNum;
- enum driverMajor major;
- enum driverMinor minor;
-};
-
-struct extractedModule {
- char * path;
- char * location;
-};
-
-struct moduleList_s {
- struct loadedModuleInfo mods[100];
- int numModules;
-};
-
-int mlReadLoadedList(moduleList * mlp);
-int mlLoadModule(const char * module, moduleList modLoaded,
- moduleDeps modDeps, moduleInfoSet modInfo,
- char ** args);
-int mlLoadModuleSet(const char * modNames,
- moduleList modLoaded, moduleDeps modDeps,
- moduleInfoSet modInfo);
-
-int mlModuleInList(const char * modName, moduleList list);
-void writeScsiDisks(moduleList list);
-
-int removeLoadedModule(const char * modName, moduleList modLoaded);
-char * getModuleLocation(int version);
+void mlInitModuleConfig();
+int mlLoadModule(const char * module, char ** args);
+int mlLoadModuleSet(const char * modNames);
+void mlRemoveBlacklist(char *module);
#endif