Commit 579fade7 authored by Tatjana Baranova's avatar Tatjana Baranova Committed by Tigran Mkrtchyan
Browse files

nfsv41: do not use session handler as a singleton.

Each NFSv4.1 server needs it's own session tracking. This
becomes more important when two and more servers in
a single JVM.

Signed-off-by: Tatjana Baranova
Signed-off-by: Tigran Mkrtchyan
parent f7895bfc
......@@ -34,6 +34,7 @@ public class CompoundContext {
private final ExportFile _exportFile;
private final NFSv41DeviceManager _deviceManager;
private final AclHandler _aclHandler;
private final NFSv4StateHandler _stateHandler;
/**
* Create context of COUMPOUND request.
......@@ -45,6 +46,7 @@ public class CompoundContext {
* @param exportFile list of servers exports.
*/
public CompoundContext(List<nfs_resop4> processedOps, int minorversion, FileSystemProvider fs,
NFSv4StateHandler stateHandler,
NFSv41DeviceManager deviceManager, AclHandler aclHandler, RpcCall call, ExportFile exportFile) {
_processedOps = processedOps;
_minorversion = minorversion;
......@@ -54,6 +56,7 @@ public class CompoundContext {
_callInfo = call;
_exportFile = exportFile;
_user = HimeraNFS4Utils.remoteUser(_callInfo, _exportFile);
_stateHandler = stateHandler;
}
public RpcCall getRpcCall() {
......@@ -175,4 +178,8 @@ public class CompoundContext {
public List<nfs_resop4> processedOperations() {
return _processedOps;
}
public NFSv4StateHandler getStateHandler() {
return _stateHandler;
}
}
......@@ -31,6 +31,7 @@ public class NFSServerV41 extends nfs4_prot_NFS4_PROGRAM_ServerStub {
private final NFSv4OperationFactory _operationFactory;
private final NFSv41DeviceManager _deviceManager;
private final AclHandler _aclHandler;
private final NFSv4StateHandler _statHandler = new NFSv4StateHandler();
public NFSServerV41(NFSv4OperationFactory operationFactory,
NFSv41DeviceManager deviceManager, AclHandler aclHandler, FileSystemProvider fs,
......@@ -70,7 +71,7 @@ public class NFSServerV41 extends nfs4_prot_NFS4_PROGRAM_ServerStub {
}
CompoundContext context = new CompoundContext(v, arg1.minorversion.value,
_fs, _deviceManager, _aclHandler, call$, _exportFile);
_fs, _statHandler, _deviceManager, _aclHandler, call$, _exportFile);
for (nfs_argop4 op : arg1.argarray) {
......
......@@ -19,30 +19,20 @@ public class NFSv4StateHandler {
private static final Logger _log = LoggerFactory.getLogger(NFSv4StateHandler.class);
private static final NFSv4StateHandler HANDLER = new NFSv4StateHandler();
private List<NFS4Client> _clients = new ArrayList<NFS4Client>();
private final List<NFS4Client> _clients = new ArrayList<NFS4Client>();
// all seen by server
private static Map<String, NFS4Client> _clientsByVerifier = new HashMap<String, NFS4Client>();
private final Map<String, NFS4Client> _clientsByVerifier = new HashMap<String, NFS4Client>();
// mapping between server generated clietid and nfs_client_id, not confirmed yet
private static Map<Long, NFS4Client> _clientsByServerId = new HashMap<Long, NFS4Client>();
private static Map<stateid4, Long> _clientsByStateId = new HashMap<stateid4, Long>();
private final Map<Long, NFS4Client> _clientsByServerId = new HashMap<Long, NFS4Client>();
private final Map<stateid4, Long> _clientsByStateId = new HashMap<stateid4, Long>();
private final Cache<sessionid4, NFSv41Session> _sessionById =
new Cache<sessionid4, NFSv41Session>("NFSv41 sessions", 5000, Long.MAX_VALUE, TimeUnit.SECONDS.toMillis(NFSv4Defaults.NFS4_LEASE_TIME*2));
private static Map<String, NFS4Client> _clientByOwner = new HashMap<String, NFS4Client>();
private NFSv4StateHandler() {}
public static NFSv4StateHandler getInstace() {
return HANDLER;
}
private final Map<String, NFS4Client> _clientByOwner = new HashMap<String, NFS4Client>();
public void removeClient(NFS4Client client) {
......
......@@ -27,7 +27,7 @@ public class OperationCLOSE extends AbstractNFSv4Operation {
FsInode inode = context.currentInode();
if( context.getSession() == null ) {
NFSv4StateHandler.getInstace().updateClientLeaseTime(_args.opclose.open_stateid);
context.getStateHandler().updateClientLeaseTime(_args.opclose.open_stateid);
}else{
context.getSession().getClient().updateLeaseTime(NFSv4Defaults.NFS4_LEASE_TIME);
}
......
......@@ -49,7 +49,7 @@ public class OperationCREATE_SESSION extends AbstractNFSv4Operation {
throw new ChimeraNFSException(nfsstat4.NFS4ERR_INVAL, "bad ceate_session flag");
}
NFS4Client client = NFSv4StateHandler.getInstace().getClientByID(clientId);
NFS4Client client = context.getStateHandler().getClientByID(clientId);
/*
* Phase 1:
......@@ -95,7 +95,7 @@ public class OperationCREATE_SESSION extends AbstractNFSv4Operation {
session = client.createSession(_args.opcreate_session.csa_sequence.value.value,
_args.opcreate_session.csa_fore_chan_attrs.ca_maxrequests.value.value);
_log.debug("adding new session [{}]", session.id());
NFSv4StateHandler.getInstace().sessionById(session.id(), session);
context.getStateHandler().sessionById(session.id(), session);
}
client.refreshLeaseTime();
......
......@@ -24,7 +24,7 @@ public class OperationDESTROY_SESSION extends AbstractNFSv4Operation {
try {
NFSv41Session session = NFSv4StateHandler.getInstace().sessionById(_args.opdestroy_session.dsa_sessionid);
NFSv41Session session = context.getStateHandler().sessionById(_args.opdestroy_session.dsa_sessionid);
if(session == null) {
throw new ChimeraNFSException(nfsstat4.NFS4ERR_BADSESSION, "client not found");
}
......@@ -37,7 +37,7 @@ public class OperationDESTROY_SESSION extends AbstractNFSv4Operation {
*/
if( client.sessions().isEmpty() ) {
_log.debug("remove client: no sessions any more");
NFSv4StateHandler.getInstace().removeClient(client);
context.getStateHandler().removeClient(client);
}
res.dsr_status = nfsstat4.NFS4_OK;
......
......@@ -143,7 +143,7 @@ public class OperationEXCHANGE_ID extends AbstractNFSv4Operation {
//decision variable for case selection
NFS4Client client = NFSv4StateHandler.getInstace().clientByOwner(clientOwner);
NFS4Client client = context.getStateHandler().clientByOwner(clientOwner);
String principal = Integer.toString(context.getUser().getUID() );
byte[] verifier = _args.opexchange_id.eia_clientowner.co_verifier.value;
......@@ -163,7 +163,7 @@ public class OperationEXCHANGE_ID extends AbstractNFSv4Operation {
_log.debug("Case 1: New Owner ID");
client = new NFS4Client(remoteSocketAddress, localSocketAddress,
clientOwner, _args.opexchange_id.eia_clientowner.co_verifier.value , principal);
NFSv4StateHandler.getInstace().addClient(client);
context.getStateHandler().addClient(client);
}else{
......@@ -193,17 +193,17 @@ public class OperationEXCHANGE_ID extends AbstractNFSv4Operation {
}else if ( principal.equals(client.principal() ) ) {
_log.debug("case 5: Client Restart");
NFSv4StateHandler.getInstace().removeClient(client);
context.getStateHandler().removeClient(client);
client = new NFS4Client(remoteSocketAddress, localSocketAddress,
new String(_args.opexchange_id.eia_clientowner.co_ownerid), _args.opexchange_id.eia_clientowner.co_verifier.value , principal);
NFSv4StateHandler.getInstace().addClient(client);
context.getStateHandler().addClient(client);
}else {
if ((!client.hasState()) || (System.currentTimeMillis() - client.leaseTime()) > (NFSv4Defaults.NFS4_LEASE_TIME * 1000)){
_log.debug("case 3a: Client Collision is equivalent to case 1 (the new Owner ID)");
NFSv4StateHandler.getInstace().removeClient(client);
context.getStateHandler().removeClient(client);
client = new NFS4Client(remoteSocketAddress, localSocketAddress,
new String(_args.opexchange_id.eia_clientowner.co_ownerid), _args.opexchange_id.eia_clientowner.co_verifier.value, principal);
NFSv4StateHandler.getInstace().addClient(client);
context.getStateHandler().addClient(client);
} else {
_log.debug("Case 3b: Client Collision");
throw new ChimeraNFSException(nfsstat4.NFS4ERR_CLID_INUSE, "Principal Missmatch");
......@@ -211,10 +211,10 @@ public class OperationEXCHANGE_ID extends AbstractNFSv4Operation {
}
}else{
_log.debug("case 4: Replacement of Unconfirmed Record");
NFSv4StateHandler.getInstace().removeClient(client);
context.getStateHandler().removeClient(client);
client = new NFS4Client(remoteSocketAddress, localSocketAddress,
new String(_args.opexchange_id.eia_clientowner.co_ownerid), _args.opexchange_id.eia_clientowner.co_verifier.value , principal);
NFSv4StateHandler.getInstace().addClient(client);
context.getStateHandler().addClient(client);
}
}
......
......@@ -45,7 +45,7 @@ public class OperationOPEN extends AbstractNFSv4Operation {
NFS4Client client = null;
if (context.getSession() == null) {
client = NFSv4StateHandler.getInstace().getClientByID(clientid);
client = context.getStateHandler().getClientByID(clientid);
if (client == null || !client.isConfirmed()) {
throw new ChimeraNFSException(nfsstat4.NFS4ERR_STALE_CLIENTID, "bad client id.");
......@@ -174,7 +174,7 @@ public class OperationOPEN extends AbstractNFSv4Operation {
res.resok4.stateid = nfs4state.stateid();
client.addState(nfs4state);
NFSv4StateHandler.getInstace().addClinetByStateID(nfs4state.stateid(), clientid);
context.getStateHandler().addClinetByStateID(nfs4state.stateid(), clientid);
_log.debug("New stateID: {}", nfs4state.stateid());
res.status = nfsstat4.NFS4_OK;
......
......@@ -39,12 +39,12 @@ public class OperationOPEN_CONFIRM extends AbstractNFSv4Operation {
stateid4 stateid = _args.opopen_confirm.open_stateid;
_log.debug("confirmed stateID: {}", stateid );
Long clientId = NFSv4StateHandler.getInstace().getClientIdByStateId(stateid);
Long clientId = context.getStateHandler().getClientIdByStateId(stateid);
if(clientId == null ) {
throw new ChimeraNFSException( nfsstat4.NFS4ERR_BAD_STATEID, "bad client id." );
}
NFS4Client client = NFSv4StateHandler.getInstace().getClientByID(clientId);
NFS4Client client = context.getStateHandler().getClientByID(clientId);
if(client == null ) {
throw new ChimeraNFSException( nfsstat4.NFS4ERR_BAD_STATEID, "bad client id." );
}
......
......@@ -52,7 +52,7 @@ public class OperationREAD extends AbstractNFSv4Operation {
* and RENEW opertations. With introduction of sessions in
* v4.1 update of the lease time done through SEQUENCE operation.
*/
NFSv4StateHandler.getInstace().updateClientLeaseTime(_args.opread.stateid);
context.getStateHandler().updateClientLeaseTime(_args.opread.stateid);
}
......
......@@ -25,7 +25,7 @@ public class OperationRENEW extends AbstractNFSv4Operation {
try {
Long clientid = Long.valueOf(_args.oprenew.clientid.value.value);
NFS4Client client = NFSv4StateHandler.getInstace().getClientByID( clientid );
NFS4Client client = context.getStateHandler().getClientByID( clientid );
if( client == null ) {
throw new ChimeraNFSException(nfsstat4.NFS4ERR_STALE_CLIENTID, "Bad client id");
}
......
......@@ -55,7 +55,7 @@ public class OperationSEQUENCE extends AbstractNFSv4Operation {
res.sr_resok4.sr_target_highest_slotid = new slotid4(_args.opsequence.sa_slotid.value);
res.sr_resok4.sr_sessionid = new sessionid4(_args.opsequence.sa_sessionid.value);
NFSv41Session session = NFSv4StateHandler.getInstace().sessionById(_args.opsequence.sa_sessionid);
NFSv41Session session = context.getStateHandler().sessionById(_args.opsequence.sa_sessionid);
if(session == null ) {
_log.debug("no session for id [{}]", _args.opsequence.sa_sessionid );
......
......@@ -31,7 +31,7 @@ public class OperationSETCLIENTID extends AbstractNFSv4Operation {
byte[] clientid = _args.opsetclientid.client.id; // clientid
if( NFSv4StateHandler.getInstace().getClientByVerifier(clientid) != null ) {
if( context.getStateHandler().getClientByVerifier(clientid) != null ) {
throw new ChimeraNFSException(nfsstat4.NFS4ERR_CLID_INUSE, "Client Id In use");
}
......@@ -53,7 +53,7 @@ public class OperationSETCLIENTID extends AbstractNFSv4Operation {
_log.debug("no callback defined for: {}", context.getRpcCall().getTransport().getRemoteSocketAddress().getAddress());
}
NFSv4StateHandler.getInstace().addClient(client);
context.getStateHandler().addClient(client);
res.resok4 = new SETCLIENTID4resok();
res.resok4.clientid = new clientid4();
......
......@@ -24,7 +24,7 @@ public class OperationSETCLIENTID_CONFIRM extends AbstractNFSv4Operation {
try {
Long clientid = Long.valueOf(_args.opsetclientid_confirm.clientid.value.value);
NFS4Client client = NFSv4StateHandler.getInstace().getClientByID(clientid);
NFS4Client client = context.getStateHandler().getClientByID(clientid);
if (client == null) {
throw new ChimeraNFSException(nfsstat4.NFS4ERR_STALE_CLIENTID, "Bad client id");
}
......
......@@ -58,7 +58,7 @@ public class OperationWRITE extends AbstractNFSv4Operation {
if( context.getSession() == null ) {
NFSv4StateHandler.getInstace().updateClientLeaseTime(_args.opwrite.stateid);
context.getStateHandler().updateClientLeaseTime(_args.opwrite.stateid);
}else{
context.getSession().getClient().updateLeaseTime(NFSv4Defaults.NFS4_LEASE_TIME);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment