diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2004-05-20 10:09:56 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2004-05-20 10:09:56 +0000 |
commit | 05c9107607357aabe7ac14b970080d2f8a7b66c9 (patch) | |
tree | b820f9f059fcb3b08d74ac32456e837299fd965a /sbin/geom/misc | |
parent | 2c88a61c15a853efdef27ff446dcdbb5be0ffbac (diff) | |
download | src-05c9107607357aabe7ac14b970080d2f8a7b66c9.tar.gz src-05c9107607357aabe7ac14b970080d2f8a7b66c9.zip |
Bring in geom(8) utility. It is an universal utility for operating on
GEOM classes. It works by loading a shared library via dlopen(3) mechanism
with class-specific code, it is also responsible for communicating with
GEOM via libgeom(3).
Per-class shared libraries are going to be stored in /lib/geom/ directory.
It provides also few standard commands like 'list', 'load' and 'unload'
for existing classes which aren't aware of geom(8).
More info will be send on freebsd-current@ mailing list.
Supported by: Wheel - Open Technologies - http://www.wheel.pl
Notes
Notes:
svn path=/head/; revision=129470
Diffstat (limited to 'sbin/geom/misc')
-rw-r--r-- | sbin/geom/misc/subr.c | 247 | ||||
-rw-r--r-- | sbin/geom/misc/subr.h | 38 |
2 files changed, 285 insertions, 0 deletions
diff --git a/sbin/geom/misc/subr.c b/sbin/geom/misc/subr.c new file mode 100644 index 000000000000..9d72e3483442 --- /dev/null +++ b/sbin/geom/misc/subr.c @@ -0,0 +1,247 @@ +/*- + * Copyright (c) 2004 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/endian.h> +#include <sys/uio.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include <assert.h> +#include <libgeom.h> + +#include "misc/subr.h" + + +struct std_metadata { + char md_magic[16]; + uint32_t md_version; +}; + +static void +std_metadata_decode(const u_char *data, struct std_metadata *md) +{ + + bcopy(data, md->md_magic, sizeof(md->md_magic)); + md->md_version = le32dec(data + 16); +} + +static void +pathgen(const char *name, char *path, size_t size) +{ + + if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) != 0) + snprintf(path, size, "%s%s", _PATH_DEV, name); + else + strlcpy(path, name, size); +} + +int +g_metadata_store(const char *name, u_char *md, size_t size) +{ + char path[MAXPATHLEN]; + unsigned sectorsize; + off_t mediasize; + u_char *sector; + int error, fd; + + pathgen(name, path, sizeof(path)); + sector = NULL; + error = 0; + + fd = open(path, O_WRONLY); + if (fd == -1) + return (errno); + if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) { + error = errno; + goto out; + } + if (ioctl(fd, DIOCGSECTORSIZE, §orsize) < 0) { + error = errno; + goto out; + } + assert(sectorsize >= size); + sector = malloc(sectorsize); + if (sector == NULL) { + error = ENOMEM; + goto out; + } + bcopy(md, sector, size); + if (pwrite(fd, sector, sectorsize, mediasize - sectorsize) != + (ssize_t)sectorsize) { + error = errno; + goto out; + } +out: + if (sector != NULL) + free(sector); + close(fd); + return (error); +} + +int +g_metadata_clear(const char *name, const char *magic) +{ + struct std_metadata md; + char path[MAXPATHLEN]; + unsigned sectorsize; + off_t mediasize; + u_char *sector; + int error, fd; + + pathgen(name, path, sizeof(path)); + sector = NULL; + error = 0; + + fd = open(path, O_RDWR); + if (fd == -1) + return (errno); + if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) { + error = errno; + goto out; + } + if (ioctl(fd, DIOCGSECTORSIZE, §orsize) < 0) { + error = errno; + goto out; + } + sector = malloc(sectorsize); + if (sector == NULL) { + error = ENOMEM; + goto out; + } + if (magic != NULL) { + if (pread(fd, sector, sectorsize, mediasize - sectorsize) != + (ssize_t)sectorsize) { + error = errno; + goto out; + } + std_metadata_decode(sector, &md); + if (strcmp(md.md_magic, magic) != 0) { + error = EINVAL; + goto out; + } + } + bzero(sector, sectorsize); + if (pwrite(fd, sector, sectorsize, mediasize - sectorsize) != + (ssize_t)sectorsize) { + error = errno; + goto out; + } +out: + if (sector != NULL) + free(sector); + close(fd); + return (error); +} + +/* + * Set an error message, if one does not already exist. + */ +void +gctl_error(struct gctl_req *req, const char *error, ...) +{ + va_list ap; + + if (req->error != NULL) + return; + va_start(ap, error); + vasprintf(&req->error, error, ap); + va_end(ap); +} + +void * +gctl_get_param(struct gctl_req *req, const char *param, int *len) +{ + unsigned i; + void *p; + struct gctl_req_arg *ap; + + for (i = 0; i < req->narg; i++) { + ap = &req->arg[i]; + if (strcmp(param, ap->name)) + continue; + if (!(ap->flag & GCTL_PARAM_RD)) + continue; + p = ap->value; + if (len != NULL) + *len = ap->len; + return (p); + } + return (NULL); +} + +char const * +gctl_get_asciiparam(struct gctl_req *req, const char *param) +{ + unsigned i; + char const *p; + struct gctl_req_arg *ap; + + for (i = 0; i < req->narg; i++) { + ap = &req->arg[i]; + if (strcmp(param, ap->name)) + continue; + if (!(ap->flag & GCTL_PARAM_RD)) + continue; + p = ap->value; + if (ap->len < 1) { + gctl_error(req, "No length argument (%s)", param); + return (NULL); + } + if (p[ap->len - 1] != '\0') { + gctl_error(req, "Unterminated argument (%s)", param); + return (NULL); + } + return (p); + } + return (NULL); +} + +void * +gctl_get_paraml(struct gctl_req *req, const char *param, int len) +{ + int i; + void *p; + + p = gctl_get_param(req, param, &i); + if (p == NULL) + gctl_error(req, "Missing %s argument", param); + else if (i != len) { + p = NULL; + gctl_error(req, "Wrong length %s argument", param); + } + return (p); +} diff --git a/sbin/geom/misc/subr.h b/sbin/geom/misc/subr.h new file mode 100644 index 000000000000..487f3db5ceb8 --- /dev/null +++ b/sbin/geom/misc/subr.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2004 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. + * + * $FreeBSD$ + */ + +#ifndef _SUBR_H_ +#define _SUBR_H_ +int g_metadata_store(const char *name, u_char *md, size_t size); +int g_metadata_clear(const char *name, const char *magic); + +void gctl_error(struct gctl_req *req, const char *error, ...); +void *gctl_get_param(struct gctl_req *req, const char *param, int *len); +char const *gctl_get_asciiparam(struct gctl_req *req, const char *param); +void *gctl_get_paraml(struct gctl_req *req, const char *param, int len); +#endif /* !_SUBR_H_ */ |