diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2014-03-18 09:24:35 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2014-07-10 12:35:01 -0400 |
commit | 5d0b17f1a29e8189d04aef447a3a53cfd05529b2 (patch) | |
tree | 2d53fe259fd70241a40f33438b4b3676676bbf2c | |
parent | 4920e37a9e851172158ecc0fd7e060712dc1b5e8 (diff) |
drbd: New net configuration option socket-check-timeout
In setups involving a DRBD-proxy and connections that experience a lot of
buffer-bloat it might be necessary to set ping-timeout to an
unusual high value. By default DRBD uses the same value to wait if a newly
established TCP-connection is stable. Since the DRBD-proxy is usually located
in the same data center such a long wait time may hinder DRBD's connect process.
In such setups socket-check-timeout should be set to
at least to the round trip time between DRBD and DRBD-proxy. I.e. in most
cases to 1.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 46 | ||||
-rw-r--r-- | include/linux/drbd_genl.h | 1 | ||||
-rw-r--r-- | include/linux/drbd_limits.h | 5 |
3 files changed, 36 insertions, 16 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 7da83f3a61eb..b89e6fb468c6 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -819,7 +819,7 @@ static int receive_first_packet(struct drbd_connection *connection, struct socke | |||
819 | * drbd_socket_okay() - Free the socket if its connection is not okay | 819 | * drbd_socket_okay() - Free the socket if its connection is not okay |
820 | * @sock: pointer to the pointer to the socket. | 820 | * @sock: pointer to the pointer to the socket. |
821 | */ | 821 | */ |
822 | static int drbd_socket_okay(struct socket **sock) | 822 | static bool drbd_socket_okay(struct socket **sock) |
823 | { | 823 | { |
824 | int rr; | 824 | int rr; |
825 | char tb[4]; | 825 | char tb[4]; |
@@ -837,6 +837,30 @@ static int drbd_socket_okay(struct socket **sock) | |||
837 | return false; | 837 | return false; |
838 | } | 838 | } |
839 | } | 839 | } |
840 | |||
841 | static bool connection_established(struct drbd_connection *connection, | ||
842 | struct socket **sock1, | ||
843 | struct socket **sock2) | ||
844 | { | ||
845 | struct net_conf *nc; | ||
846 | int timeout; | ||
847 | bool ok; | ||
848 | |||
849 | if (!*sock1 || !*sock2) | ||
850 | return false; | ||
851 | |||
852 | rcu_read_lock(); | ||
853 | nc = rcu_dereference(connection->net_conf); | ||
854 | timeout = (nc->sock_check_timeo ?: nc->ping_timeo) * HZ / 10; | ||
855 | rcu_read_unlock(); | ||
856 | schedule_timeout_interruptible(timeout); | ||
857 | |||
858 | ok = drbd_socket_okay(sock1); | ||
859 | ok = drbd_socket_okay(sock2) && ok; | ||
860 | |||
861 | return ok; | ||
862 | } | ||
863 | |||
840 | /* Gets called if a connection is established, or if a new minor gets created | 864 | /* Gets called if a connection is established, or if a new minor gets created |
841 | in a connection */ | 865 | in a connection */ |
842 | int drbd_connected(struct drbd_peer_device *peer_device) | 866 | int drbd_connected(struct drbd_peer_device *peer_device) |
@@ -878,8 +902,8 @@ static int conn_connect(struct drbd_connection *connection) | |||
878 | struct drbd_socket sock, msock; | 902 | struct drbd_socket sock, msock; |
879 | struct drbd_peer_device *peer_device; | 903 | struct drbd_peer_device *peer_device; |
880 | struct net_conf *nc; | 904 | struct net_conf *nc; |
881 | int vnr, timeout, h, ok; | 905 | int vnr, timeout, h; |
882 | bool discard_my_data; | 906 | bool discard_my_data, ok; |
883 | enum drbd_state_rv rv; | 907 | enum drbd_state_rv rv; |
884 | struct accept_wait_data ad = { | 908 | struct accept_wait_data ad = { |
885 | .connection = connection, | 909 | .connection = connection, |
@@ -923,17 +947,8 @@ static int conn_connect(struct drbd_connection *connection) | |||
923 | } | 947 | } |
924 | } | 948 | } |
925 | 949 | ||
926 | if (sock.socket && msock.socket) { | 950 | if (connection_established(connection, &sock.socket, &msock.socket)) |
927 | rcu_read_lock(); | 951 | break; |
928 | nc = rcu_dereference(connection->net_conf); | ||
929 | timeout = nc->ping_timeo * HZ / 10; | ||
930 | rcu_read_unlock(); | ||
931 | schedule_timeout_interruptible(timeout); | ||
932 | ok = drbd_socket_okay(&sock.socket); | ||
933 | ok = drbd_socket_okay(&msock.socket) && ok; | ||
934 | if (ok) | ||
935 | break; | ||
936 | } | ||
937 | 952 | ||
938 | retry: | 953 | retry: |
939 | s = drbd_wait_for_connect(connection, &ad); | 954 | s = drbd_wait_for_connect(connection, &ad); |
@@ -979,8 +994,7 @@ randomize: | |||
979 | goto out_release_sockets; | 994 | goto out_release_sockets; |
980 | } | 995 | } |
981 | 996 | ||
982 | ok = drbd_socket_okay(&sock.socket); | 997 | ok = connection_established(connection, &sock.socket, &msock.socket); |
983 | ok = drbd_socket_okay(&msock.socket) && ok; | ||
984 | } while (!ok); | 998 | } while (!ok); |
985 | 999 | ||
986 | if (ad.s_listen) | 1000 | if (ad.s_listen) |
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h index 71fc924c53fa..7b131ed8f9c6 100644 --- a/include/linux/drbd_genl.h +++ b/include/linux/drbd_genl.h | |||
@@ -174,6 +174,7 @@ GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf, | |||
174 | /* 9: __str_field_def(31, DRBD_GENLA_F_MANDATORY, name, SHARED_SECRET_MAX) */ | 174 | /* 9: __str_field_def(31, DRBD_GENLA_F_MANDATORY, name, SHARED_SECRET_MAX) */ |
175 | /* 9: __u32_field(32, DRBD_F_REQUIRED | DRBD_F_INVARIANT, peer_node_id) */ | 175 | /* 9: __u32_field(32, DRBD_F_REQUIRED | DRBD_F_INVARIANT, peer_node_id) */ |
176 | __flg_field_def(33, 0 /* OPTIONAL */, csums_after_crash_only, DRBD_CSUMS_AFTER_CRASH_ONLY_DEF) | 176 | __flg_field_def(33, 0 /* OPTIONAL */, csums_after_crash_only, DRBD_CSUMS_AFTER_CRASH_ONLY_DEF) |
177 | __u32_field_def(34, 0 /* OPTIONAL */, sock_check_timeo, DRBD_SOCKET_CHECK_TIMEO_DEF) | ||
177 | ) | 178 | ) |
178 | 179 | ||
179 | GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms, | 180 | GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms, |
diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index 9d2df1d51414..8ac8c5d9a3ad 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h | |||
@@ -225,4 +225,9 @@ | |||
225 | #define DRBD_AL_STRIPE_SIZE_MAX 16777216 | 225 | #define DRBD_AL_STRIPE_SIZE_MAX 16777216 |
226 | #define DRBD_AL_STRIPE_SIZE_DEF 32 | 226 | #define DRBD_AL_STRIPE_SIZE_DEF 32 |
227 | #define DRBD_AL_STRIPE_SIZE_SCALE 'k' /* kilobytes */ | 227 | #define DRBD_AL_STRIPE_SIZE_SCALE 'k' /* kilobytes */ |
228 | |||
229 | #define DRBD_SOCKET_CHECK_TIMEO_MIN 0 | ||
230 | #define DRBD_SOCKET_CHECK_TIMEO_MAX DRBD_PING_TIMEO_MAX | ||
231 | #define DRBD_SOCKET_CHECK_TIMEO_DEF 0 | ||
232 | #define DRBD_SOCKET_CHECK_TIMEO_SCALE '1' | ||
228 | #endif | 233 | #endif |