Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143602720
D45056.id138030.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D45056.id138030.diff
View Options
diff --git a/sbin/ggate/ggatec/ggatec.8 b/sbin/ggate/ggatec/ggatec.8
--- a/sbin/ggate/ggatec/ggatec.8
+++ b/sbin/ggate/ggatec/ggatec.8
@@ -33,7 +33,7 @@
.Cm create
.Op Fl n
.Op Fl v
-.Op Fl o Cm ro | wo | rw
+.Oo Fl o option Oc ...
.Op Fl p Ar port
.Op Fl q Ar queue_size
.Op Fl R Ar rcvbuf
@@ -47,7 +47,7 @@
.Cm rescue
.Op Fl n
.Op Fl v
-.Op Fl o Cm ro | wo | rw
+.Oo Fl o option Oc ...
.Op Fl p Ar port
.Op Fl R Ar rcvbuf
.Op Fl S Ar sndbuf
@@ -108,13 +108,21 @@
Do not use
.Dv TCP_NODELAY
option on TCP sockets.
-.It Fl o Cm ro | wo | rw
-Specify permissions to use when opening the file or device: read-only
-.Pq Cm ro ,
+.It Fl o Ar option
+Specify permissions and options to use when opening the file or device.
+.Bl -tag -width indent
+.It Cm ro
+read-only
+.It Cm wo
write-only
-.Pq Cm wo ,
-or read-write
-.Pq Cm rw .
+.It Cm rw
+read-write
+.It Cm direct
+open with
+.Dv O_DIRECT
+option on the file
+.El
+.Pp
Default is
.Cm rw .
.It Fl p Ar port
@@ -160,11 +168,14 @@
.Bd -literal -offset indent
server# cat /etc/gg.exports
client RO /dev/cd0
+client RW /tmp/image
server# ggated
client# ggatec create -o ro server /dev/cd0
ggate0
client# mount_cd9660 /dev/ggate0 /cdrom
+client# ggatec create -o rw -o direct server /tmp/image
+ggate1
.Ed
.Sh SEE ALSO
.Xr geom 4 ,
diff --git a/sbin/ggate/ggatec/ggatec.c b/sbin/ggate/ggatec/ggatec.c
--- a/sbin/ggate/ggatec/ggatec.c
+++ b/sbin/ggate/ggatec/ggatec.c
@@ -52,7 +52,6 @@
#include <netinet/tcp.h>
#include <arpa/inet.h>
-#include <geom/gate/g_gate.h>
#include "ggate.h"
@@ -62,6 +61,7 @@
static const char *host = NULL;
static int unit = G_GATE_UNIT_AUTO;
static unsigned flags = 0;
+static int direct_flag = 0;
static int force = 0;
static unsigned queue_size = G_GATE_QUEUE_SIZE;
static unsigned port = G_GATE_PORT;
@@ -78,13 +78,14 @@
usage(void)
{
- fprintf(stderr, "usage: %s create [-nv] [-o <ro|wo|rw>] [-p port] "
+ fprintf(stderr, "usage: %s create [-nv] [-o option] ... [-p port] "
"[-q queue_size] [-R rcvbuf] [-S sndbuf] [-s sectorsize] "
"[-t timeout] [-u unit] <host> <path>\n", getprogname());
- fprintf(stderr, " %s rescue [-nv] [-o <ro|wo|rw>] [-p port] "
+ fprintf(stderr, " %s rescue [-nv] [-o option] ... [-p port] "
"[-R rcvbuf] [-S sndbuf] <-u unit> <host> <path>\n", getprogname());
fprintf(stderr, " %s destroy [-f] <-u unit>\n", getprogname());
fprintf(stderr, " %s list [-v] [-u unit]\n", getprogname());
+ fprintf(stderr, " option = {ro, wo, rw, direct}\n");
exit(EXIT_FAILURE);
}
@@ -361,7 +362,7 @@
close(sfd);
return (-1);
}
- cinit.gc_flags = flags | dir;
+ cinit.gc_flags = flags | direct_flag | dir;
cinit.gc_token = token;
cinit.gc_nconn = 2;
g_gate_swap2n_cinit(&cinit);
@@ -544,7 +545,6 @@
int
main(int argc, char *argv[])
{
-
if (argc < 2)
usage();
if (strcasecmp(argv[1], "create") == 0)
@@ -585,6 +585,8 @@
flags = G_GATE_FLAG_WRITEONLY;
else if (strcasecmp("rw", optarg) == 0)
flags = 0;
+ else if (strcasecmp("direct", optarg) == 0)
+ direct_flag = GGATE_FLAG_DIRECT;
else {
errx(EXIT_FAILURE,
"Invalid argument for '-o' option.");
diff --git a/sbin/ggate/ggated/ggated.8 b/sbin/ggate/ggated/ggated.8
--- a/sbin/ggate/ggated/ggated.8
+++ b/sbin/ggate/ggated/ggated.8
@@ -85,9 +85,11 @@
.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
+1.2.3.4 RO /dev/cd0
+1.2.3.0/24 RW /tmp/test.img
+hostname WO /tmp/image
+hostname RW,DIRECT /tmp/direct-image
+hostname RW,NODIRECT /tmp/nodirect-image
.Ed
.Sh FILES
.Bl -tag -width ".Pa /var/run/ggated.pid" -compact
@@ -104,10 +106,14 @@
.Fl v
option.
.Sh EXAMPLES
-Export CD-ROM device and a file:
+Export CD-ROM device, a file, and a file with
+.Dv O_DIRECT
+option:
.Bd -literal -offset indent
# echo "1.2.3.0/24 RO /dev/cd0" > /etc/gg.exports
# echo "client RW /image" >> /etc/gg.exports
+# echo "client RW,DIRECT /image2" >> /etc/gg.exports
+# echo "client RW,NODIRECT /image3" >> /etc/gg.exports
# ggated
.Ed
.Sh SEE ALSO
diff --git a/sbin/ggate/ggated/ggated.c b/sbin/ggate/ggated/ggated.c
--- a/sbin/ggate/ggated/ggated.c
+++ b/sbin/ggate/ggated/ggated.c
@@ -64,7 +64,7 @@
struct ggd_connection {
off_t c_mediasize;
unsigned c_sectorsize;
- unsigned c_flags; /* flags (RO/RW) */
+ int c_flags; /* flags (RO/RW) */
int c_diskfd;
int c_sendfd;
int c_recvfd;
@@ -85,11 +85,18 @@
#define r_length r_hdr.gh_length
#define r_error r_hdr.gh_error
+#define EFLAGS_RDONLY 0x0000
+#define EFLAGS_WRONLY 0x0001
+#define EFLAGS_RDWR 0x0002
+#define EFLAGS_ACCMODE 0x0003
+#define EFLAGS_DIRECT 0x0004
+#define EFLAGS_NODIRECT 0x0008
+
struct ggd_export {
char *e_path; /* path to device/file */
in_addr_t e_ip; /* remote IP address */
in_addr_t e_mask; /* IP mask */
- unsigned e_flags; /* flags (RO/RW) */
+ int e_flags; /* flags (WO/RO/RW/DIRECT/NODIRECT) */
SLIST_ENTRY(ggd_export) e_next;
};
@@ -146,20 +153,61 @@
return (mask);
}
+static int
+parse_flags(char *flagsstr, int lineno)
+{
+ char *flagscpy;
+ char *word,*brkf;
+ int access_flags = -1;
+ int direct_flags = 0;
+ flagscpy = strdup(flagsstr);
+ if (flagscpy == NULL) {
+ g_gate_xlog("Not enough memory.");
+ }
+
+ for (word = strtok_r(flagscpy, ",", &brkf);
+ word;
+ word = strtok_r(NULL, ",", &brkf))
+ {
+ if (strcasecmp("ro", word) == 0 ||
+ strcasecmp("rd", word) == 0) {
+ access_flags = EFLAGS_RDONLY;
+ } else if (strcasecmp("wo", word) == 0) {
+ access_flags = EFLAGS_WRONLY;
+ } else if (strcasecmp("rw", word) == 0) {
+ access_flags = EFLAGS_RDWR;
+ } else if (strcasecmp("direct", word) == 0) {
+ direct_flags = EFLAGS_DIRECT;
+ } else if (strcasecmp("nodirect", word) == 0) {
+ direct_flags = EFLAGS_NODIRECT;
+ } else {
+ g_gate_xlog("Invalid value (%s) in flags field at "
+ "line %u.", word, lineno);
+ }
+ }
+ free(flagscpy);
+ if (access_flags == -1) {
+ g_gate_xlog("Invalid value (%s) in flags field at "
+ "line %u.", flagsstr, lineno);
+ }
+ return direct_flags | access_flags;
+}
+
static void
line_parse(char *line, unsigned lineno)
{
struct ggd_export *ex;
- char *word, *path, *sflags;
- unsigned flags, i, vmask;
+ char *word, *path, *sflags, *brkl;
+ unsigned i, vmask;
+ int flags;
in_addr_t ip, mask;
ip = mask = flags = vmask = 0;
path = NULL;
sflags = NULL;
- for (i = 0, word = strtok(line, " \t"); word != NULL;
- i++, word = strtok(NULL, " \t")) {
+ for (i = 0, word = strtok_r(line, " \t", &brkl); word != NULL;
+ i++, word = strtok_r(NULL, " \t", &brkl)) {
switch (i) {
case 0: /* IP address or host name */
ip = g_gate_str2ip(strsep(&word, "/"));
@@ -185,17 +233,7 @@
mask = countmask(vmask);
break;
case 1: /* flags */
- if (strcasecmp("rd", word) == 0 ||
- strcasecmp("ro", word) == 0) {
- flags = O_RDONLY;
- } else if (strcasecmp("wo", word) == 0) {
- flags = O_WRONLY;
- } else if (strcasecmp("rw", word) == 0) {
- flags = O_RDWR;
- } else {
- g_gate_xlog("Invalid value in flags field at "
- "line %u.", lineno);
- }
+ flags = parse_flags(word, lineno);
sflags = word;
break;
case 2: /* path */
@@ -306,13 +344,16 @@
struct ggd_connection *conn)
{
char ipmask[32]; /* 32 == strlen("xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx")+1 */
- int error = 0, flags;
+ int error = 0, flags, access_flags, direct_flags = 0;
strlcpy(ipmask, ip2str(ex->e_ip), sizeof(ipmask));
strlcat(ipmask, "/", sizeof(ipmask));
strlcat(ipmask, ip2str(ex->e_mask), sizeof(ipmask));
+
+ access_flags = ex->e_flags & EFLAGS_ACCMODE;
+
if ((cinit->gc_flags & GGATE_FLAG_RDONLY) != 0) {
- if (ex->e_flags == O_WRONLY) {
+ if (access_flags == EFLAGS_WRONLY) {
g_gate_log(LOG_WARNING, "Read-only access requested, "
"but %s (%s) is exported write-only.", ex->e_path,
ipmask);
@@ -321,7 +362,7 @@
conn->c_flags |= GGATE_FLAG_RDONLY;
}
} else if ((cinit->gc_flags & GGATE_FLAG_WRONLY) != 0) {
- if (ex->e_flags == O_RDONLY) {
+ if (access_flags == EFLAGS_RDONLY) {
g_gate_log(LOG_WARNING, "Write-only access requested, "
"but %s (%s) is exported read-only.", ex->e_path,
ipmask);
@@ -330,24 +371,41 @@
conn->c_flags |= GGATE_FLAG_WRONLY;
}
} else {
- if (ex->e_flags == O_RDONLY) {
+ if (access_flags == EFLAGS_RDONLY) {
g_gate_log(LOG_WARNING, "Read-write access requested, "
"but %s (%s) is exported read-only.", ex->e_path,
ipmask);
return (EPERM);
- } else if (ex->e_flags == O_WRONLY) {
+ } else if (access_flags == EFLAGS_WRONLY) {
g_gate_log(LOG_WARNING, "Read-write access requested, "
"but %s (%s) is exported write-only.", ex->e_path,
ipmask);
return (EPERM);
}
}
+
+ if ((cinit->gc_flags & GGATE_FLAG_DIRECT) != 0) {
+ if (ex->e_flags & EFLAGS_NODIRECT) {
+ g_gate_log(LOG_WARNING, "Direct IO requested, "
+ "but %s (%s) is exported NODIRECT.", ex->e_path,
+ ipmask);
+ } else {
+ conn->c_flags |= GGATE_FLAG_DIRECT;
+ direct_flags = O_DIRECT;
+ }
+ }
+
+ if (ex->e_flags & EFLAGS_DIRECT) {
+ direct_flags = O_DIRECT;
+ }
+
if ((conn->c_flags & GGATE_FLAG_RDONLY) != 0)
flags = O_RDONLY;
else if ((conn->c_flags & GGATE_FLAG_WRONLY) != 0)
flags = O_WRONLY;
else
flags = O_RDWR;
+ flags |= direct_flags;
if (conn->c_diskfd != -1) {
if (strcmp(conn->c_path, ex->e_path) != 0) {
g_gate_log(LOG_ERR, "old %s and new %s: "
diff --git a/sbin/ggate/ggatel/ggatel.8 b/sbin/ggate/ggatel/ggatel.8
--- a/sbin/ggate/ggatel/ggatel.8
+++ b/sbin/ggate/ggatel/ggatel.8
@@ -32,7 +32,7 @@
.Nm
.Cm create
.Op Fl v
-.Op Fl o Cm ro | wo | rw
+.Oo Fl o option Oc ...
.Op Fl s Ar sectorsize
.Op Fl t Ar timeout
.Op Fl u Ar unit
@@ -48,7 +48,7 @@
.Nm
.Cm rescue
.Op Fl v
-.Op Fl o Cm ro | wo | rw
+.Oo Fl o option Oc ...
.Fl u Ar unit
.Ar path
.Sh DESCRIPTION
@@ -92,13 +92,21 @@
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 ,
+.It Fl o Ar option
+Specify permissions and options to use when opening the file or device.
+.Bl -tag -width indent
+.It Cm ro
+read-only
+.It Cm wo
write-only
-.Pq Cm wo ,
-or read-write
-.Pq Cm rw .
+.It Cm rw
+read-write
+.It Cm direct
+open with
+.Dv O_DIRECT
+option on the file
+.El
+.Pp
Default is
.Cm rw .
.It Fl s Ar sectorsize
diff --git a/sbin/ggate/ggatel/ggatel.c b/sbin/ggate/ggatel/ggatel.c
--- a/sbin/ggate/ggatel/ggatel.c
+++ b/sbin/ggate/ggatel/ggatel.c
@@ -43,7 +43,6 @@
#include <sys/stat.h>
#include <sys/syslog.h>
-#include <geom/gate/g_gate.h>
#include "ggate.h"
@@ -52,6 +51,7 @@
static const char *path = NULL;
static int unit = G_GATE_UNIT_AUTO;
static unsigned flags = 0;
+static int direct_flag = 0;
static int force = 0;
static unsigned sectorsize = 0;
static unsigned timeout = G_GATE_TIMEOUT;
@@ -60,24 +60,30 @@
usage(void)
{
- fprintf(stderr, "usage: %s create [-v] [-o <ro|wo|rw>] "
+ fprintf(stderr, "usage: %s create [-v] [-o option] ... "
"[-s sectorsize] [-t timeout] [-u unit] <path>\n", getprogname());
- fprintf(stderr, " %s rescue [-v] [-o <ro|wo|rw>] <-u unit> "
+ fprintf(stderr, " %s rescue [-v] [-o option] ... <-u unit> "
"<path>\n", getprogname());
fprintf(stderr, " %s destroy [-f] <-u unit>\n", getprogname());
fprintf(stderr, " %s list [-v] [-u unit]\n", getprogname());
+ fprintf(stderr, " option = {ro, wo, rw, direct}\n");
exit(EXIT_FAILURE);
}
static int
g_gate_openflags(unsigned ggflags)
{
+ int openflags = O_RDWR;
if ((ggflags & G_GATE_FLAG_READONLY) != 0)
- return (O_RDONLY);
+ openflags = O_RDONLY;
else if ((ggflags & G_GATE_FLAG_WRITEONLY) != 0)
- return (O_WRONLY);
- return (O_RDWR);
+ openflags = O_WRONLY;
+
+ if (direct_flag)
+ openflags |= O_DIRECT;
+
+ return openflags
}
static void
@@ -248,6 +254,8 @@
flags = G_GATE_FLAG_WRITEONLY;
else if (strcasecmp("rw", optarg) == 0)
flags = 0;
+ else if (strcasecmp("direct", optarg) == 0)
+ direct_flag = 1;
else {
errx(EXIT_FAILURE,
"Invalid argument for '-o' option.");
diff --git a/sbin/ggate/shared/ggate.h b/sbin/ggate/shared/ggate.h
--- a/sbin/ggate/shared/ggate.h
+++ b/sbin/ggate/shared/ggate.h
@@ -29,6 +29,7 @@
#ifndef _GGATE_H_
#define _GGATE_H_
+#include <geom/gate/g_gate.h>
#include <sys/endian.h>
#include <stdarg.h>
@@ -42,8 +43,8 @@
#define GGATE_MAGIC "GEOM_GATE "
#define GGATE_VERSION 0
-#define GGATE_FLAG_RDONLY 0x0001
-#define GGATE_FLAG_WRONLY 0x0002
+#define GGATE_FLAG_RDONLY G_GATE_FLAG_READONLY
+#define GGATE_FLAG_WRONLY G_GATE_FLAG_WRITEONLY
/*
* If neither the GGATE_FLAG_SEND nor the GGATE_FLAG_RECV flag is
* set - this is initial connection.
@@ -53,6 +54,8 @@
#define GGATE_FLAG_SEND 0x0004
#define GGATE_FLAG_RECV 0x0008
+#define GGATE_FLAG_DIRECT 0x0010
+
#define GGATE_CMD_READ 0
#define GGATE_CMD_WRITE 1
#define GGATE_CMD_FLUSH 3
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 1, 1:10 AM (8 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28235645
Default Alt Text
D45056.id138030.diff (12 KB)
Attached To
Mode
D45056: support for DIRECT access via ggated and ggatec
Attached
Detach File
Event Timeline
Log In to Comment