Stuff shared between ggate utilities.
This commit is contained in:
parent
af4f788a94
commit
6ac5fe4854
330
sbin/ggate/shared/ggate.c
Normal file
330
sbin/ggate/shared/ggate.c
Normal file
@ -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);
|
||||
}
|
143
sbin/ggate/shared/ggate.h
Normal file
143
sbin/ggate/shared/ggate.h
Normal file
@ -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_ */
|
Loading…
Reference in New Issue
Block a user