- From d5033f344376d843fb505094ec84846aa482d83f Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 17 Nov 2023 16:32:10 +0100
- Subject: [PATCH 1/4] sys/nfs41_driver: |nfs41_UpcallWaitForReply()| should
- always retry
- |nfs41_UpcallWaitForReply()| should always retry
- |KeWaitForSingleObject()|, even for NFS41_CLOSE and NFS41_UNLOCK.
- Simplifies this codepath and per review comments is the right thing
- to do.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- sys/nfs41_driver.c | 52 +++++++++++++---------------------------------
- 1 file changed, 14 insertions(+), 38 deletions(-)
- diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
- index 97f6445..8e7f34c 100644
- --- a/sys/nfs41_driver.c
- +++ b/sys/nfs41_driver.c
- @@ -1471,47 +1471,23 @@ NTSTATUS nfs41_UpcallWaitForReply(
- nfs41_AddEntry(upcallLock, upcall, entry);
- KeSetEvent(&upcallEvent, 0, FALSE);
- - if (!entry->async_op) {
- - LARGE_INTEGER timeout;
- - timeout.QuadPart = RELATIVE(SECONDS(secs));
- - /* 02/03/2011 AGLO: it is not clear what the "right" waiting design
- - * should be. Having non-interruptable waiting seems to be the right
- - * approach. However, when things go wrong, the only wait to proceed
- - * is a reboot (since "waits" are not interruptable we can't stop a
- - * hung task. Having interruptable wait causes issues with security
- - * context. For now, I'm making CLOSE non-interruptable but keeping
- - * the rest interruptable so that we don't have to reboot all the time
- - */
- - /* 02/15/2011 cbodley: added NFS41_UNLOCK for the same reason. locking
- - * tests were triggering an interrupted unlock, which led to a bugcheck
- - * in CloseSrvOpen() */
- -retry_wait:
- -#define MAKE_WAITONCLOSE_NONITERRUPTABLE
- -#ifdef MAKE_WAITONCLOSE_NONITERRUPTABLE
- - if (entry->opcode == NFS41_CLOSE || entry->opcode == NFS41_UNLOCK)
- - status = KeWaitForSingleObject(&entry->cond, Executive,
- - KernelMode, FALSE, &timeout);
- - else {
- - status = KeWaitForSingleObject(&entry->cond, Executive,
- - UserMode, TRUE, &timeout);
- - }
- - if (status != STATUS_SUCCESS) {
- - print_wait_status(1, "[downcall]", status,
- - ENTRY_OPCODE2STRING(entry), entry,
- - (entry?entry->xid:-1LL));
- - if (status == STATUS_TIMEOUT)
- - status = STATUS_NETWORK_UNREACHABLE;
- - }
- -#else
- - status = KeWaitForSingleObject(&entry->cond, Executive, KernelMode, FALSE, NULL);
- -#endif
- - print_wait_status(0, "[downcall]", status,
- - ENTRY_OPCODE2STRING(entry), entry,
- - (entry?entry->xid:-1LL));
- - } else
- + if (entry->async_op)
- goto out;
- + LARGE_INTEGER timeout;
- + timeout.QuadPart = RELATIVE(SECONDS(secs));
- +retry_wait:
- + status = KeWaitForSingleObject(&entry->cond, Executive,
- + UserMode, TRUE, &timeout);
- +
- + if (status == STATUS_TIMEOUT)
- + status = STATUS_NETWORK_UNREACHABLE;
- +
- + print_wait_status(0, "[downcall]", status,
- + ENTRY_OPCODE2STRING(entry), entry,
- + (entry?entry->xid:-1LL));
- +
- switch(status) {
- case STATUS_SUCCESS:
- break;
- --
- 2.42.1
- From afdf65bb9e67c24025be6d4fd96043fa8c2450b3 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 17 Nov 2023 16:53:13 +0100
- Subject: [PATCH 2/4] cygwin/Makefile: Package sshnfs and mount_sshnfs scripts
- and ksh93
- Add the sshnfs and mount_sshnfs utility scripts to the Cygwin
- tarball, and package ksh93&shcomp if the system has it installed
- (because Cygwin still has no ksh93 package).
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- cygwin/Makefile | 8 ++++++++
- 1 file changed, 8 insertions(+)
- diff --git a/cygwin/Makefile b/cygwin/Makefile
- index 2e9fcba..301ea56 100644
- --- a/cygwin/Makefile
- +++ b/cygwin/Makefile
- @@ -56,6 +56,7 @@ installdest: $(VS_BUILD_DIR)/nfsd.exe \
- fi
- mkdir -p $(DESTDIR)
- mkdir -p $(DESTDIR)/cygdrive/c/cygwin64/sbin/
- + mkdir -p $(DESTDIR)/cygdrive/c/cygwin64/usr/bin
- cp -r $(VS_BUILD_DIR)/nfsd.exe $(DESTDIR)/cygdrive/c/cygwin64/sbin/nfsd_debug.exe
- cp -r $(VS_BUILD_DIR)/nfsd.pdb $(DESTDIR)/cygdrive/c/cygwin64/sbin/nfsd_debug.pdb
- cp -r $(VS_BUILD_DIR)/nfs_mount.* $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
- @@ -68,7 +69,14 @@ installdest: $(VS_BUILD_DIR)/nfsd.exe \
- cp $(PROJECT_BASEDIR_DIR)/etc_netconfig $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
- cp $(PROJECT_BASEDIR_DIR)/ms-nfs41-idmap.conf $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
- cp $(CYGWIN_MAKEFILE_DIR)/devel/msnfs41client.bash $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
- + cp $(CYGWIN_MAKEFILE_DIR)/utils/mount_sshnfs/mount_sshnfs.ksh $(DESTDIR)/cygdrive/c/cygwin64/sbin/mount_sshnfs
- + chmod a+x $(DESTDIR)/cygdrive/c/cygwin64/sbin/mount_sshnfs
- + cp $(CYGWIN_MAKEFILE_DIR)/utils/sshnfs/sshnfs.ksh $(DESTDIR)/cygdrive/c/cygwin64/sbin/sshnfs
- + chmod a+x $(DESTDIR)/cygdrive/c/cygwin64/sbin/sshnfs
- (cd $(DESTDIR)/cygdrive/c/cygwin64/sbin/ ; chmod a+x *.exe *.dll *.sys *.bash)
- + @ printf "# Package ksh93&co (if available) since Cygwin does not ship with it yet\n"
- + [[ -x /usr/bin/ksh93.exe ]] && cp /usr/bin/ksh93.exe $(DESTDIR)/cygdrive/c/cygwin64/usr/bin/ksh93.exe
- + [[ -x /usr/bin/shcomp.exe ]] && cp /usr/bin/shcomp.exe $(DESTDIR)/cygdrive/c/cygwin64/usr/bin/shcomp.exe
- @printf "\n#\n# TEST sbin dir is %s\n#\n" "$(DESTDIR)/cygdrive/c/cygwin64/sbin/"
- @printf '\n'
- @printf "\n#\n# Now use\n# $$ cd '%s' && bash ./msnfs41client.bash install #\n# to install the kernel driver as Admin\n#\n" \
- --
- 2.42.1
- From b5b1124496fa3d97f2e328eac742a735cdec508b Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 17 Nov 2023 17:02:44 +0100
- Subject: [PATCH 3/4] tests: Add first prototype of
- winlocktest1/winlocktest1.ksh
- Add first prototype of winlocktest1/winlocktest1.ksh to test
- Win32 native locking with the NFSv4 client across mounts
- of the same NFSv4 filesystem.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/winlocktest1/winlocktest1.ksh | 210 ++++++++++++++++++++++++++++
- 1 file changed, 210 insertions(+)
- create mode 100644 tests/winlocktest1/winlocktest1.ksh
- diff --git a/tests/winlocktest1/winlocktest1.ksh b/tests/winlocktest1/winlocktest1.ksh
- new file mode 100644
- index 0000000..8b0307b
- --- /dev/null
- +++ b/tests/winlocktest1/winlocktest1.ksh
- @@ -0,0 +1,210 @@
- +#!/usr/bin/ksh93
- +
- +#
- +# winlocktest1 - test whether Win32 locks work across NFSv4 mounts
- +#
- +# Written by Roland Mainz <roland.mainz@nrubsig.org>
- +#
- +
- +#
- +# Usage:
- +# 1. modify NFSv4 server location+mount path
- +# 2. run
- +# 3. should print "#### Test OK ####"
- +#
- +
- +function pw2u
- +{
- + printf '%s\n' "$(cygpath -w "$1")"
- +}
- +
- +function cygdrive_nfs_mount_dir
- +{
- + typeset hostname=$2
- + typeset mountpath=$3
- + nameref mntpoint=$1
- + integer retval=0
- +
- + #nfs_mount -p -o sec=sys T "derfwnb4966_ipv6:/net_tmpfs2"
- +
- + stdout="${ nfs_mount -o sec=sys '*' "${hostname}:${mountpath}" ; (( retval=$? )) ;}"
- + #cat <<<"$stdout"
- +
- + if (( retval == 0 )) ; then
- + # Parse stdout for drive letter
- + dummy="${stdout/~(E)Successfully mounted (.+) to drive (?:\'|)(.+):(?:\'|)/dummy}"
- +
- + # fixme: we should test whether c.windows_drive_letter is empty or not
- + windows_drive_letter="${.sh.match[2]}"
- +
- + mntpoint="/cygdrive/$windows_drive_letter/"
- + return 0
- + fi
- +
- + return 1
- +}
- +
- +function cygdrive_nfs_umount_dir
- +{
- + typeset mntpath="$1"
- +
- + net use "${mntpath/~(Elr)\/cygdrive\/(.)(\/.*|)/}:" /delete || true
- +}
- +
- +function compile_test_programm
- +{
- + rm -f 'tmp_winlocktest1.c'
- + cat >'tmp_winlocktest1.c' <<EOF
- +/*
- + * compile with
- + * $ gcc -g -Wall winlocktest1.c -o winlocktest1
- + */
- +
- +#define UNICODE 1
- +
- +#include <windows.h>
- +#include <stdio.h>
- +
- +int main(int ac, char *av[])
- +{
- + OVERLAPPED ovl = { 0 };
- + const char *taskname;
- + const char *filename;
- + const char *text_to_write;
- + int sleep_before_lock;
- + int sleep_while_lock_held;
- +
- + if (ac != 6) {
- + (void)fprintf(stderr, "%s: Usage: "
- + "%s "
- + "<taskname> "
- + "<filename> "
- + "<text-to-write> "
- + "<sec-to-sleep-before-lock> "
- + "<sec-to-sleep-while-lock-is-held>\n",
- + av[0], av[0]);
- + return 1;
- + }
- +
- + taskname = av[1];
- + filename = av[2];
- + text_to_write = av[3];
- + sleep_before_lock = atoi(av[4]);
- + sleep_while_lock_held = atoi(av[5]);
- +
- + (void)printf("# %s: start\n", taskname);
- +
- + // Open the file for read and write access.
- + HANDLE hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- + if (hFile == INVALID_HANDLE_VALUE) {
- + perror("Error opening file.\n");
- + return 1;
- + }
- +
- + (void)printf("# %s: sleeping\n", taskname);
- + Sleep(sleep_before_lock*1000);
- +
- + (void)printf("# %s: before lock\n", taskname);
- + // Lock the file from offset 10 to offset 20.
- + if (LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 10, 20, &ovl) == 0) {
- + fprintf(stderr, "Error locking file.\n");
- + CloseHandle(hFile);
- + return 1;
- + }
- + (void)printf("# %s: file locked\n", taskname);
- +
- + Sleep(sleep_while_lock_held*1000);
- +
- + // Perform some operations on the locked region of the file.
- + DWORD bytesWritten;
- + if (WriteFile(hFile, text_to_write, strlen(text_to_write), &bytesWritten, NULL) == 0) {
- + fprintf(stderr, "Error writing to file.\n");
- + UnlockFileEx(hFile, 0, 10, 20, &ovl);
- + CloseHandle(hFile);
- + return 1;
- + }
- +
- + // Unlock the file.
- + if (UnlockFileEx(hFile, 0, 10, 20, &ovl) == 0) {
- + fprintf(stderr, "Error unlocking file.\n");
- + CloseHandle(hFile);
- + return 1;
- + }
- + (void)printf("# %s: file unlocked\n", taskname);
- +
- + // Close the file.
- + CloseHandle(hFile);
- + (void)printf("# %s: done\n", taskname);
- +
- + return 0;
- +}
- +EOF
- + rm -f winlocktest1.exe
- + gcc -g -Wall tmp_winlocktest1.c -o winlocktest1.exe
- +}
- +
- +#
- +# main
- +#
- +set -o xtrace
- +set -o errexit
- +set -o nounset
- +
- +PATH+=':/home/roland_mainz/work/msnfs41_uidmapping/ms-nfs41-client/destdir/cygdrive/c/cygwin64/sbin/'
- +
- +
- +# td==testdata
- +compound td
- +
- +td.hostname="derfwnb4966_ipv6"
- +td.mntpoint="/net_tmpfs2"
- +
- +compile_test_programm || exit 1
- +
- +cygdrive_nfs_mount_dir td.basedir "${td.hostname}" "${td.mntpoint}" || exit 1
- +
- +mkdir -p "${td.basedir}/lockdir2/test1"
- +
- +cygdrive_nfs_mount_dir td.dir1 "${td.hostname}" "${td.mntpoint}/lockdir2" || exit 1
- +td.dir1+="/test1"
- +cygdrive_nfs_mount_dir td.dir2 "${td.hostname}" "${td.mntpoint}/lockdir2/test1" || exit 1
- +
- +print -v td
- +
- +printf 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n' >"${td.dir1}/example.txt"
- +
- +
- +./winlocktest1.exe "T1" "$(pw2u "${td.dir1}/example.txt")" ".......... test 12345" 1 12 &
- +./winlocktest1.exe "T2" "$(pw2u "${td.dir2}/example.txt")" ".......... test ABCDE" 4 1 &
- +sleep 2
- +
- +# this should fail, because T1 has locked "${td.dir1}/example.txt"
- +if [[ "$( { cat "${td.dir1}/example.txt" || true ; } 2>&1)" == *busy* ]] ; then
- + print OK
- +fi
- +# this should fail, because T1 has locked "${td.dir1}/example.txt"
- +if [[ "$( { cat "${td.dir2}/example.txt" || true ; } 2>&1)" == *busy* ]] ; then
- + print OK
- +fi
- +
- +wait
- +cat -n "${td.dir1}/example.txt"
- +cat -n "${td.dir2}/example.txt"
- +
- +#
- +# cleanup - must be successful, no leftover files
- +#
- +rm "${td.basedir}/lockdir2/test1/example.txt"
- +rmdir "${td.basedir}/lockdir2/test1"
- +rmdir "${td.basedir}/lockdir2"
- +
- +#
- +# unmount test dirs
- +#
- +cygdrive_nfs_umount_dir "${td.dir2}" || true
- +cygdrive_nfs_umount_dir "${td.dir1}" || true
- +cygdrive_nfs_umount_dir "${td.basedir}" || true
- +
- +print "#### Test OK ####"
- +
- +# EOF.
- --
- 2.42.1
- From 42c7cff56f2d6010a2ffd2ebb67be96df4c35232 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 17 Nov 2023 17:29:12 +0100
- Subject: [PATCH 4/4] mount_sshnfs.ksh: Fix issue with parsing nfs_mount.exe
- output
- mount_sshnfs.ksh: Fix issue with parsing nfs_mount.exe output,
- where newer versions have quotes around the driver letter.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- cygwin/utils/mount_sshnfs/mount_sshnfs.ksh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- mode change 100644 => 100755 cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
- diff --git a/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh b/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
- old mode 100644
- new mode 100755
- index 8eb16f1..9b5c76e
- --- a/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
- +++ b/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
- @@ -583,7 +583,7 @@ function cmd_mount
- if (( retval == 0 )) ; then
- # Parse stdout for drive letter
- - dummy="${stdout/~(E)Successfully mounted (.+) to drive (.+):/dummy}"
- + dummy="${stdout/~(E)Successfully mounted (.+) to drive (?:\'|)(.+):(?:\'|)/dummy}"
- # fixme: we should test whether c.windows_drive_letter is empty or not
- typeset c.windows_drive_letter="${.sh.match[2]}"
- --
- 2.42.1
msnfs41client: Patches for driver retry cleanup, Cygwin, mount_sshnfs etc, 2023-11-17
Posted by Anonymous on Fri 17th Nov 2023 17:33
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.