summaryrefslogtreecommitdiffstats
path: root/sbin/ggate
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2004-04-30 16:13:45 +0000
committerpjd <pjd@FreeBSD.org>2004-04-30 16:13:45 +0000
commitb0399e5dbaaae46ddda9b22ca11e9d087e5006c6 (patch)
tree93cab1890ea3da3d8c7372a4d4df6a5de62f7616 /sbin/ggate
parentdbf20e6f7f731c598930774ccc0573a36ec0e0d3 (diff)
downloadFreeBSD-src-b0399e5dbaaae46ddda9b22ca11e9d087e5006c6.zip
FreeBSD-src-b0399e5dbaaae46ddda9b22ca11e9d087e5006c6.tar.gz
Stuff shared between ggate utilities.
Diffstat (limited to 'sbin/ggate')
-rw-r--r--sbin/ggate/shared/ggate.c330
-rw-r--r--sbin/ggate/shared/ggate.h143
2 files changed, 473 insertions, 0 deletions
diff --git a/sbin/ggate/shared/ggate.c b/sbin/ggate/shared/ggate.c
new file mode 100644
index 0000000..9002b91
--- /dev/null
+++ b/sbin/ggate/shared/ggate.c
@@ -0,0 +1,330 @@
+/*-
+ * 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$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <sys/disk.h>
+#include <sys/stat.h>
+#include <sys/endian.h>
+#include <sys/socket.h>
+#include <sys/linker.h>
+#include <sys/module.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <signal.h>
+#include <err.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <libgen.h>
+#include <netdb.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <libgeom.h>
+
+#include <geom/gate/g_gate.h>
+#include "ggate.h"
+
+
+int g_gate_devfd = -1;
+int g_gate_verbose = 0;
+
+
+void
+g_gate_vlog(int priority, const char *message, va_list ap)
+{
+
+ if (g_gate_verbose) {
+ const char *prefix;
+
+ switch (priority) {
+ case LOG_ERR:
+ prefix = "error";
+ break;
+ case LOG_WARNING:
+ prefix = "warning";
+ break;
+ case LOG_NOTICE:
+ prefix = "notice";
+ break;
+ case LOG_INFO:
+ prefix = "info";
+ break;
+ case LOG_DEBUG:
+ prefix = "debug";
+ break;
+ default:
+ prefix = "unknown";
+ }
+
+ printf("%s: ", prefix);
+ vprintf(message, ap);
+ printf("\n");
+ } else {
+ if (priority != LOG_DEBUG)
+ vsyslog(priority, message, ap);
+ }
+}
+
+void
+g_gate_log(int priority, const char *message, ...)
+{
+ va_list ap;
+
+ va_start(ap, message);
+ g_gate_vlog(priority, message, ap);
+ va_end(ap);
+}
+
+void
+g_gate_xvlog(const char *message, va_list ap)
+{
+
+ g_gate_vlog(LOG_ERR, message, ap);
+ g_gate_vlog(LOG_ERR, "Exiting.", ap);
+ exit(EXIT_FAILURE);
+}
+
+void
+g_gate_xlog(const char *message, ...)
+{
+ va_list ap;
+
+ va_start(ap, message);
+ g_gate_xvlog(message, ap);
+ /* NOTREACHED */
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+off_t
+g_gate_mediasize(int fd)
+{
+ off_t mediasize;
+ struct stat sb;
+
+ if (fstat(fd, &sb) < 0)
+ g_gate_xlog("fstat(): %s.", strerror(errno));
+ if (S_ISCHR(sb.st_mode)) {
+ if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) {
+ g_gate_xlog("Can't get media size: %s.",
+ strerror(errno));
+ }
+ } else if (S_ISREG(sb.st_mode)) {
+ mediasize = sb.st_size;
+ } else {
+ g_gate_xlog("Unsupported file system object.");
+ }
+ return (mediasize);
+}
+
+size_t
+g_gate_sectorsize(int fd)
+{
+ size_t secsize;
+ struct stat sb;
+
+ if (fstat(fd, &sb) < 0)
+ g_gate_xlog("fstat(): %s.", strerror(errno));
+ if (S_ISCHR(sb.st_mode)) {
+ if (ioctl(fd, DIOCGSECTORSIZE, &secsize) < 0) {
+ g_gate_xlog("Can't get sector size: %s.",
+ strerror(errno));
+ }
+ } else if (S_ISREG(sb.st_mode)) {
+ secsize = 512;
+ } else {
+ g_gate_xlog("Unsupported file system object.");
+ }
+ return (secsize);
+}
+
+void
+g_gate_open_device(void)
+{
+
+ g_gate_devfd = open("/dev/" G_GATE_CTL_NAME, O_RDWR, 0);
+ if (g_gate_devfd < 0)
+ err(EXIT_FAILURE, "open(/dev/%s)", G_GATE_CTL_NAME);
+}
+
+void
+g_gate_close_device(void)
+{
+
+ close(g_gate_devfd);
+}
+
+void
+g_gate_ioctl(unsigned long req, void *data)
+{
+
+ if (ioctl(g_gate_devfd, req, data) < 0) {
+ g_gate_xlog("%s: ioctl(/dev/%s): %s.", getprogname(),
+ G_GATE_CTL_NAME, strerror(errno));
+ }
+}
+
+void
+g_gate_destroy(int unit, int force)
+{
+ struct g_gate_ctl_destroy ggio;
+
+ ggio.gctl_version = G_GATE_VERSION;
+ ggio.gctl_unit = unit;
+ ggio.gctl_force = force;
+ g_gate_ioctl(G_GATE_CMD_DESTROY, &ggio);
+}
+
+int
+g_gate_openflags(unsigned ggflags)
+{
+
+ if ((ggflags & G_GATE_FLAG_READONLY) != 0)
+ return (O_RDONLY);
+ else if ((ggflags & G_GATE_FLAG_WRITEONLY) != 0)
+ return (O_WRONLY);
+ return (O_RDWR);
+}
+
+void
+g_gate_load_module(void)
+{
+
+ if (modfind("g_gate") < 0) {
+ /* Not present in kernel, try loading it. */
+ if (kldload("geom_gate") < 0 || modfind("g_gate") < 0) {
+ if (errno != EEXIST) {
+ errx(EXIT_FAILURE,
+ "geom_gate module not available!");
+ }
+ }
+ }
+}
+
+#ifdef LIBGEOM
+static struct gclass *
+find_class(struct gmesh *mesh, const char *name)
+{
+ struct gclass *class;
+
+ LIST_FOREACH(class, &mesh->lg_class, lg_class) {
+ if (strcmp(class->lg_name, name) == 0)
+ return (class);
+ }
+ return (NULL);
+}
+
+static const char *
+get_conf(struct ggeom *gp, const char *name)
+{
+ struct gconfig *conf;
+
+ LIST_FOREACH(conf, &gp->lg_config, lg_config) {
+ if (strcmp(conf->lg_name, name) == 0)
+ return (conf->lg_val);
+ }
+ return (NULL);
+}
+
+static void
+show_config(struct ggeom *gp, int verbose)
+{
+ struct gprovider *pp;
+
+ pp = LIST_FIRST(&gp->lg_provider);
+ if (pp == NULL)
+ return;
+ if (!verbose) {
+ printf("%s\n", pp->lg_name);
+ return;
+ }
+ printf(" NAME: %s\n", pp->lg_name);
+ printf(" info: %s\n", get_conf(gp, "info"));
+ printf(" access: %s\n", get_conf(gp, "access"));
+ printf(" timeout: %s\n", get_conf(gp, "timeout"));
+ printf("queue_count: %s\n", get_conf(gp, "queue_count"));
+ printf(" queue_size: %s\n", get_conf(gp, "queue_size"));
+ printf(" references: %s\n", get_conf(gp, "ref"));
+ printf(" mediasize: %jd\n", pp->lg_mediasize);
+ printf(" sectorsize: %u\n", pp->lg_sectorsize);
+ printf(" mode: %s\n", pp->lg_mode);
+ printf("\n");
+}
+
+void
+g_gate_list(int unit, int verbose)
+{
+ struct gmesh mesh;
+ struct gclass *class;
+ struct ggeom *gp;
+ char name[64];
+ int error;
+
+ error = geom_gettree(&mesh);
+ if (error != 0)
+ exit(EXIT_FAILURE);
+ class = find_class(&mesh, G_GATE_CLASS_NAME);
+ if (class == NULL) {
+ geom_deletetree(&mesh);
+ exit(EXIT_SUCCESS);
+ }
+ if (unit >= 0) {
+ snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME,
+ unit);
+ }
+ LIST_FOREACH(gp, &class->lg_geom, lg_geom) {
+ if (unit != -1 && strcmp(gp->lg_name, name) != 0)
+ continue;
+ show_config(gp, verbose);
+ }
+ geom_deletetree(&mesh);
+ exit(EXIT_SUCCESS);
+}
+#endif /* LIBGEOM */
+
+in_addr_t
+g_gate_str2ip(const char *str)
+{
+ struct hostent *hp;
+ in_addr_t ip;
+
+ ip = inet_addr(str);
+ if (ip != INADDR_NONE) {
+ /* It is a valid IP address. */
+ return (ip);
+ }
+ /* Check if it is a valid host name. */
+ hp = gethostbyname(str);
+ if (hp == NULL)
+ return (INADDR_NONE);
+ return (((struct in_addr *)(hp->h_addr))->s_addr);
+}
diff --git a/sbin/ggate/shared/ggate.h b/sbin/ggate/shared/ggate.h
new file mode 100644
index 0000000..d4d8253
--- /dev/null
+++ b/sbin/ggate/shared/ggate.h
@@ -0,0 +1,143 @@
+/*-
+ * 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 _GGATE_H_
+#define _GGATE_H_
+
+#include <sys/endian.h>
+
+#define G_GATE_BUFSIZE_START 65536
+#define G_GATE_PORT 3080
+
+#define G_GATE_RCVBUF 131072
+#define G_GATE_SNDBUF 131072
+#define G_GATE_QUEUE_SIZE 1024
+#define G_GATE_TIMEOUT 30
+
+extern int g_gate_devfd;
+extern int g_gate_verbose;
+
+/* Client's initial packet. */
+struct g_gate_cinit {
+ char gc_path[PATH_MAX + 1];
+ uint8_t gc_flags;
+};
+
+/* Server's initial packet. */
+struct g_gate_sinit {
+ uint8_t gs_flags;
+ uint64_t gs_mediasize;
+ uint32_t gs_sectorsize;
+ uint16_t gs_error;
+};
+
+/* Control struct. */
+struct g_gate_hdr {
+ uint8_t gh_cmd; /* command */
+ uint64_t gh_offset; /* device offset */
+ uint32_t gh_length; /* size of block */
+ int16_t gh_error; /* error value (0 if ok) */
+};
+
+void g_gate_vlog(int priority, const char *message, va_list ap);
+void g_gate_log(int priority, const char *message, ...);
+void g_gate_xvlog(const char *message, va_list ap);
+void g_gate_xlog(const char *message, ...);
+off_t g_gate_mediasize(int fd);
+size_t g_gate_sectorsize(int fd);
+void g_gate_open_device(void);
+void g_gate_close_device(void);
+void g_gate_ioctl(unsigned long req, void *data);
+void g_gate_destroy(int unit, int force);
+int g_gate_openflags(unsigned ggflags);
+void g_gate_load_module(void);
+#ifdef LIBGEOM
+void g_gate_list(int unit, int verbose);
+#endif
+in_addr_t g_gate_str2ip(const char *str);
+
+/*
+ * g_gate_swap2h_* - functions swap bytes to host byte order (from big endian).
+ * g_gate_swap2n_* - functions swap bytes to network byte order (actually
+ * to big endian byte order).
+ */
+
+static __inline void
+g_gate_swap2h_cinit(struct g_gate_cinit *cinit __unused)
+{
+
+ /* Nothing here for now. */
+}
+
+static __inline void
+g_gate_swap2n_cinit(struct g_gate_cinit *cinit __unused)
+{
+
+ /* Nothing here for now. */
+}
+
+static __inline void
+g_gate_swap2h_sinit(struct g_gate_sinit *sinit)
+{
+
+ /* Swap only used fields. */
+ sinit->gs_mediasize = be64toh(sinit->gs_mediasize);
+ sinit->gs_sectorsize = be32toh(sinit->gs_sectorsize);
+ sinit->gs_error = be16toh(sinit->gs_error);
+}
+
+static __inline void
+g_gate_swap2n_sinit(struct g_gate_sinit *sinit)
+{
+
+ /* Swap only used fields. */
+ sinit->gs_mediasize = htobe64(sinit->gs_mediasize);
+ sinit->gs_sectorsize = htobe32(sinit->gs_sectorsize);
+ sinit->gs_error = htobe16(sinit->gs_error);
+}
+
+static __inline void
+g_gate_swap2h_hdr(struct g_gate_hdr *hdr)
+{
+
+ /* Swap only used fields. */
+ hdr->gh_offset = be64toh(hdr->gh_offset);
+ hdr->gh_length = be32toh(hdr->gh_length);
+ hdr->gh_error = be16toh(hdr->gh_error);
+}
+
+static __inline void
+g_gate_swap2n_hdr(struct g_gate_hdr *hdr)
+{
+
+ /* Swap only used fields. */
+ hdr->gh_offset = htobe64(hdr->gh_offset);
+ hdr->gh_length = htobe32(hdr->gh_length);
+ hdr->gh_error = htobe16(hdr->gh_error);
+}
+#endif /* _GGATE_H_ */
OpenPOWER on IntegriCloud