Index: sbin/hastd/hast.conf.5 =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/hast.conf.5,v retrieving revision 1.1 diff -u -p -r1.1 hast.conf.5 --- sbin/hastd/hast.conf.5 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/hast.conf.5 28 Apr 2010 21:42:56 -0000 @@ -58,6 +58,7 @@ file is following: control listen replication +timeout on { # Node section @@ -76,6 +77,7 @@ resource { replication name local + timeout on { # Resource-node section @@ -194,6 +196,11 @@ The .Ic async replication mode is currently not implemented. .El +.It Ic timeout Aq seconds +.Pp +Connection timeout in seconds. +The default value is +.Va 5 . .It Ic name Aq name .Pp GEOM provider name that will appear as Index: sbin/hastd/hast.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/hast.h,v retrieving revision 1.1 diff -u -p -r1.1 hast.h --- sbin/hastd/hast.h 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/hast.h 28 Apr 2010 21:42:46 -0000 @@ -75,6 +75,7 @@ #define HIO_DELETE 3 #define HIO_FLUSH 4 +#define HAST_TIMEOUT 5 #define HAST_CONFIG "/etc/hast.conf" #define HAST_CONTROL "/var/run/hastctl" #define HASTD_PORT 8457 @@ -148,6 +149,8 @@ struct hast_resource { /* Token to verify both in and out connection are coming from the same node (not necessarily from the same address). */ unsigned char hr_token[HAST_TOKEN_SIZE]; + /* Connection timeout. */ + int hr_timeout; /* Resource unique identifier. */ uint64_t hr_resuid; Index: sbin/hastd/hastd.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/hastd.c,v retrieving revision 1.2 diff -u -p -r1.2 hastd.c --- sbin/hastd/hastd.c 16 Apr 2010 06:47:29 -0000 1.2 +++ sbin/hastd/hastd.c 28 Apr 2010 21:29:38 -0000 @@ -181,6 +181,10 @@ listen_accept(void) proto_remote_address(conn, raddr, sizeof(raddr)); pjdlog_info("Connection from %s to %s.", laddr, raddr); + /* Error in setting timeout is not critical, but why should it fail? */ + if (proto_timeout(conn, HAST_TIMEOUT) < 0) + pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); + nvin = nvout = nverr = NULL; /* Index: sbin/hastd/parse.y =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/parse.y,v retrieving revision 1.1 diff -u -p -r1.1 parse.y --- sbin/hastd/parse.y 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/parse.y 28 Apr 2010 17:27:29 -0000 @@ -58,6 +58,7 @@ static bool mynode; static char depth0_control[HAST_ADDRSIZE]; static char depth0_listen[HAST_ADDRSIZE]; static int depth0_replication; +static int depth0_timeout; static char depth1_provname[PATH_MAX]; static char depth1_localpath[PATH_MAX]; @@ -115,6 +116,7 @@ yy_config_parse(const char *config) curres = NULL; mynode = false; + depth0_timeout = HAST_TIMEOUT; depth0_replication = HAST_REPLICATION_MEMSYNC; strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); @@ -154,6 +156,13 @@ yy_config_parse(const char *config) */ curres->hr_replication = depth0_replication; } + if (curres->hr_timeout == -1) { + /* + * Timeout is not set at resource-level. + * Use global or default setting. + */ + curres->hr_timeout = depth0_timeout; + } } return (&lconfig); @@ -171,7 +180,7 @@ yy_config_free(struct hastd_config *conf } %} -%token CONTROL LISTEN PORT REPLICATION EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON +%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON %token FULLSYNC MEMSYNC ASYNC %token NUM STR OB CB @@ -200,6 +209,8 @@ statement: | replication_statement | + timeout_statement + | node_statement | resource_statement @@ -281,6 +292,22 @@ replication_type: ASYNC { $$ = HAST_REPLICATION_ASYNC; } ; +timeout_statement: TIMEOUT NUM + { + switch (depth) { + case 0: + depth0_timeout = $2; + break; + case 1: + if (curres != NULL) + curres->hr_timeout = $2; + break; + default: + assert(!"timeout at wrong depth level"); + } + } + ; + node_statement: ON node_start OB node_entries CB { mynode = false; @@ -389,6 +416,7 @@ resource_start: STR curres->hr_role = HAST_ROLE_INIT; curres->hr_previous_role = HAST_ROLE_INIT; curres->hr_replication = -1; + curres->hr_timeout = -1; curres->hr_provname[0] = '\0'; curres->hr_localpath[0] = '\0'; curres->hr_localfd = -1; @@ -405,6 +433,8 @@ resource_entries: resource_entry: replication_statement | + timeout_statement + | name_statement | local_statement Index: sbin/hastd/primary.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/primary.c,v retrieving revision 1.3 diff -u -p -r1.3 primary.c --- sbin/hastd/primary.c 15 Apr 2010 17:04:08 -0000 1.3 +++ sbin/hastd/primary.c 28 Apr 2010 17:16:02 -0000 @@ -489,6 +489,9 @@ init_remote(struct hast_resource *res, s res->hr_remoteaddr); goto close; } + /* Error in setting timeout is not critical, but why should it fail? */ + if (proto_timeout(out, res->hr_timeout) < 0) + pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); /* * First handshake step. * Setup outgoing connection with remote node. @@ -552,6 +555,9 @@ init_remote(struct hast_resource *res, s res->hr_remoteaddr); goto close; } + /* Error in setting timeout is not critical, but why should it fail? */ + if (proto_timeout(in, res->hr_timeout) < 0) + pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); nvout = nv_alloc(); nv_add_string(nvout, res->hr_name, "resource"); nv_add_uint8_array(nvout, res->hr_token, sizeof(res->hr_token), Index: sbin/hastd/proto.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/proto.c,v retrieving revision 1.1 diff -u -p -r1.1 proto.c --- sbin/hastd/proto.c 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/proto.c 28 Apr 2010 17:35:53 -0000 @@ -30,7 +30,9 @@ #include __FBSDID("$FreeBSD: src/sbin/hastd/proto.c,v 1.1 2010/02/18 23:16:19 pjd Exp $"); +#include #include +#include #include #include @@ -247,6 +249,30 @@ proto_remote_address(const struct proto_ conn->pc_proto->hp_remote_address(conn->pc_ctx, addr, size); } +int +proto_timeout(const struct proto_conn *conn, int timeout) +{ + struct timeval tv; + int fd; + + assert(conn != NULL); + assert(conn->pc_magic == PROTO_CONN_MAGIC); + assert(conn->pc_proto != NULL); + + fd = proto_descriptor(conn); + if (fd < 0) + return (-1); + + tv.tv_sec = timeout; + tv.tv_usec = 0; + if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) + return (-1); + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) + return (-1); + + return (0); +} + void proto_close(struct proto_conn *conn) { Index: sbin/hastd/proto.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/proto.h,v retrieving revision 1.1 diff -u -p -r1.1 proto.h --- sbin/hastd/proto.h 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/proto.h 28 Apr 2010 17:29:37 -0000 @@ -49,6 +49,7 @@ void proto_local_address(const struct pr size_t size); void proto_remote_address(const struct proto_conn *conn, char *addr, size_t size); +int proto_timeout(const struct proto_conn *conn, int timeout); void proto_close(struct proto_conn *conn); #endif /* !_PROTO_H_ */ Index: sbin/hastd/proto_common.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/proto_common.c,v retrieving revision 1.1 diff -u -p -r1.1 proto_common.c --- sbin/hastd/proto_common.c 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/proto_common.c 28 Apr 2010 21:41:40 -0000 @@ -58,7 +58,7 @@ proto_common_send(int fd, const unsigned if (done == 0) return (ENOTCONN); else if (done < 0) { - if (errno == EAGAIN) + if (errno == EINTR) continue; return (errno); } @@ -76,7 +76,7 @@ proto_common_recv(int fd, unsigned char do { done = recv(fd, data, size, MSG_WAITALL); - } while (done == -1 && errno == EAGAIN); + } while (done == -1 && errno == EINTR); if (done == 0) return (ENOTCONN); else if (done < 0) Index: sbin/hastd/secondary.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/secondary.c,v retrieving revision 1.1 diff -u -p -r1.1 secondary.c --- sbin/hastd/secondary.c 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/secondary.c 28 Apr 2010 17:20:19 -0000 @@ -337,6 +337,12 @@ hastd_secondary(struct hast_resource *re setproctitle("%s (secondary)", res->hr_name); + /* Error in setting timeout is not critical, but why should it fail? */ + if (proto_timeout(res->hr_remotein, 0) < 0) + pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); + if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0) + pjdlog_errno(LOG_WARNING, "Unable to set connection timeout"); + init_local(res); init_remote(res, nvin); init_environment(); Index: sbin/hastd/token.l =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/sbin/hastd/token.l,v retrieving revision 1.1 diff -u -p -r1.1 token.l --- sbin/hastd/token.l 18 Feb 2010 23:16:19 -0000 1.1 +++ sbin/hastd/token.l 28 Apr 2010 17:29:05 -0000 @@ -48,6 +48,7 @@ control { DP; return CONTROL; } listen { DP; return LISTEN; } port { DP; return PORT; } replication { DP; return REPLICATION; } +timeout { DP; return TIMEOUT; } resource { DP; return RESOURCE; } name { DP; return NAME; } local { DP; return LOCAL; }