stand: parsedev API change: devspec now points to start of full device name

To support more flexible device matching, we now pass in the full
devspec to the parsedev routines. For everything execpt uboot, this is
just a drop in (since everything except uboot and openfirmware always
uses disk...: and/or zfs:, but openfirmware isn't really affected).

uboot we kludge around it by subtracting 4 from where the rest of the
device name starts. This is unforunate, and can compute the address one
before the string. But we never dereference that address. uboot needs
more work, and this is an acceptable UB until that other work happens.

OFW doesn't really use the parsedev routines these days (since none of
the supported device uses this... yet). It too needs more work, but it
needs device matching support first.

Sponsored by:		Netflix
Reviewed by:		delphij
Differential Revision:	https://reviews.freebsd.org/D37553
This commit is contained in:
Warner Losh 2022-11-30 15:09:36 -07:00
parent 66012c8fc4
commit 33bbe5ddcb
7 changed files with 14 additions and 8 deletions

View file

@ -420,7 +420,7 @@ disk_parsedev(struct devdesc **idev, const char *devspec, const char **path)
char *cp;
struct disk_devdesc *dev;
np = devspec;
np = devspec + 4; /* Skip the leading 'disk' */
unit = -1;
/*
* If there is path/file info after the device info, then any missing

View file

@ -214,7 +214,7 @@ main(void)
devinit();
/* XXX assumes this will be a disk, but it looks likely give above */
disk_parsedev((struct devdesc **)&devdesc, boot_devname + 4, NULL);
disk_parsedev((struct devdesc **)&devdesc, boot_devname, NULL);
bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc->d_slice + 1,
devdesc->dd.d_unit,

View file

@ -112,7 +112,7 @@ ofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path)
if (dv->dv_parsedev != NULL) {
p = devspec + strlen(dv->dv_name);
free(idev);
err = dv->dv_parsedev((struct devdesc **)&idev, p, path);
err = dv->dv_parsedev((struct devdesc **)&idev, devspec, path);
if (err != 0) {
return (err);
}

View file

@ -134,7 +134,7 @@ devparse(struct devdesc **dev, const char *devspec, const char **path)
idev = NULL;
err = 0;
if (dv->dv_parsedev) {
err = dv->dv_parsedev(&idev, np, path);
err = dv->dv_parsedev(&idev, devspec, path);
} else {
np = devspec + strlen(dv->dv_name);
err = default_parsedev(&idev, np, path);

View file

@ -385,7 +385,7 @@ zfs_mount(const char *dev, const char *path, void **data)
int rv;
errno = 0;
rv = zfs_parsedev((struct devdesc **)&zfsdev, dev + 3, NULL);
rv = zfs_parsedev((struct devdesc **)&zfsdev, dev, NULL);
if (rv != 0) {
return (rv);
}
@ -1644,7 +1644,7 @@ zfs_parsedev(struct devdesc **idev, const char *devspec, const char **path)
int rv;
struct zfs_devdesc *dev;
np = devspec;
np = devspec + 3; /* Skip the leading 'zfs' */
if (*np != ':')
return (EINVAL);
np++;

View file

@ -116,7 +116,7 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
#ifdef LOADER_DISK_SUPPORT
case DEVT_DISK:
free(idev);
err = disk_parsedev((struct devdesc **)&idev, np, path);
err = disk_parsedev((struct devdesc **)&idev, devspec, path);
if (err != 0)
goto fail;
break;

View file

@ -233,11 +233,17 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
* parse the remainder of the string as such, and if it works, return
* those results. Otherwise we'll fall through to the code that parses
* the legacy format.
*
* disk_parsedev now assumes that it points to the start of the device
* name, but since it doesn't know about uboot's usage, just subtract 4
* since it always adds 4. This is the least-bad solution since it makes
* all the other loader code easier (might be better to create a fake
* 'disk...' string, but that's more work than uboot is worth).
*/
if (*type & DEV_TYP_STOR) {
size_t len = strlen(p);
if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 &&
disk_parsedev((struct devdesc **)&dev, p, NULL) == 0) {
disk_parsedev((struct devdesc **)&dev, p - 4, NULL) == 0) { /* Hack */
*unit = dev->dd.d_unit;
*slice = dev->d_slice;
*partition = dev->d_partition;