Module Name:    src
Committed By:   jmcneill
Date:           Sun Sep 13 18:13:37 UTC 2009

Modified Files:
        src/sys/arch/i386/stand/lib: exec.c

Log Message:
kmod improvements
 - unless otherwise specified, modules are now loaded from the same device
   as the kernel ('load miniroot' now implies 'load tftp:miniroot' if the
   boot command is 'boot tftp:netbsd')
 - the module name -> path expansion now works when a device prefix: is
   specified ('load tftp:miniroot' now works)
 - if the module name has been expanded to a path, print that path when
   loading the module rather than the symbolic name
 - only print an error in module_open if both the expanded path and the
   raw path fail to open


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/i386/stand/lib/exec.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/i386/stand/lib/exec.c
diff -u src/sys/arch/i386/stand/lib/exec.c:1.40 src/sys/arch/i386/stand/lib/exec.c:1.41
--- src/sys/arch/i386/stand/lib/exec.c:1.40	Sat Mar 21 15:01:56 2009
+++ src/sys/arch/i386/stand/lib/exec.c	Sun Sep 13 18:13:37 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec.c,v 1.40 2009/03/21 15:01:56 ad Exp $	 */
+/*	$NetBSD: exec.c,v 1.41 2009/09/13 18:13:37 jmcneill Exp $	 */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -124,6 +124,8 @@
 #define	PAGE_SIZE	4096
 #endif
 
+#define MODULE_WARNING_DELAY	5000000
+
 extern struct btinfo_console btinfo_console;
 
 boot_module_t *boot_modules;
@@ -138,7 +140,7 @@
 static char module_base[64] = "/";
 static int howto;
 
-static void	module_init(void);
+static void	module_init(const char *);
 
 void
 framebuffer_configure(struct btinfo_framebuffer *fb)
@@ -304,7 +306,7 @@
 
 	/* pull in any modules if necessary */
 	if (boot_modules_enabled) {
-		module_init();
+		module_init(file);
 		if (btinfo_modulelist) {
 			BI_ADD(btinfo_modulelist, BTINFO_MODULELIST,
 			    btinfo_modulelist_size);
@@ -333,12 +335,26 @@
 	return -1;
 }
 
+static void
+extract_device(const char *path, char *buf, size_t buflen)
+{
+	int i;
+
+	if (strchr(path, ':') != NULL) {
+		for (i = 0; i < buflen - 2 && path[i] != ':'; i++)
+			buf[i] = path[i];
+		buf[i++] = ':';
+		buf[i] = '\0';
+	} else
+		buf[0] = '\0';
+}
+
 static const char *
-module_path(boot_module_t *bm)
+module_path(boot_module_t *bm, const char *kdev)
 {
 	static char buf[256];
-	char name_buf[256];
-	const char *name, *name2;
+	char name_buf[256], dev_buf[64];
+	const char *name, *name2, *p;
 
 	name = bm->bm_path;
 	for (name2 = name; *name2; ++name2) {
@@ -350,45 +366,69 @@
 			break;
 		}
 	}
- 	if (name[0] == '/')
-		snprintf(buf, sizeof(buf), "%s", name);
-	else
-		snprintf(buf, sizeof(buf), "%s/%s/%s.kmod",
-		    module_base, name, name);
+	if ((p = strchr(name, ':')) != NULL) {
+		/* device specified, use it */
+		if (p[1] == '/')
+			snprintf(buf, sizeof(buf), "%s", name);
+		else {
+			p++;
+			extract_device(name, dev_buf, sizeof(dev_buf));
+			snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
+			    dev_buf, module_base, p, p);
+		}
+	} else {
+		/* device not specified; load from kernel device if known */
+ 		if (name[0] == '/')
+			snprintf(buf, sizeof(buf), "%s%s", kdev, name);
+		else
+			snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
+			    kdev, module_base, name, name);
+	}
 
 	return buf;
 }
 
 static int
-module_open(boot_module_t *bm, int mode)
+module_open(boot_module_t *bm, int mode, const char *kdev, bool doload)
 {
 	int fd;
 	const char *path;
 
 	/* check the expanded path first */
-	path = module_path(bm);
+	path = module_path(bm, kdev);
 	fd = open(path, mode);
-	if (fd == -1) {
-		printf("WARNING: couldn't open %s\n", path);
+	if (fd != -1) {
+		if ((howto & AB_SILENT) == 0 && doload)
+			printf("Loading %s ", path);
+	} else {
 		/* now attempt the raw path provided */
 		fd = open(bm->bm_path, mode);
-		if (fd == -1)
-			printf("WARNING: couldn't open %s\n", bm->bm_path);
+		if (fd != -1 && (howto & AB_SILENT) == 0 && doload)
+			printf("Loading %s ", bm->bm_path);
+	}
+	if (!doload && fd == -1) {
+		printf("WARNING: couldn't open %s", bm->bm_path);
+		if (strcmp(bm->bm_path, path) != 0)
+			printf(" (%s)", path);
+		printf("\n");
 	}
 	return fd;
 }
 
 static void
-module_init(void)
+module_init(const char *kernel_path)
 {
 	struct bi_modulelist_entry *bi;
 	struct stat st;
 	const char *machine;
+	char kdev[64];
 	char *buf;
 	boot_module_t *bm;
 	size_t len;
 	off_t off;
-	int err, fd;
+	int err, fd, nfail = 0;
+
+	extract_device(kernel_path, kdev, sizeof(kdev));
 
 	switch (netbsd_elf_class) {
 	case ELFCLASS32:
@@ -419,9 +459,10 @@
 	/* First, see which modules are valid and calculate btinfo size */
 	len = sizeof(struct btinfo_modulelist);
 	for (bm = boot_modules; bm; bm = bm->bm_next) {
-		fd = module_open(bm, 0);
+		fd = module_open(bm, 0, kdev, false);
 		if (fd == -1) {
 			bm->bm_len = -1;
+			++nfail;
 			continue;
 		}
 		err = fstat(fd, &st);
@@ -429,6 +470,7 @@
 			printf("WARNING: couldn't stat %s\n", bm->bm_path);
 			close(fd);
 			bm->bm_len = -1;
+			++nfail;
 			continue;
 		}
 		bm->bm_len = st.st_size;
@@ -440,6 +482,7 @@
 	btinfo_modulelist = alloc(len);
 	if (btinfo_modulelist == NULL) {
 		printf("WARNING: couldn't allocate module list\n");
+		delay(MODULE_WARNING_DELAY);
 		return;
 	}
 	memset(btinfo_modulelist, 0, len);
@@ -453,13 +496,9 @@
 	for (bm = boot_modules; bm; bm = bm->bm_next) {
 		if (bm->bm_len == -1)
 			continue;
-		if ((howto & AB_SILENT) == 0)
-			printf("Loading %s ", bm->bm_path);
-		fd = module_open(bm, 0);
-		if (fd == -1) {
-			printf("ERROR: couldn't open %s\n", bm->bm_path);
+		fd = module_open(bm, 0, kdev, true);
+		if (fd == -1)
 			continue;
-		}
 		image_end = (image_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
 		len = pread(fd, (void *)image_end, SSIZE_MAX);
 		if (len < bm->bm_len) {
@@ -482,6 +521,14 @@
 		close(fd);
 	}
 	btinfo_modulelist->endpa = image_end;
+
+	if (nfail > 0) {
+		printf("WARNING: %d module%s failed to load\n",
+		    nfail, nfail == 1 ? "" : "s");
+#if notyet
+		delay(MODULE_WARNING_DELAY);
+#endif
+	}
 }
 
 int
@@ -515,7 +562,7 @@
 
 	/* pull in any modules if necessary */
 	if (boot_modules_enabled) {
-		module_init();
+		module_init(file);
 		if (btinfo_modulelist) {
 			mbm = alloc(sizeof(struct multiboot_module) *
 					   btinfo_modulelist->num);

Reply via email to