From 8c52b542c0de3a703a273d3ef92e1d9ba8ea23e1 Mon Sep 17 00:00:00 2001 From: lulf Date: Sun, 7 Sep 2008 13:54:57 +0000 Subject: - Add a new ioctl for getting the provider name of a geom provider. - Add a routine for looking up a device and checking if it is a valid geom provider given a partial or full path to its device node. Reviewed by: phk Approved by: pjd (mentor) --- lib/libgeom/geom_util.c | 106 ++++++++++++++++++++++++++++++++++++++++++------ lib/libgeom/libgeom.h | 2 + 2 files changed, 95 insertions(+), 13 deletions(-) (limited to 'lib/libgeom') diff --git a/lib/libgeom/geom_util.c b/lib/libgeom/geom_util.c index c596178..539b6c6 100644 --- a/lib/libgeom/geom_util.c +++ b/lib/libgeom/geom_util.c @@ -42,29 +42,22 @@ __FBSDID("$FreeBSD$"); #include +static char *g_device_path_open(const char *, int *, int); + /* * Open the given provider and at least check if this is a block device. */ int g_open(const char *name, int dowrite) { - char path[MAXPATHLEN]; + char *path; int fd; - if (name[0] == '/') - strlcpy(path, name, sizeof(path)); - else - snprintf(path, sizeof(path), "%s%s", _PATH_DEV, name); - - fd = open(path, dowrite ? O_RDWR : O_RDONLY); + path = g_device_path_open(name, &fd, dowrite); + if (path != NULL) + free(path); if (fd == -1) return (-1); - /* Let try to get sectorsize, which will prove it is a GEOM provider. */ - if (g_sectorsize(fd) == -1) { - close(fd); - errno = EFTYPE; - return (-1); - } return (fd); } @@ -121,6 +114,19 @@ g_sectorsize(int fd) } /* + * Return the correct provider name. + */ +char * +g_providername(int fd) +{ + char name[MAXPATHLEN]; + + if (g_ioctl_arg(fd, DIOCGPROVIDERNAME, name) == -1) + return (NULL); + return (strdup(name)); +} + +/* * Call BIO_FLUSH for the given provider. */ int @@ -234,3 +240,77 @@ end: } return (fd); } + +/* + * Return the device path device given a partial or full path to its node. + * A pointer can be provided, which will be set to an opened file descriptor of + * not NULL. + */ +static char * +g_device_path_open(const char *devpath, int *fdp, int dowrite) +{ + char *path; + int fd; + + /* Make sure that we can fail. */ + if (fdp != NULL) + *fdp = -1; + /* Use the device node if we're able to open it. */ + do { + fd = open(devpath, dowrite ? O_RDWR : O_RDONLY); + if (fd == -1) + break; + /* + * Let try to get sectorsize, which will prove it is a GEOM + * provider. + */ + if (g_sectorsize(fd) == -1) { + close(fd); + errno = EFTYPE; + return (NULL); + } + if ((path = strdup(devpath)) == NULL) { + close(fd); + return (NULL); + } + if (fdp != NULL) + *fdp = fd; + else + close(fd); + return (path); + } while (0); + + /* If we're not given an absolute path, assume /dev/ prefix. */ + if (*devpath != '/') { + asprintf(&path, "%s%s", _PATH_DEV, devpath); + if (path == NULL) + return (NULL); + fd = open(path, dowrite ? O_RDWR : O_RDONLY); + if (fd == -1) { + free(path); + return (NULL); + } + /* + * Let try to get sectorsize, which will prove it is a GEOM + * provider. + */ + if (g_sectorsize(fd) == -1) { + free(path); + close(fd); + errno = EFTYPE; + return (NULL); + } + if (fdp != NULL) + *fdp = fd; + else + close(fd); + return (path); + } + return (NULL); +} + +char * +g_device_path(const char *devpath) +{ + return (g_device_path_open(devpath, NULL, 0)); +} diff --git a/lib/libgeom/libgeom.h b/lib/libgeom/libgeom.h index 56736a3..7255bd4 100644 --- a/lib/libgeom/libgeom.h +++ b/lib/libgeom/libgeom.h @@ -154,6 +154,8 @@ int g_delete(int, off_t, off_t); int g_get_ident(int, char *, size_t); int g_get_name(const char *, char *, size_t); int g_open_by_ident(const char *, int, char *, size_t); +char *g_device_path(const char *); +char *g_providername(int); __END_DECLS -- cgit v1.1