Implement and document some utility functions that can be used to communicate

with GEOM providers.

OK'ed by:	phk
This commit is contained in:
Pawel Jakub Dawidek 2007-05-06 01:17:46 +00:00
parent e15b9720f1
commit fbda685d38
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169299
4 changed files with 360 additions and 3 deletions

View File

@ -6,6 +6,7 @@ SRCS+= geom_getxml.c
SRCS+= geom_stats.c
SRCS+= geom_xml2tree.c
SRCS+= geom_ctl.c
SRCS+= geom_util.c
INCS= libgeom.h
CFLAGS += -I${.CURDIR}
@ -31,6 +32,15 @@ MLINKS+= \
libgeom.3 gctl_rw_param.3 \
libgeom.3 gctl_issue.3 \
libgeom.3 gctl_free.3 \
libgeom.3 gctl_dump.3
libgeom.3 gctl_dump.3 \
libgeom.3 g_close.3 \
libgeom.3 g_delete.3 \
libgeom.3 g_flush.3 \
libgeom.3 g_get_ident.3 \
libgeom.3 g_get_name.3 \
libgeom.3 g_mediasize.3 \
libgeom.3 g_open.3 \
libgeom.3 g_open_by_ident.3 \
libgeom.3 g_sectorsize.3
.include <bsd.lib.mk>

236
lib/libgeom/geom_util.c Normal file
View File

@ -0,0 +1,236 @@
/*-
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/disk.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <paths.h>
#include <libgeom.h>
/*
* Open the given provider and at least check if this is a block device.
*/
int
g_open(const char *name, int write)
{
char path[MAXPATHLEN];
int fd;
if (name[0] == '/')
strlcpy(path, name, sizeof(path));
else
snprintf(path, sizeof(path), "%s%s", _PATH_DEV, name);
fd = open(path, write ? O_RDWR : O_RDONLY);
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);
}
int
g_close(int fd)
{
return (close(fd));
}
static int
g_ioctl_arg(int fd, unsigned long cmd, void *arg)
{
int ret;
if (arg != NULL)
ret = ioctl(fd, cmd, arg);
else
ret = ioctl(fd, cmd);
return (ret >= 0 ? 0 : -1);
}
static int
g_ioctl(int fd, unsigned long cmd)
{
return (g_ioctl_arg(fd, cmd, NULL));
}
/*
* Return media size of the given provider.
*/
off_t
g_mediasize(int fd)
{
off_t mediasize;
if (g_ioctl_arg(fd, DIOCGMEDIASIZE, &mediasize) == -1)
mediasize = -1;
return (mediasize);
}
/*
* Return sector size of the given provider.
*/
ssize_t
g_sectorsize(int fd)
{
u_int sectorsize;
if (g_ioctl_arg(fd, DIOCGSECTORSIZE, &sectorsize) == -1)
return (-1);
return ((ssize_t)sectorsize);
}
/*
* Call BIO_FLUSH for the given provider.
*/
int
g_flush(int fd)
{
return (g_ioctl(fd, DIOCGFLUSH));
}
/*
* Call BIO_DELETE for the given range.
*/
int
g_delete(int fd, off_t offset, off_t length)
{
off_t arg[2];
arg[0] = offset;
arg[1] = length;
return (g_ioctl_arg(fd, DIOCGDELETE, arg));
}
/*
* Return ID of the given provider.
*/
int
g_get_ident(int fd, char *ident, size_t size)
{
char lident[DISK_IDENT_SIZE];
if (g_ioctl_arg(fd, DIOCGIDENT, lident) == -1)
return (-1);
if (lident[0] == '\0') {
errno = ENOENT;
return (-1);
}
if (strlcpy(ident, lident, size) >= size) {
errno = ENAMETOOLONG;
return (-1);
}
return (0);
}
/*
* Return name of the provider, which has the given ID.
*/
int
g_get_name(const char *ident, char *name, size_t size)
{
int fd;
fd = g_open_by_ident(ident, 0, name, size);
if (fd == -1)
return (-1);
g_close(fd);
return (0);
}
/*
* Find provider name by the given ID.
*/
int
g_open_by_ident(const char *ident, int write, char *name, size_t size)
{
char lident[DISK_IDENT_SIZE];
struct gmesh mesh;
struct gclass *mp;
struct ggeom *gp;
struct gprovider *pp;
int error, fd;
error = geom_gettree(&mesh);
if (error != 0) {
errno = error;
return (-1);
}
error = ENOENT;
fd = -1;
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
fd = g_open(pp->lg_name, write);
if (fd == -1)
continue;
if (g_get_ident(fd, lident,
sizeof(lident)) == -1) {
g_close(fd);
continue;
}
if (strcmp(ident, lident) != 0) {
g_close(fd);
continue;
}
error = 0;
if (name != NULL && strlcpy(name, pp->lg_name,
size) >= size) {
error = ENAMETOOLONG;
g_close(fd);
}
goto end;
}
}
}
end:
geom_deletetree(&mesh);
if (error != 0) {
errno = error;
return (-1);
}
return (fd);
}

View File

@ -1,4 +1,5 @@
.\" Copyright (c) 2003 Poul-Henning Kamp
.\" Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -27,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 7, 2004
.Dd May 6, 2007
.Dt LIBGEOM 3
.Os
.Sh NAME
@ -44,7 +45,16 @@
.Nm gctl_rw_param ,
.Nm gctl_issue ,
.Nm gctl_free ,
.Nm gctl_dump
.Nm gctl_dump ,
.Nm g_open ,
.Nm g_close ,
.Nm g_mediasize ,
.Nm g_sectorsize ,
.Nm g_flush ,
.Nm g_delete ,
.Nm g_get_ident ,
.Nm g_get_name ,
.Nm g_open_by_ident
.Nd userland API library for kernel GEOM subsystem
.Sh LIBRARY
.Lb libgeom
@ -80,6 +90,25 @@
.Fn gctl_free "struct gctl_req *req"
.Ft void
.Fn gctl_dump "struct gctl_req *req" "FILE *f"
.Ss "Utility Functions"
.Ft int
.Fn g_open "const char *name" "int write"
.Ft int
.Fn g_close "int fd"
.Ft off_t
.Fn g_mediasize "int fd"
.Ft ssize_t
.Fn g_sectorsize "int fd"
.Ft int
.Fn g_flush "int fd"
.Ft int
.Fn g_delete "int fd" "off_t offset" "off_t length"
.Ft int
.Fn g_get_ident "int fd" "char *ident" "size_t size"
.Ft int
.Fn g_get_name "const char *ident" "char *name" "size_t size"
.Ft int
.Fn g_open_by_ident "const char *ident" "int write" "char *name" "size_t size"
.Sh DESCRIPTION
The
.Nm geom
@ -232,6 +261,76 @@ which returns
.Dv NULL
on success, or an error message corresponding to the
first error which happened.
.Ss "Utility Functions"
The
.Fn g_*
functions are used to communicate with GEOM providers.
.Pp
The
.Fn g_open
function opens the given provider and returns file descriptor number, which can
be used with other functions.
The
.Fa write
argument indicates if operations that modify the provider (like
.Fn g_flush
or
.Fn g_delete )
are going to be called.
.Pp
The
.Fn g_close
function closes the provider.
.Pp
The
.Fn g_mediasize
function returns size of the given provider.
.Pp
The
.Fn g_sectorsize
function returns sector size of the given provider.
.Pp
The
.Fn g_flush
function sends
.Dv BIO_FLUSH
request to flush write cache of the provider.
.Pp
The
.Fn g_delete
function tells the provider that the given data range is no longer used.
.Pp
The
.Fn g_get_ident
function returns provider's fixed and unique identifier.
The
.Fa ident
argument should be at least
.Dv DISK_IDENT_SIZE
big.
.Pp
The
.Fn g_get_name
function returns name of the provider, which identifier is equal to the
.Fa ident
string.
.Pp
The
.Fn g_open_by_ident
function opens provider using its ident, unlike
.Fn g_open
which uses provider's name.
If the
.Fa name
argument is not
.Dv NULL ,
the function will store provider's name there.
.Pp
All functions return value greater than or equal to
.Va 0
on success or
.Va -1
on failure.
.Sh EXAMPLES
Create a request that is to be sent to the CCD class, and tell
it to destroy a specific geom:
@ -256,3 +355,4 @@ library appeared in
.Sh AUTHORS
.An Poul-Henning Kamp Aq phk@FreeBSD.org
.An Lukas Ertl Aq le@FreeBSD.org
.An Pawel Jakub Dawidek pjd@FreeBSD.org

View File

@ -144,6 +144,17 @@ const char *gctl_issue(struct gctl_req *req);
void gctl_ro_param(struct gctl_req *req, const char *name, int len, const void* val);
void gctl_rw_param(struct gctl_req *req, const char *name, int len, void* val);
/* geom_util.c */
int g_open(const char *name, int write);
int g_close(int fd);
off_t g_mediasize(int fd);
ssize_t g_sectorsize(int fd);
int g_flush(int fd);
int g_delete(int fd, off_t offset, off_t length);
int g_get_ident(int fd, char *ident, size_t size);
int g_get_name(const char *ident, char *name, size_t size);
int g_open_by_ident(const char *ident, int write, char *name, size_t size);
__END_DECLS
#endif /* _LIBGEOM_H_ */