| @@ -1,4 +1,7 @@ | |||||
| ggate working tree | |||||
| ================== | |||||
| https ggate working tree | |||||
| ======================== | |||||
| This is a working tree for ggate work. | This is a working tree for ggate work. | ||||
| This is a variant of ggatec using http(s) GET/PUT instead of talking | |||||
| to ggated. | |||||
| @@ -1,13 +0,0 @@ | |||||
| # $FreeBSD$ | |||||
| .PATH: ${.CURDIR:H}/shared | |||||
| PROG= ggated | |||||
| MAN= ggated.8 | |||||
| SRCS= ggated.c ggate.c | |||||
| LDADD= -lpthread -lutil | |||||
| CFLAGS+= -I${.CURDIR:H}/shared | |||||
| .include <bsd.prog.mk> | |||||
| @@ -1,21 +0,0 @@ | |||||
| # $FreeBSD$ | |||||
| # Autogenerated - do NOT edit! | |||||
| DIRDEPS = \ | |||||
| gnu/lib/csu \ | |||||
| include \ | |||||
| include/arpa \ | |||||
| include/xlocale \ | |||||
| lib/${CSU_DIR} \ | |||||
| lib/libc \ | |||||
| lib/libcompiler_rt \ | |||||
| lib/libgeom \ | |||||
| lib/libthr \ | |||||
| lib/libutil \ | |||||
| .include <dirdeps.mk> | |||||
| .if ${DEP_RELDIR} == ${_DEP_RELDIR} | |||||
| # local dependencies - needed for -jN in clean tree | |||||
| .endif | |||||
| @@ -1,134 +0,0 @@ | |||||
| .\" 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$ | |||||
| .\" | |||||
| .Dd September 8, 2016 | |||||
| .Dt GGATED 8 | |||||
| .Os | |||||
| .Sh NAME | |||||
| .Nm ggated | |||||
| .Nd "GEOM Gate network daemon" | |||||
| .Sh SYNOPSIS | |||||
| .Nm | |||||
| .Op Fl h | |||||
| .Op Fl n | |||||
| .Op Fl v | |||||
| .Op Fl a Ar address | |||||
| .Op Fl p Ar port | |||||
| .Op Fl q Ar queue_size | |||||
| .Op Fl F Ar pidfile | |||||
| .Op Fl R Ar rcvbuf | |||||
| .Op Fl S Ar sndbuf | |||||
| .Op Ar "exports file" | |||||
| .Sh DESCRIPTION | |||||
| The | |||||
| .Nm | |||||
| utility is a network server for the GEOM Gate class. | |||||
| It runs on a server machine to service GEOM Gate requests from workers | |||||
| placed on a client machine. | |||||
| Keep in mind, that connections between | |||||
| .Xr ggatec 8 | |||||
| and | |||||
| .Nm | |||||
| are not encrypted. | |||||
| .Pp | |||||
| Available options: | |||||
| .Bl -tag -width ".Ar exports\ file" | |||||
| .It Fl a Ar address | |||||
| Specifies an IP address to bind to. | |||||
| .It Fl h | |||||
| Print available options. | |||||
| .It Fl n | |||||
| Do not use | |||||
| .Dv TCP_NODELAY | |||||
| option on TCP sockets. | |||||
| .It Fl p Ar port | |||||
| Port on which | |||||
| .Nm | |||||
| listens for connections. | |||||
| Default is 3080. | |||||
| .It Fl q Ar queue_size | |||||
| The number of IOs to queue to the disks at once. | |||||
| The default is 20. | |||||
| If you have a large number of disks and/or you are not seeing the expected | |||||
| number of IOPS, increase this parameter. | |||||
| .It Fl F Ar pidfile | |||||
| PID file that | |||||
| .Nm | |||||
| uses. | |||||
| .It Fl R Ar rcvbuf | |||||
| Size of receive buffer to use. | |||||
| When not specified, the system default is used. | |||||
| .It Fl S Ar sndbuf | |||||
| Size of send buffer to use. | |||||
| When not specified, the system default is used. | |||||
| .It Fl v | |||||
| Do not fork, run in foreground and print debug information on standard | |||||
| output. | |||||
| .It Ar "exports file" | |||||
| An alternate location for the exports file. | |||||
| .El | |||||
| .Pp | |||||
| The format of an exports file is as follows: | |||||
| .Bd -literal -offset indent | |||||
| 1.2.3.4 RO /dev/cd0 | |||||
| 1.2.3.0/24 RW /tmp/test.img | |||||
| hostname WO /tmp/image | |||||
| .Ed | |||||
| .Sh FILES | |||||
| .Bl -tag -width ".Pa /var/run/ggated.pid" -compact | |||||
| .It Pa /var/run/ggated.pid | |||||
| The default location of the | |||||
| .Nm | |||||
| PID file. | |||||
| .El | |||||
| .Sh EXIT STATUS | |||||
| Exit status is 0 on success, or 1 if the command fails. | |||||
| To get details about the failure, | |||||
| .Nm | |||||
| should be called with the | |||||
| .Fl v | |||||
| option. | |||||
| .Sh EXAMPLES | |||||
| Export CD-ROM device and a file: | |||||
| .Bd -literal -offset indent | |||||
| # echo "1.2.3.0/24 RO /dev/cd0" > /etc/gg.exports | |||||
| # echo "client RW /image" >> /etc/gg.exports | |||||
| # ggated | |||||
| .Ed | |||||
| .Sh SEE ALSO | |||||
| .Xr geom 4 , | |||||
| .Xr ggatec 8 , | |||||
| .Xr ggatel 8 | |||||
| .Sh HISTORY | |||||
| The | |||||
| .Nm | |||||
| utility appeared in | |||||
| .Fx 5.3 . | |||||
| .Sh AUTHORS | |||||
| The | |||||
| .Nm | |||||
| utility as well as this manual page was written by | |||||
| .An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org . | |||||
| @@ -1,14 +0,0 @@ | |||||
| # $FreeBSD$ | |||||
| .PATH: ${.CURDIR:H}/shared | |||||
| PROG= ggatel | |||||
| MAN= ggatel.8 | |||||
| SRCS= ggatel.c ggate.c | |||||
| CFLAGS+= -DLIBGEOM | |||||
| CFLAGS+= -I${.CURDIR:H}/shared | |||||
| LDADD= -lgeom -lutil | |||||
| .include <bsd.prog.mk> | |||||
| @@ -1,22 +0,0 @@ | |||||
| # $FreeBSD$ | |||||
| # Autogenerated - do NOT edit! | |||||
| DIRDEPS = \ | |||||
| gnu/lib/csu \ | |||||
| include \ | |||||
| include/arpa \ | |||||
| include/xlocale \ | |||||
| lib/${CSU_DIR} \ | |||||
| lib/libc \ | |||||
| lib/libcompiler_rt \ | |||||
| lib/libexpat \ | |||||
| lib/libgeom \ | |||||
| lib/libsbuf \ | |||||
| lib/libutil \ | |||||
| .include <dirdeps.mk> | |||||
| .if ${DEP_RELDIR} == ${_DEP_RELDIR} | |||||
| # local dependencies - needed for -jN in clean tree | |||||
| .endif | |||||
| @@ -1,164 +0,0 @@ | |||||
| .\" 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$ | |||||
| .\" | |||||
| .Dd September 8, 2016 | |||||
| .Dt GGATEL 8 | |||||
| .Os | |||||
| .Sh NAME | |||||
| .Nm ggatel | |||||
| .Nd "GEOM Gate local control utility" | |||||
| .Sh SYNOPSIS | |||||
| .Nm | |||||
| .Cm create | |||||
| .Op Fl v | |||||
| .Op Fl o Cm ro | wo | rw | |||||
| .Op Fl s Ar sectorsize | |||||
| .Op Fl t Ar timeout | |||||
| .Op Fl u Ar unit | |||||
| .Ar path | |||||
| .Nm | |||||
| .Cm destroy | |||||
| .Op Fl f | |||||
| .Fl u Ar unit | |||||
| .Nm | |||||
| .Cm list | |||||
| .Op Fl v | |||||
| .Op Fl u Ar unit | |||||
| .Nm | |||||
| .Cm rescue | |||||
| .Op Fl v | |||||
| .Op Fl o Cm ro | wo | rw | |||||
| .Fl u Ar unit | |||||
| .Ar path | |||||
| .Sh DESCRIPTION | |||||
| The | |||||
| .Nm | |||||
| utility is a local GEOM Gate class consumer. | |||||
| It can be used as a replacement for | |||||
| .Xr md 4 | |||||
| devices or as a | |||||
| .Dq GEOMificator | |||||
| for non GEOM-aware devices, but it was mainly created as an example | |||||
| on how to use and how to communicate with the GEOM Gate kernel subsystem. | |||||
| .Pp | |||||
| Available commands: | |||||
| .Bl -tag -width ".Cm destroy" | |||||
| .It Cm create | |||||
| Create a | |||||
| .Nm ggate | |||||
| provider related to the given regular file or device. | |||||
| .It Cm destroy | |||||
| Destroy the given | |||||
| .Nm ggate | |||||
| provider. | |||||
| .It Cm list | |||||
| List | |||||
| .Nm ggate | |||||
| providers. | |||||
| .It Cm rescue | |||||
| Take over a previously created provider and handle pending and future | |||||
| requests. | |||||
| This is useful if the initial | |||||
| .Nm | |||||
| process died. | |||||
| To prevent data loss, the given path must lead to the | |||||
| regular file or device that was used to create the provider. | |||||
| .El | |||||
| .Pp | |||||
| Available options: | |||||
| .Bl -tag -width ".Fl s Cm ro | wo | rw" | |||||
| .It Fl f | |||||
| Forcibly destroy | |||||
| .Nm ggate | |||||
| provider (cancels all pending requests). | |||||
| .It Fl o Cm ro | wo | rw | |||||
| Specify permissions to use when opening the file or device: read-only | |||||
| .Pq Cm ro , | |||||
| write-only | |||||
| .Pq Cm wo , | |||||
| or read-write | |||||
| .Pq Cm rw . | |||||
| Default is | |||||
| .Cm rw . | |||||
| .It Fl s Ar sectorsize | |||||
| Sector size for | |||||
| .Nm ggate | |||||
| provider. | |||||
| If not specified, it is taken from the device, or set to 512 bytes for files. | |||||
| .It Fl t Ar timeout | |||||
| Number of seconds to wait before an I/O request will be canceled. | |||||
| 0 means no timeout. | |||||
| Default is 30. | |||||
| .It Fl u Ar unit | |||||
| Unit number to use. | |||||
| .It Fl v | |||||
| Do not fork, run in foreground and print debug information on standard | |||||
| output. | |||||
| .It Ar path | |||||
| Path to a regular file or device. | |||||
| .El | |||||
| .Sh EXIT STATUS | |||||
| Exit status is 0 on success, or 1 if the command fails. | |||||
| To get details about the failure, | |||||
| .Nm | |||||
| should be called with the | |||||
| .Fl v | |||||
| option. | |||||
| .Sh EXAMPLES | |||||
| .Dq GEOMify | |||||
| the | |||||
| .Dq Li fd0 | |||||
| device and use | |||||
| .Xr gbde 8 | |||||
| to encrypt data on a floppy disk. | |||||
| .Bd -literal -offset indent | |||||
| ggatel create -u 5 /dev/fd0 | |||||
| gbde init /dev/ggate5 | |||||
| gbde attach ggate5 | |||||
| newfs /dev/ggate5.bde | |||||
| mount /dev/ggate5.bde /secret | |||||
| cp /private/foo /secret/ | |||||
| umount /secret | |||||
| gbde detach ggate5 | |||||
| ggatel destroy -u 5 | |||||
| .Ed | |||||
| .Sh SEE ALSO | |||||
| .Xr geom 4 , | |||||
| .Xr gbde 8 , | |||||
| .Xr ggatec 8 , | |||||
| .Xr ggated 8 , | |||||
| .Xr mount 8 , | |||||
| .Xr newfs 8 | |||||
| .Sh HISTORY | |||||
| The | |||||
| .Nm | |||||
| utility appeared in | |||||
| .Fx 5.3 . | |||||
| .Sh AUTHORS | |||||
| The | |||||
| .Nm | |||||
| utility as well as this manual page was written by | |||||
| .An Pawel Jakub Dawidek Aq Mt pjd@FreeBSD.org . | |||||
| @@ -1,330 +0,0 @@ | |||||
| /*- | |||||
| * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
| * | |||||
| * 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 <stdint.h> | |||||
| #include <fcntl.h> | |||||
| #include <unistd.h> | |||||
| #include <string.h> | |||||
| #include <err.h> | |||||
| #include <errno.h> | |||||
| #include <assert.h> | |||||
| #include <sys/param.h> | |||||
| #include <sys/time.h> | |||||
| #include <sys/bio.h> | |||||
| #include <sys/disk.h> | |||||
| #include <sys/ioctl.h> | |||||
| #include <sys/stat.h> | |||||
| #include <sys/syslog.h> | |||||
| #include <geom/gate/g_gate.h> | |||||
| #include "ggate.h" | |||||
| static enum { UNSET, CREATE, DESTROY, LIST, RESCUE } action = UNSET; | |||||
| static const char *path = NULL; | |||||
| static int unit = G_GATE_UNIT_AUTO; | |||||
| static unsigned flags = 0; | |||||
| static int force = 0; | |||||
| static unsigned sectorsize = 0; | |||||
| static unsigned timeout = G_GATE_TIMEOUT; | |||||
| static void | |||||
| usage(void) | |||||
| { | |||||
| fprintf(stderr, "usage: %s create [-v] [-o <ro|wo|rw>] " | |||||
| "[-s sectorsize] [-t timeout] [-u unit] <path>\n", getprogname()); | |||||
| fprintf(stderr, " %s rescue [-v] [-o <ro|wo|rw>] <-u unit> " | |||||
| "<path>\n", getprogname()); | |||||
| fprintf(stderr, " %s destroy [-f] <-u unit>\n", getprogname()); | |||||
| fprintf(stderr, " %s list [-v] [-u unit]\n", getprogname()); | |||||
| exit(EXIT_FAILURE); | |||||
| } | |||||
| static 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); | |||||
| } | |||||
| static void | |||||
| g_gatel_serve(int fd) | |||||
| { | |||||
| struct g_gate_ctl_io ggio; | |||||
| size_t bsize; | |||||
| if (g_gate_verbose == 0) { | |||||
| if (daemon(0, 0) == -1) { | |||||
| g_gate_destroy(unit, 1); | |||||
| err(EXIT_FAILURE, "Cannot daemonize"); | |||||
| } | |||||
| } | |||||
| g_gate_log(LOG_DEBUG, "Worker created: %u.", getpid()); | |||||
| ggio.gctl_version = G_GATE_VERSION; | |||||
| ggio.gctl_unit = unit; | |||||
| bsize = sectorsize; | |||||
| ggio.gctl_data = malloc(bsize); | |||||
| for (;;) { | |||||
| int error; | |||||
| once_again: | |||||
| ggio.gctl_length = bsize; | |||||
| ggio.gctl_error = 0; | |||||
| g_gate_ioctl(G_GATE_CMD_START, &ggio); | |||||
| error = ggio.gctl_error; | |||||
| switch (error) { | |||||
| case 0: | |||||
| break; | |||||
| case ECANCELED: | |||||
| /* Exit gracefully. */ | |||||
| free(ggio.gctl_data); | |||||
| g_gate_close_device(); | |||||
| close(fd); | |||||
| exit(EXIT_SUCCESS); | |||||
| case ENOMEM: | |||||
| /* Buffer too small. */ | |||||
| assert(ggio.gctl_cmd == BIO_DELETE || | |||||
| ggio.gctl_cmd == BIO_WRITE); | |||||
| ggio.gctl_data = realloc(ggio.gctl_data, | |||||
| ggio.gctl_length); | |||||
| if (ggio.gctl_data != NULL) { | |||||
| bsize = ggio.gctl_length; | |||||
| goto once_again; | |||||
| } | |||||
| /* FALLTHROUGH */ | |||||
| case ENXIO: | |||||
| default: | |||||
| g_gate_xlog("ioctl(/dev/%s): %s.", G_GATE_CTL_NAME, | |||||
| strerror(error)); | |||||
| } | |||||
| error = 0; | |||||
| switch (ggio.gctl_cmd) { | |||||
| case BIO_READ: | |||||
| if ((size_t)ggio.gctl_length > bsize) { | |||||
| ggio.gctl_data = realloc(ggio.gctl_data, | |||||
| ggio.gctl_length); | |||||
| if (ggio.gctl_data != NULL) | |||||
| bsize = ggio.gctl_length; | |||||
| else | |||||
| error = ENOMEM; | |||||
| } | |||||
| if (error == 0) { | |||||
| if (pread(fd, ggio.gctl_data, ggio.gctl_length, | |||||
| ggio.gctl_offset) == -1) { | |||||
| error = errno; | |||||
| } | |||||
| } | |||||
| break; | |||||
| case BIO_DELETE: | |||||
| case BIO_WRITE: | |||||
| if (pwrite(fd, ggio.gctl_data, ggio.gctl_length, | |||||
| ggio.gctl_offset) == -1) { | |||||
| error = errno; | |||||
| } | |||||
| break; | |||||
| default: | |||||
| error = EOPNOTSUPP; | |||||
| } | |||||
| ggio.gctl_error = error; | |||||
| g_gate_ioctl(G_GATE_CMD_DONE, &ggio); | |||||
| } | |||||
| } | |||||
| static void | |||||
| g_gatel_create(void) | |||||
| { | |||||
| struct g_gate_ctl_create ggioc; | |||||
| int fd; | |||||
| fd = open(path, g_gate_openflags(flags) | O_DIRECT | O_FSYNC); | |||||
| if (fd == -1) | |||||
| err(EXIT_FAILURE, "Cannot open %s", path); | |||||
| memset(&ggioc, 0, sizeof(ggioc)); | |||||
| ggioc.gctl_version = G_GATE_VERSION; | |||||
| ggioc.gctl_unit = unit; | |||||
| ggioc.gctl_mediasize = g_gate_mediasize(fd); | |||||
| if (sectorsize == 0) | |||||
| sectorsize = g_gate_sectorsize(fd); | |||||
| ggioc.gctl_sectorsize = sectorsize; | |||||
| ggioc.gctl_timeout = timeout; | |||||
| ggioc.gctl_flags = flags; | |||||
| ggioc.gctl_maxcount = 0; | |||||
| strlcpy(ggioc.gctl_info, path, sizeof(ggioc.gctl_info)); | |||||
| g_gate_ioctl(G_GATE_CMD_CREATE, &ggioc); | |||||
| if (unit == -1) | |||||
| printf("%s%u\n", G_GATE_PROVIDER_NAME, ggioc.gctl_unit); | |||||
| unit = ggioc.gctl_unit; | |||||
| g_gatel_serve(fd); | |||||
| } | |||||
| static void | |||||
| g_gatel_rescue(void) | |||||
| { | |||||
| struct g_gate_ctl_cancel ggioc; | |||||
| int fd; | |||||
| fd = open(path, g_gate_openflags(flags)); | |||||
| if (fd == -1) | |||||
| err(EXIT_FAILURE, "Cannot open %s", path); | |||||
| ggioc.gctl_version = G_GATE_VERSION; | |||||
| ggioc.gctl_unit = unit; | |||||
| ggioc.gctl_seq = 0; | |||||
| g_gate_ioctl(G_GATE_CMD_CANCEL, &ggioc); | |||||
| g_gatel_serve(fd); | |||||
| } | |||||
| int | |||||
| main(int argc, char *argv[]) | |||||
| { | |||||
| if (argc < 2) | |||||
| usage(); | |||||
| if (strcasecmp(argv[1], "create") == 0) | |||||
| action = CREATE; | |||||
| else if (strcasecmp(argv[1], "rescue") == 0) | |||||
| action = RESCUE; | |||||
| else if (strcasecmp(argv[1], "destroy") == 0) | |||||
| action = DESTROY; | |||||
| else if (strcasecmp(argv[1], "list") == 0) | |||||
| action = LIST; | |||||
| else | |||||
| usage(); | |||||
| argc -= 1; | |||||
| argv += 1; | |||||
| for (;;) { | |||||
| int ch; | |||||
| ch = getopt(argc, argv, "fo:s:t:u:v"); | |||||
| if (ch == -1) | |||||
| break; | |||||
| switch (ch) { | |||||
| case 'f': | |||||
| if (action != DESTROY) | |||||
| usage(); | |||||
| force = 1; | |||||
| break; | |||||
| case 'o': | |||||
| if (action != CREATE && action != RESCUE) | |||||
| usage(); | |||||
| if (strcasecmp("ro", optarg) == 0) | |||||
| flags = G_GATE_FLAG_READONLY; | |||||
| else if (strcasecmp("wo", optarg) == 0) | |||||
| flags = G_GATE_FLAG_WRITEONLY; | |||||
| else if (strcasecmp("rw", optarg) == 0) | |||||
| flags = 0; | |||||
| else { | |||||
| errx(EXIT_FAILURE, | |||||
| "Invalid argument for '-o' option."); | |||||
| } | |||||
| break; | |||||
| case 's': | |||||
| if (action != CREATE) | |||||
| usage(); | |||||
| errno = 0; | |||||
| sectorsize = strtoul(optarg, NULL, 10); | |||||
| if (sectorsize == 0 && errno != 0) | |||||
| errx(EXIT_FAILURE, "Invalid sectorsize."); | |||||
| break; | |||||
| case 't': | |||||
| if (action != CREATE) | |||||
| usage(); | |||||
| errno = 0; | |||||
| timeout = strtoul(optarg, NULL, 10); | |||||
| if (timeout == 0 && errno != 0) | |||||
| errx(EXIT_FAILURE, "Invalid timeout."); | |||||
| break; | |||||
| case 'u': | |||||
| errno = 0; | |||||
| unit = strtol(optarg, NULL, 10); | |||||
| if (unit == 0 && errno != 0) | |||||
| errx(EXIT_FAILURE, "Invalid unit number."); | |||||
| break; | |||||
| case 'v': | |||||
| if (action == DESTROY) | |||||
| usage(); | |||||
| g_gate_verbose++; | |||||
| break; | |||||
| default: | |||||
| usage(); | |||||
| } | |||||
| } | |||||
| argc -= optind; | |||||
| argv += optind; | |||||
| switch (action) { | |||||
| case CREATE: | |||||
| if (argc != 1) | |||||
| usage(); | |||||
| g_gate_load_module(); | |||||
| g_gate_open_device(); | |||||
| path = argv[0]; | |||||
| g_gatel_create(); | |||||
| break; | |||||
| case RESCUE: | |||||
| if (argc != 1) | |||||
| usage(); | |||||
| if (unit == -1) { | |||||
| fprintf(stderr, "Required unit number.\n"); | |||||
| usage(); | |||||
| } | |||||
| g_gate_open_device(); | |||||
| path = argv[0]; | |||||
| g_gatel_rescue(); | |||||
| break; | |||||
| case DESTROY: | |||||
| if (unit == -1) { | |||||
| fprintf(stderr, "Required unit number.\n"); | |||||
| usage(); | |||||
| } | |||||
| g_gate_verbose = 1; | |||||
| g_gate_open_device(); | |||||
| g_gate_destroy(unit, force); | |||||
| break; | |||||
| case LIST: | |||||
| g_gate_list(unit, g_gate_verbose); | |||||
| break; | |||||
| case UNSET: | |||||
| default: | |||||
| usage(); | |||||
| } | |||||
| g_gate_close_device(); | |||||
| exit(EXIT_SUCCESS); | |||||
| } | |||||