Subject: Re: broken LKM, modload and so on.
To: None <jdolecek@netbsd.org>
From: MAEKAWA Masahide <bishop@rr.iij4u.or.jp>
List: current-users
Date: 09/09/2002 17:45:50
----Next_Part(Mon_Sep__9_17:45:50_2002_616)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Jaromir Dolecek <jdolecek@netbsd.org> wrote:
>Please do NOT expose struct lkm_* to userland.

How about attached one?

--- MAEKAWA Masahide
--- Key fingerprint = BC5E D8CB 816C 2CB5 8560  FDE3 6CB8 BF5D 8D50 F2EE

----Next_Part(Mon_Sep__9_17:45:50_2002_616)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="base.diff"

Index: sbin/modload/modload.c
===================================================================
RCS file: /cvsroot/cvs/NetBSD/basesrc/sbin/modload/modload.c,v
retrieving revision 1.30
diff -u -r1.30 modload.c
--- sbin/modload/modload.c	2001/11/08 15:33:15	1.30
+++ sbin/modload/modload.c	2002/09/09 08:14:46
@@ -454,21 +454,27 @@
 	 */
 	if (post) {
 		struct lmc_stat sbuf;
-		char id[16], type[16], offset[16];
+		char id[16], type[16], offset[2][16];
 
 		sbuf.id = resrv.slot;
 		if (ioctl(devfd, LMSTAT, &sbuf) == -1)
 			err(15, "error fetching module stats for post-install");
 		(void)snprintf(id, sizeof(id), "%d", sbuf.id);
 		(void)snprintf(type, sizeof(type), "0x%x", sbuf.type);
-		(void)snprintf(offset, sizeof(offset), "%ld",
-		    (long)sbuf.offset);
-		/*
-		 * XXX
-		 * The modload docs say that drivers can install bdevsw &
-		 * cdevsw, but the interface only supports one at a time.
-		 */
-		execl(post, post, id, type, offset, 0);
+		if (sbuf.type == LM_DEV) {
+			int16_t bmajor, cmajor;
+			bmajor = (sbuf.offset >> 16) & 0xffff;
+			cmajor = sbuf.offset & 0xffff;
+			(void)snprintf(offset[0], sizeof(offset[0]), "%d",
+				cmajor);
+			(void)snprintf(offset[1], sizeof(offset[1]), "%d",
+				bmajor);
+			execl(post, post, id, type, offset[0], offset[1], 0);
+		} else {
+			(void)snprintf(offset[0], sizeof(offset[0]), "%ld",
+			    (long)sbuf.offset);
+			execl(post, post, id, type, offset[0], 0);
+		}
 		err(16, "can't exec `%s'", post);
 	}
 

----Next_Part(Mon_Sep__9_17:45:50_2002_616)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="sys.diff"

Index: sys/kern/kern_lkm.c
===================================================================
RCS file: /cvsroot/cvs/NetBSD/syssrc/sys/kern/kern_lkm.c,v
retrieving revision 1.58
diff -u -r1.58 kern_lkm.c
--- sys/kern/kern_lkm.c	2002/09/06 13:23:47	1.58
+++ sys/kern/kern_lkm.c	2002/09/09 08:39:25
@@ -744,10 +744,13 @@
 		error = devsw_attach(args->lkm_devname,
 				     args->lkm_bdev, &args->lkm_bdevmaj,
 				     args->lkm_cdev, &args->lkm_cdevmaj);
+		args->lkm_offset = (args->lkm_bdevmaj << 16) |
+				   args->lkm_cdevmaj;
 		break;
 
 	case LKM_E_UNLOAD:
 		devsw_detach(args->lkm_bdev, args->lkm_cdev);
+		args->lkm_offset = -1;
 		args->lkm_bdevmaj = -1;
 		args->lkm_cdevmaj = -1;
 		break;
Index: sys/kern/subr_devsw.c
===================================================================
RCS file: /cvsroot/cvs/NetBSD/syssrc/sys/kern/subr_devsw.c,v
retrieving revision 1.2
diff -u -r1.2 subr_devsw.c
--- sys/kern/subr_devsw.c	2002/09/06 13:23:49	1.2
+++ sys/kern/subr_devsw.c	2002/09/09 01:32:43
@@ -172,9 +172,9 @@
 			}
 			if (i != max_devsw_convs)
 				continue;
-			*devmajor = bmajor;
 			break;
 		}
+		*devmajor = bmajor;
 	}
 	if (*devmajor >= MAXDEVSW) {
 #ifdef DEVSW_DEBUG
@@ -226,9 +226,9 @@
 			}
 			if (i != max_devsw_convs)
 				continue;
-			*devmajor = cmajor;
 			break;
 		}
+		*devmajor = cmajor;
 	}
 	if (*devmajor >= MAXDEVSW) {
 #ifdef DEVSW_DEBUG

----Next_Part(Mon_Sep__9_17:45:50_2002_616)----