Index: sys/kern/kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.222
diff -p -u -r1.222 kern_subr.c
--- sys/kern/kern_subr.c	5 Jan 2019 18:03:41 -0000	1.222
+++ sys/kern/kern_subr.c	16 Jan 2019 21:03:03 -0000
@@ -107,8 +107,8 @@ __KERNEL_RCSID(0, "$NetBSD: kern_subr.c,
 
 /* XXX these should eventually move to subr_autoconf.c */
 static device_t finddevice(const char *);
-static device_t getdisk(char *, int, int, dev_t *, int);
-static device_t parsedisk(char *, int, int, dev_t *);
+static device_t getdisk(const char *, int, int, dev_t *, int);
+static device_t parsedisk(const char *, int, int, dev_t *);
 static const char *getwedgename(const char *, int);
 
 static void setroot_nfs(device_t);
@@ -185,10 +185,13 @@ setroot(device_t bootdv, int bootpartiti
 {
 
 	/*
-	 * Let bootcode augment "rootspec".
+	 * Let bootcode augment "rootspec", ensure that
+	 * rootdev is invalid to avoid confusion.
 	 */
-	if (rootspec == NULL)
+	if (rootspec == NULL) {
 		rootspec = bootspec;
+		rootdev = NODEV;
+	}
 
 	/*
 	 * force boot device to md0
@@ -448,9 +451,9 @@ setroot_ask(device_t bootdv, int bootpar
 
 /*
  * configure
- *   dev_t rootdev
+ *   device_t root_device
+ *   dev_t rootdev (for disks)
  * 
- * return device_t or NULL if not found
  */
 static void
 setroot_root(device_t bootdv, int bootpartition)
@@ -459,6 +462,7 @@ setroot_root(device_t bootdv, int bootpa
 	int majdev;
 	const char *rootdevname;
 	char buf[128];
+	dev_t nrootdev;
 
 	if (rootspec == NULL) {
 
@@ -490,20 +494,17 @@ setroot_root(device_t bootdv, int bootpa
 		 */
 
 		/*
-		 * If it's a network interface, we can bail out
-		 * early.
+		 * If rootspec can be parsed, just use it.
 		 */
-		rootdv = finddevice(rootspec);
-		if (rootdv != NULL && device_class(rootdv) == DV_IFNET)
-			goto haveroot;
-
-		if (rootdv != NULL && device_class(rootdv) == DV_DISK &&
-		    !DEV_USES_PARTITIONS(rootdv) &&
-		    (majdev = devsw_name2blk(device_xname(rootdv), NULL, 0)) >= 0) {
-			rootdev = makedev(majdev, device_unit(rootdv));
+		rootdv = parsedisk(rootspec, strlen(rootspec), 0, &nrootdev);
+		if (rootdv != NULL) {
+			rootdev = nrootdev;
 			goto haveroot;
 		}
 
+		/*
+		 * Fall back to rootdev, compute rootdv for it
+		 */
 		rootdevname = devsw_blk2name(major(rootdev));
 		if (rootdevname == NULL) {
 			printf("unknown device major 0x%llx\n",
@@ -647,11 +648,22 @@ finddevice(const char *name)
 }
 
 static device_t
-getdisk(char *str, int len, int defpart, dev_t *devp, int isdump)
+getdisk(const char *str, int len, int defpart, dev_t *devp, int isdump)
 {
 	device_t dv;
 	deviter_t di;
 
+	if (len == 4 && strcmp(str, "halt") == 0)
+		cpu_reboot(RB_HALT, NULL);
+	else if (len == 6 && strcmp(str, "reboot") == 0)
+		cpu_reboot(0, NULL);
+#if defined(DDB)
+	else if (len == 3 && strcmp(str, "ddb") == 0) {
+		console_debugger();
+		return NULL;
+	}
+#endif
+
 	if ((dv = parsedisk(str, len, defpart, devp)) == NULL) {
 		printf("use one of:");
 		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
@@ -689,35 +701,33 @@ getwedgename(const char *name, int namel
 }
 
 static device_t
-parsedisk(char *str, int len, int defpart, dev_t *devp)
+parsedisk(const char *str, int len, int defpart, dev_t *devp)
 {
 	device_t dv;
 	const char *wname;
-	char *cp, c;
+	char c;
 	int majdev, part;
+	char xname[16]; /* same size as dv_xname */
+
 	if (len == 0)
 		return (NULL);
 
-	if (len == 4 && strcmp(str, "halt") == 0)
-		cpu_reboot(RB_HALT, NULL);
-	else if (len == 6 && strcmp(str, "reboot") == 0)
-		cpu_reboot(0, NULL);
-#if defined(DDB)
-	else if (len == 3 && strcmp(str, "ddb") == 0)
-		console_debugger();
-#endif
-
-	cp = str + len - 1;
-	c = *cp;
-
 	if ((wname = getwedgename(str, len)) != NULL) {
 		if ((dv = dkwedge_find_by_wname(wname)) == NULL)
 			return NULL;
 		part = defpart;
 		goto gotdisk;
-	} else if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
+	}
+
+	c = str[len-1];
+	if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
 		part = c - 'a';
-		*cp = '\0';
+		len--;
+		if (len > sizeof(xname)-1)
+			return NULL;
+		memcpy(xname, str, len);
+		xname[len] = '\0';
+		str = xname;
 	} else
 		part = defpart;
 
@@ -739,6 +749,5 @@ parsedisk(char *str, int len, int defpar
 			*devp = NODEV;
 	}
 
-	*cp = c;
 	return (dv);
 }
