pastebin - collaborative debugging tool
rovema.kpaste.net RSS


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

  1. From d5033f344376d843fb505094ec84846aa482d83f Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Fri, 17 Nov 2023 16:32:10 +0100
  4. Subject: [PATCH 1/4] sys/nfs41_driver: |nfs41_UpcallWaitForReply()| should
  5.  always retry
  6.  
  7. |nfs41_UpcallWaitForReply()| should always retry
  8. |KeWaitForSingleObject()|, even for NFS41_CLOSE and NFS41_UNLOCK.
  9. Simplifies this codepath and per review comments is the right thing
  10. to do.
  11.  
  12. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  13. ---
  14. sys/nfs41_driver.c | 52 +++++++++++++---------------------------------
  15.  1 file changed, 14 insertions(+), 38 deletions(-)
  16.  
  17. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  18. index 97f6445..8e7f34c 100644
  19. --- a/sys/nfs41_driver.c
  20. +++ b/sys/nfs41_driver.c
  21. @@ -1471,47 +1471,23 @@ NTSTATUS nfs41_UpcallWaitForReply(
  22.  
  23.      nfs41_AddEntry(upcallLock, upcall, entry);
  24.      KeSetEvent(&upcallEvent, 0, FALSE);
  25. -    if (!entry->async_op) {
  26. -        LARGE_INTEGER timeout;
  27. -        timeout.QuadPart = RELATIVE(SECONDS(secs));
  28. -        /* 02/03/2011 AGLO: it is not clear what the "right" waiting design
  29. -         * should be. Having non-interruptable waiting seems to be the right
  30. -         * approach. However, when things go wrong, the only wait to proceed
  31. -         * is a reboot (since "waits" are not interruptable we can't stop a
  32. -         * hung task. Having interruptable wait causes issues with security
  33. -         * context. For now, I'm making CLOSE non-interruptable but keeping
  34. -         * the rest interruptable so that we don't have to reboot all the time
  35. -         */
  36. -        /* 02/15/2011 cbodley: added NFS41_UNLOCK for the same reason. locking
  37. -         * tests were triggering an interrupted unlock, which led to a bugcheck
  38. -         * in CloseSrvOpen() */
  39. -retry_wait:
  40. -#define MAKE_WAITONCLOSE_NONITERRUPTABLE
  41. -#ifdef MAKE_WAITONCLOSE_NONITERRUPTABLE
  42. -        if (entry->opcode == NFS41_CLOSE || entry->opcode == NFS41_UNLOCK)
  43. -            status = KeWaitForSingleObject(&entry->cond, Executive,
  44. -                        KernelMode, FALSE, &timeout);
  45. -        else {
  46. -            status = KeWaitForSingleObject(&entry->cond, Executive,
  47. -                        UserMode, TRUE, &timeout);
  48. -        }
  49. -        if (status != STATUS_SUCCESS) {
  50. -            print_wait_status(1, "[downcall]", status,
  51. -                ENTRY_OPCODE2STRING(entry), entry,
  52. -                (entry?entry->xid:-1LL));
  53. -            if (status == STATUS_TIMEOUT)
  54. -                status = STATUS_NETWORK_UNREACHABLE;
  55. -        }
  56. -#else
  57.  
  58. -        status = KeWaitForSingleObject(&entry->cond, Executive, KernelMode, FALSE, NULL);
  59. -#endif
  60. -        print_wait_status(0, "[downcall]", status,
  61. -            ENTRY_OPCODE2STRING(entry), entry,
  62. -            (entry?entry->xid:-1LL));
  63. -    } else
  64. +    if (entry->async_op)
  65.          goto out;
  66.  
  67. +    LARGE_INTEGER timeout;
  68. +    timeout.QuadPart = RELATIVE(SECONDS(secs));
  69. +retry_wait:
  70. +    status = KeWaitForSingleObject(&entry->cond, Executive,
  71. +                UserMode, TRUE, &timeout);
  72. +
  73. +    if (status == STATUS_TIMEOUT)
  74. +            status = STATUS_NETWORK_UNREACHABLE;
  75. +
  76. +    print_wait_status(0, "[downcall]", status,
  77. +        ENTRY_OPCODE2STRING(entry), entry,
  78. +        (entry?entry->xid:-1LL));
  79. +
  80.      switch(status) {
  81.      case STATUS_SUCCESS:
  82.          break;
  83. --
  84. 2.42.1
  85.  
  86. From afdf65bb9e67c24025be6d4fd96043fa8c2450b3 Mon Sep 17 00:00:00 2001
  87. From: Roland Mainz <roland.mainz@nrubsig.org>
  88. Date: Fri, 17 Nov 2023 16:53:13 +0100
  89. Subject: [PATCH 2/4] cygwin/Makefile: Package sshnfs and mount_sshnfs scripts
  90.  and ksh93
  91.  
  92. Add the sshnfs and mount_sshnfs utility scripts to the Cygwin
  93. tarball, and package ksh93&shcomp if the system has it installed
  94. (because Cygwin still has no ksh93 package).
  95.  
  96. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  97. ---
  98. cygwin/Makefile | 8 ++++++++
  99.  1 file changed, 8 insertions(+)
  100.  
  101. diff --git a/cygwin/Makefile b/cygwin/Makefile
  102. index 2e9fcba..301ea56 100644
  103. --- a/cygwin/Makefile
  104. +++ b/cygwin/Makefile
  105. @@ -56,6 +56,7 @@ installdest: $(VS_BUILD_DIR)/nfsd.exe \
  106.         fi
  107.         mkdir -p $(DESTDIR)
  108.         mkdir -p $(DESTDIR)/cygdrive/c/cygwin64/sbin/
  109. +       mkdir -p $(DESTDIR)/cygdrive/c/cygwin64/usr/bin
  110.         cp -r $(VS_BUILD_DIR)/nfsd.exe          $(DESTDIR)/cygdrive/c/cygwin64/sbin/nfsd_debug.exe
  111.         cp -r $(VS_BUILD_DIR)/nfsd.pdb          $(DESTDIR)/cygdrive/c/cygwin64/sbin/nfsd_debug.pdb
  112.         cp -r $(VS_BUILD_DIR)/nfs_mount.*       $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
  113. @@ -68,7 +69,14 @@ installdest: $(VS_BUILD_DIR)/nfsd.exe \
  114.         cp $(PROJECT_BASEDIR_DIR)/etc_netconfig $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
  115.         cp $(PROJECT_BASEDIR_DIR)/ms-nfs41-idmap.conf $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
  116.         cp $(CYGWIN_MAKEFILE_DIR)/devel/msnfs41client.bash $(DESTDIR)/cygdrive/c/cygwin64/sbin/.
  117. +       cp $(CYGWIN_MAKEFILE_DIR)/utils/mount_sshnfs/mount_sshnfs.ksh $(DESTDIR)/cygdrive/c/cygwin64/sbin/mount_sshnfs
  118. +       chmod a+x $(DESTDIR)/cygdrive/c/cygwin64/sbin/mount_sshnfs
  119. +       cp $(CYGWIN_MAKEFILE_DIR)/utils/sshnfs/sshnfs.ksh $(DESTDIR)/cygdrive/c/cygwin64/sbin/sshnfs
  120. +       chmod a+x $(DESTDIR)/cygdrive/c/cygwin64/sbin/sshnfs
  121.         (cd $(DESTDIR)/cygdrive/c/cygwin64/sbin/ ; chmod a+x *.exe *.dll *.sys *.bash)
  122. +       @ printf "# Package ksh93&co (if available) since Cygwin does not ship with it yet\n"
  123. +       [[ -x /usr/bin/ksh93.exe ]] && cp /usr/bin/ksh93.exe $(DESTDIR)/cygdrive/c/cygwin64/usr/bin/ksh93.exe
  124. +       [[ -x /usr/bin/shcomp.exe ]] && cp /usr/bin/shcomp.exe $(DESTDIR)/cygdrive/c/cygwin64/usr/bin/shcomp.exe
  125.         @printf "\n#\n# TEST sbin dir is %s\n#\n" "$(DESTDIR)/cygdrive/c/cygwin64/sbin/"
  126.         @printf '\n'
  127.         @printf "\n#\n# Now use\n# $$ cd '%s' && bash ./msnfs41client.bash install #\n# to install the kernel driver as Admin\n#\n" \
  128. --
  129. 2.42.1
  130.  
  131. From b5b1124496fa3d97f2e328eac742a735cdec508b Mon Sep 17 00:00:00 2001
  132. From: Roland Mainz <roland.mainz@nrubsig.org>
  133. Date: Fri, 17 Nov 2023 17:02:44 +0100
  134. Subject: [PATCH 3/4] tests: Add first prototype of
  135.  winlocktest1/winlocktest1.ksh
  136.  
  137. Add first prototype of winlocktest1/winlocktest1.ksh to test
  138. Win32 native locking with the NFSv4 client across mounts
  139. of the same NFSv4 filesystem.
  140.  
  141. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  142. ---
  143. tests/winlocktest1/winlocktest1.ksh | 210 ++++++++++++++++++++++++++++
  144.  1 file changed, 210 insertions(+)
  145.  create mode 100644 tests/winlocktest1/winlocktest1.ksh
  146.  
  147. diff --git a/tests/winlocktest1/winlocktest1.ksh b/tests/winlocktest1/winlocktest1.ksh
  148. new file mode 100644
  149. index 0000000..8b0307b
  150. --- /dev/null
  151. +++ b/tests/winlocktest1/winlocktest1.ksh
  152. @@ -0,0 +1,210 @@
  153. +#!/usr/bin/ksh93
  154. +
  155. +#
  156. +# winlocktest1 - test whether Win32 locks work across NFSv4 mounts
  157. +#
  158. +# Written by Roland Mainz <roland.mainz@nrubsig.org>
  159. +#
  160. +
  161. +#
  162. +# Usage:
  163. +# 1. modify NFSv4 server location+mount path
  164. +# 2. run
  165. +# 3. should print "#### Test OK ####"
  166. +#
  167. +
  168. +function pw2u
  169. +{
  170. +       printf '%s\n' "$(cygpath -w "$1")"
  171. +}
  172. +
  173. +function cygdrive_nfs_mount_dir
  174. +{
  175. +       typeset hostname=$2
  176. +       typeset mountpath=$3
  177. +       nameref mntpoint=$1
  178. +       integer retval=0
  179. +
  180. +       #nfs_mount -p -o sec=sys T "derfwnb4966_ipv6:/net_tmpfs2"
  181. +
  182. +       stdout="${ nfs_mount -o sec=sys '*' "${hostname}:${mountpath}" ; (( retval=$? )) ;}"
  183. +       #cat <<<"$stdout"
  184. +
  185. +       if (( retval == 0 )) ; then
  186. +               # Parse stdout for drive letter
  187. +               dummy="${stdout/~(E)Successfully mounted (.+) to drive (?:\'|)(.+):(?:\'|)/dummy}"
  188. +
  189. +               # fixme: we should test whether c.windows_drive_letter is empty or not
  190. +               windows_drive_letter="${.sh.match[2]}"
  191. +
  192. +               mntpoint="/cygdrive/$windows_drive_letter/"
  193. +               return 0
  194. +       fi
  195. +
  196. +       return 1
  197. +}
  198. +
  199. +function cygdrive_nfs_umount_dir
  200. +{
  201. +       typeset mntpath="$1"
  202. +
  203. +       net use "${mntpath/~(Elr)\/cygdrive\/(.)(\/.*|)/}:" /delete || true
  204. +}
  205. +
  206. +function compile_test_programm
  207. +{
  208. +       rm -f 'tmp_winlocktest1.c'
  209. +       cat >'tmp_winlocktest1.c' <<EOF
  210. +/*
  211. + * compile with
  212. + * $ gcc -g -Wall winlocktest1.c -o winlocktest1
  213. + */
  214. +
  215. +#define UNICODE 1
  216. +
  217. +#include <windows.h>
  218. +#include <stdio.h>
  219. +
  220. +int main(int ac, char *av[])
  221. +{
  222. +       OVERLAPPED ovl = { 0 };
  223. +       const char *taskname;
  224. +       const char *filename;
  225. +       const char *text_to_write;
  226. +       int sleep_before_lock;
  227. +       int sleep_while_lock_held;
  228. +
  229. +       if (ac != 6) {
  230. +               (void)fprintf(stderr, "%s: Usage: "
  231. +                       "%s "
  232. +                       "<taskname> "
  233. +                       "<filename> "
  234. +                       "<text-to-write> "
  235. +                       "<sec-to-sleep-before-lock> "
  236. +                       "<sec-to-sleep-while-lock-is-held>\n",
  237. +                       av[0], av[0]);
  238. +               return 1;
  239. +       }
  240. +
  241. +       taskname = av[1];
  242. +       filename = av[2];
  243. +       text_to_write = av[3];
  244. +       sleep_before_lock = atoi(av[4]);
  245. +       sleep_while_lock_held = atoi(av[5]);
  246. +
  247. +       (void)printf("# %s: start\n", taskname);
  248. +
  249. +       // Open the file for read and write access.
  250. +       HANDLE hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  251. +       if (hFile == INVALID_HANDLE_VALUE) {
  252. +               perror("Error opening file.\n");
  253. +               return 1;
  254. +       }
  255. +
  256. +       (void)printf("# %s: sleeping\n", taskname);
  257. +       Sleep(sleep_before_lock*1000);
  258. +
  259. +       (void)printf("# %s: before lock\n", taskname);
  260. +       // Lock the file from offset 10 to offset 20.
  261. +       if (LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 10, 20, &ovl) == 0) {
  262. +               fprintf(stderr, "Error locking file.\n");
  263. +               CloseHandle(hFile);
  264. +               return 1;
  265. +       }
  266. +       (void)printf("# %s: file locked\n", taskname);
  267. +
  268. +       Sleep(sleep_while_lock_held*1000);
  269. +
  270. +       // Perform some operations on the locked region of the file.
  271. +       DWORD bytesWritten;
  272. +       if (WriteFile(hFile, text_to_write, strlen(text_to_write), &bytesWritten, NULL) == 0) {
  273. +               fprintf(stderr, "Error writing to file.\n");
  274. +               UnlockFileEx(hFile, 0, 10, 20, &ovl);
  275. +               CloseHandle(hFile);
  276. +               return 1;
  277. +       }
  278. +
  279. +       // Unlock the file.
  280. +       if (UnlockFileEx(hFile, 0, 10, 20, &ovl) == 0) {
  281. +               fprintf(stderr, "Error unlocking file.\n");
  282. +               CloseHandle(hFile);
  283. +               return 1;
  284. +       }
  285. +       (void)printf("# %s: file unlocked\n", taskname);
  286. +
  287. +       // Close the file.
  288. +       CloseHandle(hFile);
  289. +       (void)printf("# %s: done\n", taskname);
  290. +
  291. +       return 0;
  292. +}
  293. +EOF
  294. +       rm -f winlocktest1.exe
  295. +       gcc -g -Wall tmp_winlocktest1.c -o winlocktest1.exe
  296. +}
  297. +
  298. +#
  299. +# main
  300. +#
  301. +set -o xtrace
  302. +set -o errexit
  303. +set -o nounset
  304. +
  305. +PATH+=':/home/roland_mainz/work/msnfs41_uidmapping/ms-nfs41-client/destdir/cygdrive/c/cygwin64/sbin/'
  306. +
  307. +
  308. +# td==testdata
  309. +compound td
  310. +
  311. +td.hostname="derfwnb4966_ipv6"
  312. +td.mntpoint="/net_tmpfs2"
  313. +
  314. +compile_test_programm || exit 1
  315. +
  316. +cygdrive_nfs_mount_dir td.basedir "${td.hostname}" "${td.mntpoint}" || exit 1
  317. +
  318. +mkdir -p "${td.basedir}/lockdir2/test1"
  319. +
  320. +cygdrive_nfs_mount_dir td.dir1 "${td.hostname}" "${td.mntpoint}/lockdir2" || exit 1
  321. +td.dir1+="/test1"
  322. +cygdrive_nfs_mount_dir td.dir2 "${td.hostname}" "${td.mntpoint}/lockdir2/test1" || exit 1
  323. +
  324. +print -v td
  325. +
  326. +printf 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n' >"${td.dir1}/example.txt"
  327. +
  328. +
  329. +./winlocktest1.exe "T1" "$(pw2u "${td.dir1}/example.txt")" ".......... test 12345" 1 12 &
  330. +./winlocktest1.exe "T2" "$(pw2u "${td.dir2}/example.txt")" ".......... test ABCDE" 4 1 &
  331. +sleep 2
  332. +
  333. +# this should fail, because T1 has locked "${td.dir1}/example.txt"
  334. +if [[ "$( { cat "${td.dir1}/example.txt" || true ; } 2>&1)" == *busy* ]] ; then
  335. +       print OK
  336. +fi
  337. +# this should fail, because T1 has locked "${td.dir1}/example.txt"
  338. +if [[ "$( { cat "${td.dir2}/example.txt" || true ; } 2>&1)" == *busy* ]] ; then
  339. +       print OK
  340. +fi
  341. +
  342. +wait
  343. +cat -n "${td.dir1}/example.txt"
  344. +cat -n "${td.dir2}/example.txt"
  345. +
  346. +#
  347. +# cleanup - must be successful, no leftover files
  348. +#
  349. +rm "${td.basedir}/lockdir2/test1/example.txt"
  350. +rmdir "${td.basedir}/lockdir2/test1"
  351. +rmdir "${td.basedir}/lockdir2"
  352. +
  353. +#
  354. +# unmount test dirs
  355. +#
  356. +cygdrive_nfs_umount_dir "${td.dir2}" || true
  357. +cygdrive_nfs_umount_dir "${td.dir1}" || true
  358. +cygdrive_nfs_umount_dir "${td.basedir}" || true
  359. +
  360. +print "#### Test OK ####"
  361. +
  362. +# EOF.
  363. --
  364. 2.42.1
  365.  
  366. From 42c7cff56f2d6010a2ffd2ebb67be96df4c35232 Mon Sep 17 00:00:00 2001
  367. From: Roland Mainz <roland.mainz@nrubsig.org>
  368. Date: Fri, 17 Nov 2023 17:29:12 +0100
  369. Subject: [PATCH 4/4] mount_sshnfs.ksh: Fix issue with parsing nfs_mount.exe
  370.  output
  371.  
  372. mount_sshnfs.ksh: Fix issue with parsing nfs_mount.exe output,
  373. where newer versions have quotes around the driver letter.
  374.  
  375. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  376. ---
  377. cygwin/utils/mount_sshnfs/mount_sshnfs.ksh | 2 +-
  378.  1 file changed, 1 insertion(+), 1 deletion(-)
  379.  mode change 100644 => 100755 cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
  380.  
  381. diff --git a/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh b/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
  382. old mode 100644
  383. new mode 100755
  384. index 8eb16f1..9b5c76e
  385. --- a/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
  386. +++ b/cygwin/utils/mount_sshnfs/mount_sshnfs.ksh
  387. @@ -583,7 +583,7 @@ function cmd_mount
  388.  
  389.                                 if (( retval == 0 )) ; then
  390.                                         # Parse stdout for drive letter
  391. -                                       dummy="${stdout/~(E)Successfully mounted (.+) to drive (.+):/dummy}"
  392. +                                       dummy="${stdout/~(E)Successfully mounted (.+) to drive (?:\'|)(.+):(?:\'|)/dummy}"
  393.  
  394.                                         # fixme: we should test whether c.windows_drive_letter is empty or not
  395.                                         typeset c.windows_drive_letter="${.sh.match[2]}"
  396. --
  397. 2.42.1

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at