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); }