Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149781551
D26542.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D26542.id.diff
View Options
Index: sbin/ggate/ggatec/ggatec.8
===================================================================
--- sbin/ggate/ggatec/ggatec.8
+++ sbin/ggate/ggatec/ggatec.8
@@ -33,6 +33,7 @@
.Sh SYNOPSIS
.Nm
.Cm create
+.Op Fl 0 | Fl 1
.Op Fl n
.Op Fl v
.Op Fl o Cm ro | wo | rw
@@ -47,6 +48,7 @@
.Ar path
.Nm
.Cm rescue
+.Op Fl 0 | Fl 1
.Op Fl n
.Op Fl v
.Op Fl o Cm ro | wo | rw
@@ -102,6 +104,19 @@
.Pp
Available options:
.Bl -tag -width ".Fl s Cm ro | wo | rw"
+.It Fl 0
+Use
+.Nm ggate
+protocol version 0 only.
+Protocol version 0 appeared in FreeBSD 5.3-RELEASE.
+.It Fl 1
+Use
+.Nm ggate
+protocol version 1 only.
+Protocol version 1 appeared in FreeBSD 13.0-RELEASE to simplify
+.Nm ggate
+connection negotiation.
+The default is to try version 1 and then to retry with version 0.
.It Fl f
Forcibly destroy
.Nm ggate
Index: sbin/ggate/ggatec/ggatec.c
===================================================================
--- sbin/ggate/ggatec/ggatec.c
+++ sbin/ggate/ggatec/ggatec.c
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
@@ -75,14 +76,20 @@
static pthread_t sendtd, recvtd;
static int reconnect;
+/* bitmask of protocol versions to attempt connecting. */
+static int try_version = (1 << GGATE_VERSION_1) | (1 << GGATE_VERSION_0);
+
+static bool g_gatec_connect_v0(void);
+static bool g_gatec_connect_v1(void);
+
static void
usage(void)
{
-
- fprintf(stderr, "usage: %s create [-nv] [-o <ro|wo|rw>] [-p port] "
+ fprintf(stderr, "geom gate protocol version %d\n", G_GATE_VERSION);
+ fprintf(stderr, "usage: %s create [-0|-1] [-nv] [-o <ro|wo|rw>] [-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 [-0|-1] [-nv] [-o <ro|wo|rw>] [-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());
@@ -283,10 +290,11 @@
/*
* Create and send version packet.
*/
- g_gate_log(LOG_DEBUG, "Sending version packet.");
assert(strlen(GGATE_MAGIC) == sizeof(ver.gv_magic));
bcopy(GGATE_MAGIC, ver.gv_magic, sizeof(ver.gv_magic));
- ver.gv_version = GGATE_VERSION;
+ ver.gv_version = dir ? GGATE_VERSION_0 : GGATE_VERSION_1;
+ g_gate_log(LOG_DEBUG, "Sending version %u packet.",
+ ver.gv_version);
ver.gv_error = 0;
g_gate_swap2n_version(&ver);
if (g_gate_send(sfd, &ver, sizeof(ver), MSG_NOSIGNAL) == -1) {
@@ -370,8 +378,8 @@
err(EXIT_FAILURE, "Cannot daemonize");
}
-static int
-g_gatec_connect(void)
+static bool
+g_gatec_connect_v0(void)
{
token = arc4random();
@@ -381,17 +389,48 @@
*/
recvfd = handshake(GGATE_FLAG_SEND);
if (recvfd == -1)
- return (0);
+ return (false);
/*
* Our send descriptor is connected to the receive descriptor on the
* server side.
*/
sendfd = handshake(GGATE_FLAG_RECV);
if (sendfd == -1)
- return (0);
- return (1);
+ return (false);
+ return (true);
}
+static bool
+g_gatec_connect_v1(void)
+{
+
+ token = arc4random();
+ recvfd = sendfd = handshake(0);
+ if (sendfd == -1)
+ return (false);
+ return (true);
+}
+
+static bool
+g_gatec_connect(void)
+{
+
+ if (try_version & (1 << GGATE_VERSION_1)) {
+ if (g_gatec_connect_v1()) {
+ try_version = 1 << GGATE_VERSION_1;
+ return (true);
+ }
+ }
+ if (try_version & (1 << GGATE_VERSION_0)) {
+ if (g_gatec_connect_v0()) {
+ try_version = 1 << GGATE_VERSION_0;
+ return (true);
+ }
+ }
+ try_version = 0;
+ return (false);
+}
+
static void
g_gatec_start(void)
{
@@ -408,7 +447,8 @@
send_thread(NULL);
/* Disconnected. */
close(sendfd);
- close(recvfd);
+ if (sendfd != recvfd)
+ close(recvfd);
}
static void
@@ -510,10 +550,14 @@
for (;;) {
int ch;
- ch = getopt(argc, argv, "fno:p:q:R:S:s:t:u:v");
+ ch = getopt(argc, argv, "01fno:p:q:R:S:s:t:u:v");
if (ch == -1)
break;
switch (ch) {
+ case '0':
+ case '1':
+ try_version = (1 << (ch - '0'));
+ break;
case 'f':
if (action != DESTROY)
usage();
Index: sbin/ggate/ggated/ggated.c
===================================================================
--- sbin/ggate/ggated/ggated.c
+++ sbin/ggate/ggated/ggated.c
@@ -51,6 +51,7 @@
#include <pthread.h>
#include <signal.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -64,6 +65,7 @@
#define GGATED_EXPORT_FILE "/etc/gg.exports"
struct ggd_connection {
+ int c_version;
off_t c_mediasize;
unsigned c_sectorsize;
unsigned c_flags; /* flags (RO/RW) */
@@ -111,6 +113,8 @@
static void *disk_thread(void *arg);
static void *send_thread(void *arg);
+static void connection_remove(struct ggd_connection *conn);
+
static void
usage(void)
{
@@ -415,17 +419,8 @@
time(&now);
LIST_FOREACH_SAFE(conn, &connections, c_next, tconn) {
- if (now - conn->c_birthtime > 10) {
- LIST_REMOVE(conn, c_next);
- g_gate_log(LOG_NOTICE,
- "Connection from %s [%s] removed.",
- ip2str(conn->c_srcip), conn->c_path);
- close(conn->c_diskfd);
- close(conn->c_sendfd);
- close(conn->c_recvfd);
- free(conn->c_path);
- free(conn);
- }
+ if (now - conn->c_birthtime > 10)
+ connection_remove(conn);
}
}
@@ -442,7 +437,7 @@
}
static struct ggd_connection *
-connection_new(struct g_gate_cinit *cinit, struct sockaddr *s, int sfd)
+connection_new(int ver, struct g_gate_cinit *cinit, struct sockaddr *s, int sfd)
{
struct ggd_connection *conn;
in_addr_t ip;
@@ -458,6 +453,7 @@
conn = malloc(sizeof(*conn));
if (conn == NULL)
return (NULL);
+ conn->c_version = ver;
conn->c_path = strdup(cinit->gc_path);
if (conn->c_path == NULL) {
free(conn);
@@ -467,15 +463,20 @@
ip = htonl(((struct sockaddr_in *)(void *)s)->sin_addr.s_addr);
conn->c_srcip = ip;
conn->c_diskfd = conn->c_sendfd = conn->c_recvfd = -1;
- if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0)
- conn->c_sendfd = sfd;
- else
- conn->c_recvfd = sfd;
conn->c_mediasize = 0;
conn->c_sectorsize = 0;
time(&conn->c_birthtime);
conn->c_flags = cinit->gc_flags;
- LIST_INSERT_HEAD(&connections, conn, c_next);
+ if (conn->c_version == GGATE_VERSION_1) {
+ conn->c_sendfd = sfd;
+ conn->c_recvfd = sfd;
+ } else if (conn->c_version == GGATE_VERSION_0) {
+ if ((cinit->gc_flags & GGATE_FLAG_SEND) != 0)
+ conn->c_sendfd = sfd;
+ else
+ conn->c_recvfd = sfd;
+ LIST_INSERT_HEAD(&connections, conn, c_next);
+ }
g_gate_log(LOG_DEBUG, "Connection created [%s, %s].", ip2str(ip),
conn->c_path);
return (conn);
@@ -518,14 +519,15 @@
connection_remove(struct ggd_connection *conn)
{
- LIST_REMOVE(conn, c_next);
+ if (conn->c_version == GGATE_VERSION_0)
+ LIST_REMOVE(conn, c_next);
g_gate_log(LOG_DEBUG, "Connection removed [%s %s].",
ip2str(conn->c_srcip), conn->c_path);
if (conn->c_diskfd != -1)
close(conn->c_diskfd);
if (conn->c_sendfd != -1)
close(conn->c_sendfd);
- if (conn->c_recvfd != -1)
+ if (conn->c_recvfd != -1 && conn->c_sendfd != conn->c_recvfd)
close(conn->c_recvfd);
free(conn->c_path);
free(conn);
@@ -845,7 +847,11 @@
g_gate_log(LOG_INFO, "Connection from: %s.", ip2str(ip));
}
-static int
+/*
+ * handshake() returns true if sfd is closed; otherwise false so that caller
+ * has to close the sfd.
+ */
+static bool
handshake(struct sockaddr *from, int sfd)
{
struct g_gate_version ver;
@@ -864,17 +870,23 @@
g_gate_swap2h_version(&ver);
if (data != sizeof(ver)) {
g_gate_log(LOG_WARNING, "Malformed version packet.");
- return (0);
+ return (false);
}
g_gate_log(LOG_DEBUG, "Version packet received.");
if (memcmp(ver.gv_magic, GGATE_MAGIC, strlen(GGATE_MAGIC)) != 0) {
g_gate_log(LOG_WARNING, "Invalid magic field.");
- return (0);
+ return (false);
}
- if (ver.gv_version != GGATE_VERSION) {
- g_gate_log(LOG_WARNING, "Version %u is not supported.",
+ switch (ver.gv_version) {
+ case GGATE_VERSION_0:
+ case GGATE_VERSION_1:
+ g_gate_log(LOG_DEBUG, "Received version %" PRIu16,
ver.gv_version);
- return (0);
+ break;
+ default:
+ g_gate_log(LOG_WARNING, "Version %u protocol is not supported.",
+ ver.gv_version);
+ return (false);
}
ver.gv_error = 0;
g_gate_swap2n_version(&ver);
@@ -883,7 +895,7 @@
if (data == -1) {
sendfail(sfd, errno, "Error while sending version packet: %s.",
strerror(errno));
- return (0);
+ return (false);
}
/*
@@ -897,7 +909,18 @@
return (0);
}
g_gate_log(LOG_DEBUG, "Initial packet received.");
- conn = connection_find(&cinit);
+ switch (ver.gv_version) {
+ case GGATE_VERSION_0:
+ conn = connection_find(&cinit);
+ break;
+ case GGATE_VERSION_1:
+ conn = NULL;
+ break;
+ default:
+ g_gate_log(LOG_WARNING, "Version %u is not supported.",
+ ver.gv_version);
+ return (false);
+ }
if (conn != NULL) {
/*
* Connection should already exists.
@@ -906,17 +929,17 @@
(unsigned long)conn->c_token);
if (connection_add(conn, &cinit, from, sfd) == -1) {
connection_remove(conn);
- return (0);
+ return (false);
}
} else {
/*
* New connection, allocate space.
*/
- conn = connection_new(&cinit, from, sfd);
+ conn = connection_new(ver.gv_version, &cinit, from, sfd);
if (conn == NULL) {
sendfail(sfd, ENOMEM,
"Cannot allocate new connection.");
- return (0);
+ return (false);
}
g_gate_log(LOG_DEBUG, "New connection created (token=%lu).",
(unsigned long)conn->c_token);
@@ -926,7 +949,7 @@
if (ex == NULL) {
sendfail(sfd, errno, NULL);
connection_remove(conn);
- return (0);
+ return (false);
}
if (conn->c_mediasize == 0) {
conn->c_mediasize = g_gate_mediasize(conn->c_diskfd);
@@ -944,14 +967,23 @@
if (data == -1) {
sendfail(sfd, errno, "Error while sending initial packet: %s.",
strerror(errno));
- return (0);
+ return (false);
}
- if (connection_ready(conn)) {
+ switch (conn->c_version) {
+ case GGATE_VERSION_0:
+ if (connection_ready(conn)) {
+ connection_launch(conn);
+ connection_remove(conn);
+ }
+ return (true);
+ case GGATE_VERSION_1:
connection_launch(conn);
connection_remove(conn);
+ return (true);
+ default:
+ return (false);
}
- return (1);
}
static void
Index: sbin/ggate/shared/ggate.h
===================================================================
--- sbin/ggate/shared/ggate.h
+++ sbin/ggate/shared/ggate.h
@@ -42,11 +42,25 @@
#define G_GATE_TIMEOUT 0
#define GGATE_MAGIC "GEOM_GATE "
-#define GGATE_VERSION 0
+#define GGATE_VERSION_0 0
+#define GGATE_VERSION_1 1
+#define GGATE_VERSION GGATE_VERSION_1
+/*
+ * Protocol version 0 uses 2 TCP connections.
+ * ggatec initiates 2 handshakes for a single session and establishes
+ * 2 TCP connections. ggated waits for the 2nd handshake to complete before
+ * forking.
+ *
+ * Protocol version 1 uses 1 TCP connection.
+ * ggatec only initiates 1 handshake and ggated immediately forks. A parent
+ * ggated process does not cache connections for connection negotiations.
+ */
#define GGATE_FLAG_RDONLY 0x0001
#define GGATE_FLAG_WRONLY 0x0002
/*
+ * Protocol version 0 only.
+ *
* If neither the GGATE_FLAG_SEND nor the GGATE_FLAG_RECV flag is
* set - this is initial connection.
* If GGATE_FLAG_SEND flag is set - this is socket to send data.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 28, 1:21 AM (5 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30451784
Default Alt Text
D26542.id.diff (11 KB)
Attached To
Mode
D26542: [ggated/ggatec] Simplify Gate Handshake.
Attached
Detach File
Event Timeline
Log In to Comment