adding version to the upcall
to determine that the daemon has restarted -- rather that daemon is receiving upcalls from the kernel that were processed by the old instance of the daemon -- add a version to the upcall mechanism. when daemon starts up it generates a version number (just a timestamp). it passes this value to the driver on start up via "start_ioctl" downcall. the driver saves that value in its device extensions. it uses that value in the mount and shtudown upcalls. when daemon replies to the mount command it again sends its version as a part of the reply. this reply is stored in driver;s netroot extensions. the driver uses netroot's value in each upcall to the daemon. if the daemon receives an upcall for an operation where the included version does not equal to the its current version, it fails the upcall (error_code=116). a restart of the daemon would change driver's device extension value which the driver will then use in the new mount upcalls that would establish new sessions. then the correct daemon version would be returned as a part of the mount downcalled and saved in the netroot.
This commit is contained in:
parent
765fb43156
commit
a25a5221d9
7 changed files with 101 additions and 35 deletions
|
|
@ -38,7 +38,7 @@
|
|||
#include "util.h"
|
||||
|
||||
#define MAX_NUM_THREADS 128
|
||||
BOOLEAN CREATED_SESSION = FALSE;
|
||||
DWORD NFS41D_VERSION = 0;
|
||||
|
||||
#ifndef STANDALONE_NFSD //make sure to define it in "sources" not here
|
||||
#include "service.h"
|
||||
|
|
@ -115,16 +115,6 @@ static unsigned int WINAPI thread_main(void *args)
|
|||
goto write_downcall;
|
||||
}
|
||||
|
||||
#if 1 //AGLO: this is just a placeholder for a real solution. I know this variable needs a lock in a
|
||||
//normal case. However, this does not prevent us from receiving an upcall for an old mount
|
||||
//that was not reestablished. It will only work for erroring requests until the 1st mount upcall.
|
||||
if (!CREATED_SESSION && (upcall.opcode != NFS41_MOUNT && upcall.opcode != NFS41_SHUTDOWN)) {
|
||||
eprintf("nfs41_daemon restarted and does not have a valid session established\n");
|
||||
upcall.status = 116;
|
||||
goto write_downcall;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (upcall.opcode == NFS41_SHUTDOWN) {
|
||||
printf("Shutting down..\n");
|
||||
exit(0);
|
||||
|
|
@ -132,11 +122,6 @@ static unsigned int WINAPI thread_main(void *args)
|
|||
|
||||
status = upcall_handle(&upcall);
|
||||
|
||||
#if 1 //AGLO: place holder for a real solution
|
||||
if (upcall.opcode == NFS41_MOUNT && upcall.status == NO_ERROR)
|
||||
CREATED_SESSION = 1;
|
||||
#endif
|
||||
|
||||
write_downcall:
|
||||
dprintf(1, "writing downcall: xid=%d opcode=%s status=%d "
|
||||
"get_last_error=%d\n", upcall.xid, opcode2string(upcall.opcode),
|
||||
|
|
@ -211,6 +196,9 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
|
|||
goto out_logs;
|
||||
}
|
||||
|
||||
NFS41D_VERSION = GetTickCount();
|
||||
dprintf(1, "NFS41 Daemon starting: version %d\n", NFS41D_VERSION);
|
||||
|
||||
pipe = CreateFile(NFS41_USER_DEVICE_NAME_A, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||||
0, NULL);
|
||||
|
|
@ -222,7 +210,7 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
|
|||
|
||||
dprintf(1, "starting nfs41 mini redirector\n");
|
||||
status = DeviceIoControl(pipe, IOCTL_NFS41_START,
|
||||
NULL, 0, NULL, 0, (LPDWORD)&len, NULL);
|
||||
&NFS41D_VERSION, sizeof(DWORD), NULL, 0, (LPDWORD)&len, NULL);
|
||||
if (!status) {
|
||||
eprintf("IOCTL_NFS41_START failed with %d\n",
|
||||
GetLastError());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue