diff options
author | phk <phk@FreeBSD.org> | 2003-03-27 14:35:00 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-03-27 14:35:00 +0000 |
commit | 2d56ed957aaef6ee5d66bcc7c86d7832b4658de5 (patch) | |
tree | 84b36ca01e05be70dbdac8a6aee81afa4b8f1eaf /lib/libgeom | |
parent | 5447a01760d39222ce6958c12e893d7f8188883c (diff) | |
download | FreeBSD-src-2d56ed957aaef6ee5d66bcc7c86d7832b4658de5.zip FreeBSD-src-2d56ed957aaef6ee5d66bcc7c86d7832b4658de5.tar.gz |
Run a revision on the OAM api.
Use prefix gctl_ systematically.
Add flag with access perms for each argument.
Add ro/rw versions of argument building functions.
General cleanup.
Diffstat (limited to 'lib/libgeom')
-rw-r--r-- | lib/libgeom/geom_ctl.c | 205 | ||||
-rw-r--r-- | lib/libgeom/libgeom.h | 24 |
2 files changed, 136 insertions, 93 deletions
diff --git a/lib/libgeom/geom_ctl.c b/lib/libgeom/geom_ctl.c index 382d75a..e28c91f 100644 --- a/lib/libgeom/geom_ctl.c +++ b/lib/libgeom/geom_ctl.c @@ -35,29 +35,30 @@ #include <stdint.h> #include <sys/types.h> #include <stdarg.h> +#include <unistd.h> #include <string.h> #include <stdlib.h> #include <paths.h> #include <sys/queue.h> -#define GEOM_CTL_TABLE 1 +#define GCTL_TABLE 1 #include <libgeom.h> #include <geom/geom_ext.h> void -geom_ctl_dump(struct geom_ctl_req *req, FILE *f) +gctl_dump(struct gctl_req *req, FILE *f) { u_int i; int j; - struct geom_ctl_req_arg *ap; + struct gctl_req_arg *ap; if (req == NULL) { - fprintf(f, "Dump of geom_ctl request at NULL\n"); + fprintf(f, "Dump of gctl request at NULL\n"); return; } - fprintf(f, "Dump of geom_ctl %s request at %p:\n", req->reqt->name, req); + fprintf(f, "Dump of gctl %s request at %p:\n", req->reqt->name, req); if (req->error != NULL) fprintf(f, " error:\t\"%s\"\n", req->error); else @@ -68,24 +69,30 @@ geom_ctl_dump(struct geom_ctl_req *req, FILE *f) fprintf(f, " param:\t\"%s\"", ap->name); else fprintf(f, " meta:\t@%jd", (intmax_t)ap->offset); + fprintf(f, " [%s%s", + ap->flag & GCTL_PARAM_RD ? "R" : "", + ap->flag & GCTL_PARAM_WR ? "W" : ""); fflush(f); - if (ap->len < 0) - fprintf(f, " = [%d] \"%s\"", -ap->len, (char *)ap->value); + if (ap->flag & GCTL_PARAM_ASCII) + fprintf(f, "%d] = \"%s\"", ap->len, (char *)ap->value); else if (ap->len > 0) { - fprintf(f, " = [%d]", ap->len); + fprintf(f, "%d] = ", ap->len); fflush(f); for (j = 0; j < ap->len; j++) { fprintf(f, " %02x", ((u_char *)ap->value)[j]); } } else { - fprintf(f, " = [0] %p", ap->value); + fprintf(f, "0] = %p", ap->value); } fprintf(f, "\n"); } } +/* + * Set an error message, if one does not already exist. + */ static void -geom_ctl_set_error(struct geom_ctl_req *req, const char *error, ...) +gctl_set_error(struct gctl_req *req, const char *error, ...) { va_list ap; @@ -93,107 +100,145 @@ geom_ctl_set_error(struct geom_ctl_req *req, const char *error, ...) return; va_start(ap, error); vasprintf(&req->error, error, ap); + va_end(ap); } +/* + * Check that a malloc operation succeeded, and set a consistent error + * message if not. + */ static void -geom_ctl_check_alloc(struct geom_ctl_req *req, void *ptr) +gctl_check_alloc(struct gctl_req *req, void *ptr) { if (ptr != NULL) return; - geom_ctl_set_error(req, "Could not allocate memory"); + gctl_set_error(req, "Could not allocate memory"); + if (req->error == NULL) + req->error = "Could not allocate memory"; } -struct geom_ctl_req * -geom_ctl_get_handle(enum geom_ctl_request req) +/* + * Allocate a new request handle of the specified type. + * XXX: Why bother checking the type ? + */ +struct gctl_req * +gctl_get_handle(enum gctl_request req) { - struct geom_ctl_req_table *gtp; - struct geom_ctl_req *rp; + struct gctl_req_table *gtp; + struct gctl_req *rp; rp = calloc(1, sizeof *rp); if (rp == NULL) return (NULL); for (gtp = gcrt; gtp->request != req; gtp++) - if (gtp->request == GEOM_INVALID_REQUEST) + if (gtp->request == GCTL_INVALID_REQUEST) break; rp->request = req; rp->reqt = gtp; - if (rp->reqt->request == GEOM_INVALID_REQUEST) - geom_ctl_set_error(rp, "Invalid request"); + if (rp->reqt->request == GCTL_INVALID_REQUEST) + gctl_set_error(rp, "Invalid request"); return (rp); } -void -geom_ctl_set_param(struct geom_ctl_req *req, const char *name, int len, void* value) +/* + * Allocate space for another argument. + */ +static struct gctl_req_arg * +gctl_new_arg(struct gctl_req *req) { - struct geom_ctl_req_arg *ap; + struct gctl_req_arg *ap; - if (req == NULL || req->error != NULL) - return; - if (req->reqt->params == 0) - geom_ctl_set_error(req, "Request takes no parameters"); req->narg++; req->arg = realloc(req->arg, sizeof *ap * req->narg); - geom_ctl_check_alloc(req, req->arg); - if (req->arg != NULL) { - ap = req->arg + (req->narg - 1); - memset(ap, 0, sizeof *ap); - ap->name = strdup(name); - geom_ctl_check_alloc(req, ap->name); - ap->nlen = strlen(ap->name); - ap->len = len; - if (len > 0) { - ap->value = value; - } else if (len < 0) { - ap->len = -strlen(value); - ap->value = strdup(value); - } else { - ap->value = value; - } - if (len != 0) - geom_ctl_check_alloc(req, ap->value); - } else { + gctl_check_alloc(req, req->arg); + if (req->arg == NULL) { req->narg = 0; + return (NULL); } + ap = req->arg + (req->narg - 1); + memset(ap, 0, sizeof *ap); + return (ap); } void -geom_ctl_set_meta(struct geom_ctl_req *req, off_t offset, u_int len, void* value) +gctl_ro_param(struct gctl_req *req, const char *name, int len, const void* value) { - struct geom_ctl_req_arg *ap; - u_int i; + struct gctl_req_arg *ap; if (req == NULL || req->error != NULL) return; - if (req->reqt->meta == 0) - geom_ctl_set_error(req, "Request takes no meta data"); - for (i = 0; i < req->narg; i++) { - ap = &req->arg[i]; - if (ap->name != NULL) - continue; - if (ap->offset >= offset + len) - continue; - if (ap->offset + ap->len <= offset) - continue; - geom_ctl_set_error(req, "Overlapping meta data"); + ap = gctl_new_arg(req); + if (ap == NULL) return; - } - req->narg++; - req->arg = realloc(req->arg, sizeof *ap * req->narg); - geom_ctl_check_alloc(req, req->arg); - if (req->arg != NULL) { - ap = req->arg + (req->narg - 1); - memset(ap, 0, sizeof *ap); - ap->value = value; - ap->offset = offset; + ap->name = strdup(name); + gctl_check_alloc(req, ap->name); + ap->nlen = strlen(ap->name) + 1; + ap->value = __DECONST(void *, value); + ap->flag = GCTL_PARAM_RD; + if (len >= 0) ap->len = len; - } else { - req->narg = 0; + else if (len < 0) { + ap->flag |= GCTL_PARAM_ASCII; + ap->len = strlen(value) + 1; } } +void +gctl_rw_param(struct gctl_req *req, const char *name, int len, void* value) +{ + struct gctl_req_arg *ap; + + if (req == NULL || req->error != NULL) + return; + ap = gctl_new_arg(req); + if (ap == NULL) + return; + ap->name = strdup(name); + gctl_check_alloc(req, ap->name); + ap->nlen = strlen(ap->name) + 1; + ap->value = value; + ap->flag = GCTL_PARAM_RW; + if (len >= 0) + ap->len = len; + else if (len < 0) + ap->len = strlen(value) + 1; +} + +void +gctl_ro_meta(struct gctl_req *req, off_t offset, u_int len, const void* value) +{ + struct gctl_req_arg *ap; + + if (req == NULL || req->error != NULL) + return; + ap = gctl_new_arg(req); + if (ap == NULL) + return; + ap->value = __DECONST(void *, value); + ap->flag = GCTL_PARAM_RD; + ap->offset = offset; + ap->len = len; +} + +void +gctl_rw_meta(struct gctl_req *req, off_t offset, u_int len, void* value) +{ + struct gctl_req_arg *ap; + + if (req == NULL || req->error != NULL) + return; + ap = gctl_new_arg(req); + if (ap == NULL) + return; + ap->value = value; + ap->flag = GCTL_PARAM_RW; + ap->offset = offset; + ap->len = len; +} + const char * -geom_ctl_issue(struct geom_ctl_req *req) +gctl_issue(struct gctl_req *req) { int fd, error; @@ -202,16 +247,21 @@ geom_ctl_issue(struct geom_ctl_req *req) if (req->error != NULL) return (req->error); - req->version = GEOM_CTL_VERSION; + req->version = GCTL_VERSION; req->lerror = BUFSIZ; /* XXX: arbitrary number */ req->error = malloc(req->lerror); + if (req->error == NULL) { + gctl_check_alloc(req, req->error); + return (req->error); + } memset(req->error, 0, req->lerror); req->lerror--; fd = open(_PATH_DEV PATH_GEOM_CTL, O_RDONLY); if (fd < 0) return(strerror(errno)); error = ioctl(fd, GEOM_CTL, req); - if (error && errno == EINVAL && req->error[0] != '\0') + close(fd); + if (req->error[0] != '\0') return (req->error); if (error != 0) return(strerror(errno)); @@ -219,19 +269,18 @@ geom_ctl_issue(struct geom_ctl_req *req) } void -geom_ctl_free(struct geom_ctl_req *req) +gctl_free(struct gctl_req *req) { u_int i; + if (req == NULL) + return; for (i = 0; i < req->narg; i++) { if (req->arg[i].name != NULL) free(req->arg[i].name); - if (req->arg[i].len < 0) - free(req->arg[i].value); } + free(req->arg); if (req->error != NULL) free(req->error); - free(req->arg); free(req); } - diff --git a/lib/libgeom/libgeom.h b/lib/libgeom/libgeom.h index 9f00253..8b1c2e8 100644 --- a/lib/libgeom/libgeom.h +++ b/lib/libgeom/libgeom.h @@ -129,23 +129,17 @@ void geom_deletetree(struct gmesh *gmp); /* geom_ctl.c */ -struct geom_ctl_req; +struct gctl_req; #ifdef _STDIO_H_ /* limit #include pollution */ -void geom_ctl_dump(struct geom_ctl_req *req, FILE *f); +void gctl_dump(struct gctl_req *req, FILE *f); #endif -void geom_ctl_free(struct geom_ctl_req *req); -struct geom_ctl_req *geom_ctl_get_handle(enum geom_ctl_request req); -const char *geom_ctl_issue(struct geom_ctl_req *req); -void geom_ctl_set_class_by_id(struct geom_ctl_req *req, void *id); -void geom_ctl_set_class_by_name(struct geom_ctl_req *req, const char *name); -void geom_ctl_set_consumer_by_id(struct geom_ctl_req *req, void *id); -void geom_ctl_set_consumer_by_name(struct geom_ctl_req *req, const char *name); -void geom_ctl_set_geom_by_id(struct geom_ctl_req *req, void *id); -void geom_ctl_set_geom_by_name(struct geom_ctl_req *req, const char *name); -void geom_ctl_set_meta(struct geom_ctl_req *req, off_t offset, u_int len, void* val); -void geom_ctl_set_param(struct geom_ctl_req *req, const char *name, int len, void* val); -void geom_ctl_set_provider_by_id(struct geom_ctl_req *req, void *id); -void geom_ctl_set_provider_by_name(struct geom_ctl_req *req, const char *name); +void gctl_free(struct gctl_req *req); +struct gctl_req *gctl_get_handle(enum gctl_request req); +const char *gctl_issue(struct gctl_req *req); +void gctl_ro_meta(struct gctl_req *req, off_t offset, u_int len, const void* val); +void gctl_rw_meta(struct gctl_req *req, off_t offset, u_int len, void* val); +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); #endif /* _LIBGEOM_H_ */ |