Page MenuHomeFreeBSD

D37311.diff
No OneTemporary

D37311.diff

diff --git a/stand/efi/libefi/devicename.c b/stand/efi/libefi/devicename.c
--- a/stand/efi/libefi/devicename.c
+++ b/stand/efi/libefi/devicename.c
@@ -39,8 +39,6 @@
#include <efilib.h>
#include <efizfs.h>
-static int efi_parsedev(struct devdesc **, const char *, const char **);
-
/*
* Point (dev) at an allocated device specifier for the device matching the
* path in (devspec). If it contains an explicit device specification,
@@ -57,118 +55,14 @@
* use the current device instead.
*/
if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
- rv = efi_parsedev(dev, getenv("currdev"), NULL);
+ rv = devparse(dev, getenv("currdev"), NULL);
if (rv == 0 && path != NULL)
*path = devspec;
return (rv);
}
/* Parse the device name off the beginning of the devspec. */
- return (efi_parsedev(dev, devspec, path));
-}
-
-/*
- * Point (dev) at an allocated device specifier matching the string version
- * at the beginning of (devspec). Return a pointer to the remaining
- * text in (path).
- *
- * In all cases, the beginning of (devspec) is compared to the names
- * of known devices in the device switch, and then any following text
- * is parsed according to the rules applied to the device type.
- *
- * For disk-type devices, the syntax is:
- *
- * fs<unit>:
- */
-static int
-efi_parsedev(struct devdesc **dev, const char *devspec, const char **path)
-{
- struct devdesc *idev;
- struct devsw *dv;
- int i, unit, err;
- char *cp;
- const char *np;
-
- /* minimum length check */
- if (strlen(devspec) < 2)
- return (EINVAL);
-
- /* look for a device that matches */
- for (i = 0; devsw[i] != NULL; i++) {
- dv = devsw[i];
- if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
- break;
- }
- if (devsw[i] == NULL)
- return (ENOENT);
-
- np = devspec + strlen(dv->dv_name);
- idev = NULL;
- err = 0;
-
- switch (dv->dv_type) {
- case DEVT_NONE:
- break;
-
- case DEVT_DISK:
- idev = malloc(sizeof(struct disk_devdesc));
- if (idev == NULL)
- return (ENOMEM);
-
- err = disk_parsedev((struct disk_devdesc *)idev, np, path);
- if (err != 0)
- goto fail;
- break;
-
-#ifdef EFI_ZFS_BOOT
- case DEVT_ZFS:
- idev = malloc(sizeof(struct zfs_devdesc));
- if (idev == NULL)
- return (ENOMEM);
-
- err = zfs_parsedev((struct zfs_devdesc*)idev, np, path);
- if (err != 0)
- goto fail;
- break;
-#endif
- default:
- idev = malloc(sizeof(struct devdesc));
- if (idev == NULL)
- return (ENOMEM);
-
- unit = 0;
- cp = (char *)np;
-
- if (*np != '\0' && *np != ':') {
- errno = 0;
- unit = strtol(np, &cp, 0);
- if (errno != 0 || cp == np) {
- err = EUNIT;
- goto fail;
- }
- }
- if (*cp != '\0' && *cp != ':') {
- err = EINVAL;
- goto fail;
- }
-
- idev->d_unit = unit;
- if (path != NULL)
- *path = (*cp == 0) ? cp : cp + 1;
- break;
- }
-
- idev->d_dev = dv;
-
- if (dev != NULL)
- *dev = idev;
- else
- free(idev);
- return (0);
-
-fail:
- free(idev);
- return (err);
+ return (devparse(dev, devspec, path));
}
/*
@@ -180,7 +74,7 @@
struct devdesc *ncurr;
int rv;
- rv = efi_parsedev(&ncurr, value, NULL);
+ rv = devparse(&ncurr, value, NULL);
if (rv != 0)
return (rv);
free(ncurr);
diff --git a/stand/libsa/dev.c b/stand/libsa/dev.c
--- a/stand/libsa/dev.c
+++ b/stand/libsa/dev.c
@@ -67,3 +67,85 @@
snprintf(name, sizeof(name), "%s%d:", d->d_dev->dv_name, d->d_unit);
return (name);
}
+
+/* NB: devspec points to the remainder of the device name after dv_name */
+static int
+default_parsedev(struct devdesc **dev, const char *devspec,
+ const char **path)
+{
+ struct devdesc *idev;
+ int unit, err;
+ char *cp;
+
+ idev = malloc(sizeof(struct devdesc));
+ if (idev == NULL)
+ return (ENOMEM);
+
+ unit = 0;
+ cp = (char *)devspec; /* strtol interface, alas */
+
+ if (*devspec != '\0' && *devspec != ':') {
+ errno = 0;
+ unit = strtol(devspec, &cp, 0);
+ if (errno != 0 || cp == devspec) {
+ err = EUNIT;
+ goto fail;
+ }
+ }
+ if (*cp != '\0' && *cp != ':') {
+ err = EINVAL;
+ goto fail;
+ }
+
+ idev->d_unit = unit;
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ if (dev != NULL) /* maybe this can be required? */
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
+fail:
+ free(idev);
+ return (err);
+}
+
+/* NB: devspec points to the whole device spec, and possible trailing path */
+int
+devparse(struct devdesc **dev, const char *devspec, const char **path)
+{
+ struct devdesc *idev;
+ struct devsw *dv;
+ int i, err;
+ const char *np;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return (EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0; devsw[i] != NULL; i++) {
+ dv = devsw[i];
+ if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
+ break;
+ }
+ if (devsw[i] == NULL)
+ return (ENOENT);
+ np = devspec + strlen(dv->dv_name);
+ idev = NULL;
+ err = 0;
+ if (dv->dv_parsedev) {
+ err = dv->dv_parsedev(&idev, np, path);
+ } else {
+ err = default_parsedev(&idev, np, path);
+ }
+ if (err != 0)
+ return (err);
+
+ idev->d_dev = dv;
+ if (dev != NULL)
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
+}
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -160,6 +160,7 @@
int (*dv_print)(int verbose); /* print device information */
void (*dv_cleanup)(void);
char * (*dv_fmtdev)(struct devdesc *);
+ int (*dv_parsedev)(struct devdesc **, const char *, const char **);
};
/*
@@ -186,6 +187,7 @@
};
char *devformat(struct devdesc *d);
+int devparse(struct devdesc **, const char *, const char **);
struct open_file {
int f_flags; /* see F_* below */

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 17, 4:19 PM (21 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14682018
Default Alt Text
D37311.diff (5 KB)

Event Timeline