Change how auto-reconnect works
For NFS sessions, change the autoreconnect options to be : -1: (default) retry connectiong back to the server forever. Just like normal NFS clients do. 0: Do not attempt reconnecting at all. Immediately fail and return an error back to the application on session loss. >=1: Retry connecting to the server this many times before giving up. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>libnfs-4.0.0-vitalif
parent
eee1b4f7f2
commit
173ad2b1f3
14
README
14
README
|
@ -56,11 +56,15 @@ Arguments supported by libnfs are :
|
|||
: Should libnfs try to traverse across nested mounts
|
||||
automatically or not. Default is 1 == enabled.
|
||||
dircache=<0|1> : Disable/enable directory caching. Enabled by default.
|
||||
autoreconnect=<0|1>
|
||||
: Disable/enable reconnection when connections close.
|
||||
When disabled, closed connections will cause an
|
||||
immediate error return, with loss of commands and
|
||||
data that are still inflight. Default is 1 == enabled.
|
||||
autoreconnect=<-1|0|>=1>
|
||||
: Control the auto-reconnect behaviour to the NFS session.
|
||||
-1 : Try to reconnect forever on session failures.
|
||||
Just like normal NFS clients do.
|
||||
0 : Disable auto-reconnect completely and immediately
|
||||
return a failure to the application.
|
||||
>=1 : Retry to connect back to the server this many
|
||||
times before failing and returing an error back
|
||||
to the application.
|
||||
if=<interface> : Interface name (e.g., eth1) to bind; requires `root`
|
||||
|
||||
Auto_traverse_mounts
|
||||
|
|
|
@ -133,7 +133,7 @@ struct rpc_context {
|
|||
/* track the address we connect to so we can auto-reconnect on session failure */
|
||||
struct sockaddr_storage s;
|
||||
int auto_reconnect;
|
||||
int auto_reconnect_retries;
|
||||
int num_retries;
|
||||
|
||||
/* fragment reassembly */
|
||||
struct rpc_fragment *fragments;
|
||||
|
@ -218,8 +218,7 @@ int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int i
|
|||
struct rpc_context *rpc_init_udp_context(void);
|
||||
struct sockaddr *rpc_get_recv_sockaddr(struct rpc_context *rpc);
|
||||
|
||||
void rpc_set_autoreconnect(struct rpc_context *rpc);
|
||||
void rpc_unset_autoreconnect(struct rpc_context *rpc);
|
||||
void rpc_set_autoreconnect(struct rpc_context *rpc, int num_retries);
|
||||
|
||||
void rpc_set_interface(struct rpc_context *rpc, const char *ifname);
|
||||
|
||||
|
|
|
@ -183,11 +183,15 @@ EXTERN void nfs_destroy_context(struct nfs_context *nfs);
|
|||
* : Should libnfs try to traverse across nested mounts
|
||||
* automatically or not. Default is 1 == enabled.
|
||||
* dircache=<0|1> : Disable/enable directory caching. Enabled by default.
|
||||
* autoreconnect=<0|1>
|
||||
* : Disable/enable reconnection when connections close.
|
||||
* When disabled, closed connections will cause an
|
||||
* immediate error return, with loss of commands and
|
||||
* data that are still inflight. Default is 1 == enabled.
|
||||
* autoreconnect=<-1|0|>=1>
|
||||
* : Control the auto-reconnect behaviour to the NFS session.
|
||||
* -1 : Try to reconnect forever on session failures.
|
||||
* Just like normal NFS clients do.
|
||||
* 0 : Disable auto-reconnect completely and immediately
|
||||
* return a failure to the application.
|
||||
* >=1 : Retry to connect back to the server this many
|
||||
* times before failing and returing an error back
|
||||
* to the application.
|
||||
*/
|
||||
/*
|
||||
* Parse a complete NFS URL including, server, path and
|
||||
|
@ -238,7 +242,7 @@ EXTERN void nfs_set_pagecache_ttl(struct nfs_context *nfs, uint32_t v);
|
|||
EXTERN void nfs_set_readahead(struct nfs_context *nfs, uint32_t v);
|
||||
EXTERN void nfs_set_debug(struct nfs_context *nfs, int level);
|
||||
EXTERN void nfs_set_dircache(struct nfs_context *nfs, int enabled);
|
||||
EXTERN void nfs_set_autoreconnect(struct nfs_context *nfs, int enabled);
|
||||
EXTERN void nfs_set_autoreconnect(struct nfs_context *nfs, int num_retries);
|
||||
|
||||
/*
|
||||
* Invalidate the pagecache
|
||||
|
|
16
lib/libnfs.c
16
lib/libnfs.c
|
@ -148,7 +148,7 @@ struct nfs_context {
|
|||
uint64_t writemax;
|
||||
char *cwd;
|
||||
int dircache_enabled;
|
||||
int auto_reconnect_enabled;
|
||||
int auto_reconnect;
|
||||
struct nfsdir *dircache;
|
||||
uint16_t mask;
|
||||
|
||||
|
@ -532,7 +532,8 @@ struct nfs_context *nfs_init_context(void)
|
|||
nfs->mask = 022;
|
||||
nfs->auto_traverse_mounts = 1;
|
||||
nfs->dircache_enabled = 1;
|
||||
nfs->auto_reconnect_enabled = 1;
|
||||
/* Default is never give up, never surrender */
|
||||
nfs->auto_reconnect = -1;
|
||||
return nfs;
|
||||
}
|
||||
|
||||
|
@ -1023,11 +1024,10 @@ static void nfs_mount_9_cb(struct rpc_context *rpc, int status, void *command_da
|
|||
return;
|
||||
}
|
||||
|
||||
/* NFS TCP connections should be autoreconnected after sessions have
|
||||
* been torn down (due to inactivity or error)
|
||||
/* NFS TCP: As we are connected now we can pass on the auto-reconnect
|
||||
* settings to the RPC layer.
|
||||
*/
|
||||
if (nfs->auto_reconnect_enabled)
|
||||
rpc_set_autoreconnect(rpc);
|
||||
rpc_set_autoreconnect(rpc, nfs->auto_reconnect);
|
||||
|
||||
args.fsroot = nfs->rootfh;
|
||||
if (rpc_nfs3_fsinfo_async(rpc, nfs_mount_10_cb, &args, data) != 0) {
|
||||
|
@ -5607,8 +5607,8 @@ void nfs_set_dircache(struct nfs_context *nfs, int enabled) {
|
|||
nfs->dircache_enabled = enabled;
|
||||
}
|
||||
|
||||
void nfs_set_autoreconnect(struct nfs_context *nfs, int enabled) {
|
||||
nfs->auto_reconnect_enabled = enabled;
|
||||
void nfs_set_autoreconnect(struct nfs_context *nfs, int num_retries) {
|
||||
nfs->auto_reconnect = num_retries;
|
||||
}
|
||||
|
||||
void nfs_set_error(struct nfs_context *nfs, char *error_string, ...)
|
||||
|
|
43
lib/socket.c
43
lib/socket.c
|
@ -85,8 +85,6 @@
|
|||
#include "win32_errnowrapper.h"
|
||||
#endif
|
||||
|
||||
#define NR_RECONNECT_RETRIES 10
|
||||
|
||||
static int rpc_reconnect_requeue(struct rpc_context *rpc);
|
||||
|
||||
static int create_socket(int domain, int type, int protocol)
|
||||
|
@ -476,7 +474,7 @@ int rpc_service(struct rpc_context *rpc, int revents)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void rpc_set_autoreconnect(struct rpc_context *rpc)
|
||||
void rpc_set_autoreconnect(struct rpc_context *rpc, int num_retries)
|
||||
{
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
|
@ -485,18 +483,7 @@ void rpc_set_autoreconnect(struct rpc_context *rpc)
|
|||
return;
|
||||
}
|
||||
|
||||
rpc->auto_reconnect = 1;
|
||||
}
|
||||
|
||||
void rpc_unset_autoreconnect(struct rpc_context *rpc)
|
||||
{
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
if (rpc->is_server_context) {
|
||||
return;
|
||||
}
|
||||
|
||||
rpc->auto_reconnect = 0;
|
||||
rpc->auto_reconnect = num_retries;
|
||||
}
|
||||
|
||||
void rpc_set_tcp_syncnt(struct rpc_context *rpc, int v)
|
||||
|
@ -717,7 +704,8 @@ int rpc_disconnect(struct rpc_context *rpc, const char *error)
|
|||
if (!rpc->is_connected) {
|
||||
return 0;
|
||||
}
|
||||
rpc_unset_autoreconnect(rpc);
|
||||
/* Disable autoreconnect */
|
||||
rpc_set_autoreconnect(rpc, 0);
|
||||
|
||||
if (rpc->fd != -1) {
|
||||
close(rpc->fd);
|
||||
|
@ -756,8 +744,15 @@ static int rpc_reconnect_requeue(struct rpc_context *rpc)
|
|||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
if (rpc->is_connected)
|
||||
rpc->auto_reconnect_retries = NR_RECONNECT_RETRIES;
|
||||
if (rpc->auto_reconnect == 0) {
|
||||
RPC_LOG(rpc, 1, "reconnect is disabled");
|
||||
rpc_error_all_pdus(rpc, "RPC ERROR: Failed to reconnect async");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rpc->is_connected) {
|
||||
rpc->num_retries = rpc->auto_reconnect;
|
||||
}
|
||||
|
||||
if (rpc->fd != -1) {
|
||||
rpc->old_fd = rpc->fd;
|
||||
|
@ -784,20 +779,20 @@ static int rpc_reconnect_requeue(struct rpc_context *rpc)
|
|||
}
|
||||
rpc->waitpdu_len = 0;
|
||||
|
||||
if (rpc->auto_reconnect != 0 && rpc->auto_reconnect_retries > 0) {
|
||||
rpc->auto_reconnect_retries--;
|
||||
if (rpc->auto_reconnect < 0 || rpc->num_retries > 0) {
|
||||
rpc->num_retries--;
|
||||
rpc->connect_cb = reconnect_cb;
|
||||
RPC_LOG(rpc, 1, "reconnect initiated");
|
||||
if (rpc_connect_sockaddr_async(rpc) != 0) {
|
||||
rpc_error_all_pdus(rpc, "RPC ERROR: Failed to reconnect async");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
RPC_LOG(rpc, 1, "reconnect NOT initiated, auto-reconnect is disabled");
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
RPC_LOG(rpc, 1, "reconnect: all attempts failed.");
|
||||
rpc_error_all_pdus(rpc, "RPC ERROR: All attempts to reconnect failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue