- # Debug code to hung hunt down the native Windows tar issue
 - # So far it seems the zeros do not happen during read, only the NFS41_WRITE codepath sees (and writes to the NFS server) them
 - # Next-best guess is that this happens in the kernel, or that the kernel doesn't flush the cache, or ...
 - #
 - # 1480/impersonated_user='roland_mainz'/'Kein' read_from_mds(upcall->state_ref->path.path='\bigdisk\builds\win_tar_test\wintar_tmp\bin\shcomp.exe',args->offset=458752): first 512 bytes are '\0', maxreadsize=131072, status=0
 - # 2644/impersonated_user='roland_mainz'/'Kein' write_to_mds(upcall->state_ref->path.path='\bigdisk\builds\win_tar_test\tmp\10000seq.txt',args->offset=32768): layer1: first 512 bytes are '\0', maxwritesize=65536
 - # 2644/impersonated_user='roland_mainz'/'Kein' write_to_mds(upcall->state_ref->path.path='\bigdisk\builds\win_tar_test\tmp\10000seq.txt',args->offset=32768): layer2: first 512 bytes are '\0', maxwritesize=65536
 - # 2630/impersonated_user='roland_mainz'/'Kein' read_from_mds(upcall->state_ref->path.path='\bigdisk\builds\win_tar_test\tmp\10000seq.txt',args->offset=48894): first 512 bytes are '\0', maxreadsize=131072, status=0
 - diff --git a/daemon/readwrite.c b/daemon/readwrite.c
 - index 14e4bcb..c238228 100644
 - --- a/daemon/readwrite.c
 - +++ b/daemon/readwrite.c
 - @@ -22,6 +22,7 @@
 - #include <Windows.h>
 - #include <stdio.h>
 - +#include <stdbool.h>
 - #include "nfs41_ops.h"
 - #include "name_cache.h"
 - @@ -103,6 +104,30 @@ static int read_from_mds(
 - }
 - }
 - out:
 - +
 - +#if 1
 - +#define NUM_TEST_BYTES_FOR_ZERO 512
 - + if (len > NUM_TEST_BYTES_FOR_ZERO) {
 - + uint32_t zz;
 - + const unsigned char *zzc;
 - + for (zz = 0, zzc = args->buffer ; zz < NUM_TEST_BYTES_FOR_ZERO ; zz++, zzc++) {
 - + if (*zzc != 0)
 - + break;
 - + }
 - +
 - + if (zz == NUM_TEST_BYTES_FOR_ZERO) {
 - + DPRINTF(0,
 - + ("read_from_mds(upcall->state_ref->path.path='%s',args->offset=%lld): "
 - + "first %d bytes are '\\0', maxreadsize=%d, status=%d\n",
 - + upcall->state_ref->path.path,
 - + (long long)args->offset,
 - + (int)NUM_TEST_BYTES_FOR_ZERO,
 - + (int)maxreadsize,
 - + (int)status));
 - + }
 - + }
 - +#endif
 - +
 - args->out_len = len;
 - return status;
 - }
 - @@ -166,6 +191,10 @@ static int handle_read(void *daemon_context, nfs41_upcall *upcall)
 - args->out_len += pnfs_bytes_read;
 - out:
 - +
 - +#if 1
 - + FlushProcessWriteBuffers();
 - +#endif
 - return status;
 - }
 - @@ -181,7 +210,11 @@ static int write_to_mds(
 - nfs41_write_verf verf;
 - enum stable_how4 stable, committed;
 - unsigned char *p;
 - +#if 1
 - + const uint32_t maxwritesize = 131072/2;
 - +#else
 - const uint32_t maxwritesize = max_write_size(session, &file->fh);
 - +#endif
 - uint32_t to_send, reloffset, len;
 - int status = 0;
 - /* on write verifier mismatch, retry N times before failing */
 - @@ -189,18 +222,87 @@ static int write_to_mds(
 - nfs41_file_info info;
 - (void)memset(&info, 0, sizeof(info));
 - + bool virtlockpages = false;
 - +
 - +#if 1
 - + if (args->len > NUM_TEST_BYTES_FOR_ZERO) {
 - + uint32_t zz;
 - + const unsigned char *zzc;
 - + for (zz = 0, zzc = args->buffer ; zz < NUM_TEST_BYTES_FOR_ZERO ; zz++, zzc++) {
 - + if (*zzc != 0)
 - + break;
 - + }
 - +
 - + if (zz == NUM_TEST_BYTES_FOR_ZERO) {
 - + DPRINTF(0,
 - + ("write_to_mds(upcall->state_ref->path.path='%s',args->offset=%lld): "
 - + "layer1: first %d bytes are '\\0', maxwritesize=%d\n",
 - + upcall->state_ref->path.path,
 - + (long long)args->offset,
 - + (int)NUM_TEST_BYTES_FOR_ZERO,
 - + (int)maxwritesize));
 - + }
 - + }
 - +#endif
 - +
 - +#if 0
 - + if (!VirtualLock(args->buffer, args->len)) {
 - + DPRINTF(0,
 - + ("write_to_mds(upcall->state_ref->path.path='%s'): "
 - + "VirtualLock() failed, GetLastError()=%d\n",
 - + upcall->state_ref->path.path, (int)GetLastError()));
 - + status = NFS4ERR_IO;
 - + goto out;
 - + }
 - + virtlockpages = true;
 - +#endif
 - +
 - +#if 1
 - +#if defined(_M_IX86) || defined(_M_X64)
 - + {
 - + uint32_t zz;
 - + const unsigned char *zzc;
 - + for (zz = 0, zzc = args->buffer ; zz < args->len ; zz+=64, zzc+=64) {
 - + _mm_clflush(zzc);
 - + }
 - + FlushProcessWriteBuffers();
 - + }
 - +#endif /* defined(_M_IX86) || defined(_M_X64) */
 - +#endif
 - +
 - +#if 1
 - + if (args->len > NUM_TEST_BYTES_FOR_ZERO) {
 - + uint32_t zz;
 - + const unsigned char *zzc;
 - + for (zz = 0, zzc = args->buffer ; zz < NUM_TEST_BYTES_FOR_ZERO ; zz++, zzc++) {
 - + if (*zzc != 0)
 - + break;
 - + }
 - +
 - + if (zz == NUM_TEST_BYTES_FOR_ZERO) {
 - + DPRINTF(0,
 - + ("write_to_mds(upcall->state_ref->path.path='%s',args->offset=%lld): "
 - + "layer2: first %d bytes are '\\0', maxwritesize=%d\n",
 - + upcall->state_ref->path.path,
 - + (long long)args->offset,
 - + (int)NUM_TEST_BYTES_FOR_ZERO,
 - + (int)maxwritesize));
 - + }
 - + }
 - +#endif
 - +
 - retry_write:
 - p = args->buffer;
 - to_send = args->len;
 - reloffset = 0;
 - len = 0;
 - - stable = to_send <= maxwritesize ? FILE_SYNC4 : UNSTABLE4;
 - + stable = to_send < maxwritesize ? FILE_SYNC4 : UNSTABLE4;
 - committed = FILE_SYNC4;
 - - if (to_send > maxwritesize) {
 - - DPRINTF(1, ("handle_nfs41_write: writing %d in chunks of %d\n",
 - - to_send, maxwritesize));
 - + if (to_send >= maxwritesize) {
 - + DPRINTF(0, ("write_to_mds(upcall->state_ref->path.path='%s'): writing %d in chunks of %d\n",
 - + upcall->state_ref->path.path, to_send, maxwritesize));
 - }
 - while(to_send > 0) {
 - @@ -208,8 +310,12 @@ retry_write:
 - status = nfs41_write(session, file, stateid, p, chunk,
 - args->offset + reloffset, stable, &bytes_written, &verf, &info);
 - - if (status && !len)
 - - goto out;
 - + if (status && !len) {
 - + DPRINTF(0,
 - + ("write_to_mds: fail status=%d, len=%ld\n",
 - + (int)status, (long)len));
 - + goto out;
 - + }
 - p += bytes_written;
 - to_send -= bytes_written;
 - len += bytes_written;
 - @@ -247,6 +353,9 @@ retry_write:
 - args->ctime = info.change;
 - out:
 - + if (virtlockpages) {
 - + (void)VirtualUnlock(args->buffer, args->len);
 - + }
 - args->out_len = len;
 - return nfs_to_windows_error(status, ERROR_NET_WRITE_FAULT);
 - diff --git a/tests/wintartests/wintartest_seq001.bash b/tests/wintartests/wintartest_seq001.bash
 - index 489d169..ee9652b 100644
 - --- a/tests/wintartests/wintartest_seq001.bash
 - +++ b/tests/wintartests/wintartest_seq001.bash
 - @@ -11,41 +11,99 @@
 - # Written by Roland Mainz <roland.mainz@nrubsig.org>
 - #
 - -export PATH='/bin:/usr/bin'
 - +function test_wintar_seq
 - +{
 - + set -o xtrace
 - + set -o errexit
 - + set -o nounset
 - -typeset -i i
 - -typeset out
 - + # config
 - + typeset use_bzip2=$1
 - + typeset use_localdiskfortar=$2
 - -set -o xtrace
 - -set -o errexit
 - + # local vars
 - + typeset tarfile_dir
 - + typeset tarfilename
 - + typeset -i i
 - + typeset out
 - + typeset -a testfiles
 - + typeset currf
 - -# Set umask=0000 to avoid permission trouble with SMB filesystems
 - -umask 0000
 - + # seq 1040 == 4093 bytes
 - + # seq 1042 == 4103 bytes
 - + for i in 1 100 1040 5000 10000 12000 ; do
 - + rm -f -- "${i}seq.txt"
 - + seq "$i" >"${i}seq.txt"
 - + testfiles+=( "${i}seq.txt" )
 - + done
 - -rm -f '10000seq.txt'
 - -seq 100000 >'10000seq.txt' ; tar -cvf - '10000seq.txt' >'10000seq.tar' #| pbzip2 -1 >'10000seq.tar.bz2'
 - + if "${use_localdiskfortar}" ; then
 - + tarfile_dir='/tmp'
 - + else
 - + tarfile_dir="$PWD"
 - + fi
 - -rm -Rf 'tmp'
 - -mkdir 'tmp'
 - -cd 'tmp'
 - + if ${use_bzip2} ; then
 - + tarfilename="${tarfile_dir}/test_seq.tar.bz2"
 - + tar -cvf - "${testfiles[@]}" | pbzip2 -1 >"${tarfilename}"
 - + else
 - + tarfilename="${tarfile_dir}/test_seq.tar"
 - + tar -cvf - "${testfiles[@]}" >"${tarfilename}"
 - + fi
 - -set +o xtrace
 - + rm -Rf 'tmp'
 - + mkdir 'tmp'
 - + cd 'tmp'
 - -for (( i=0 ; i < 2000 ; i++ )) ; do
 - - printf '# Cycle %d:\n' "$i"
 - - /cygdrive/c/Windows/system32/tar -xvf "$(cygpath -w '../10000seq.tar')"
 - - out="$(od -x -v '10000seq.txt' | grep -F ' 0000' | head -n 5)"
 - + set +o xtrace
 - - if [[ "$out" != '' ]] ; then
 - - printf '# ERROR: Sequence of zero bytes in plain /usr/bin/seq output found:\n'
 - - printf -- '---- snip ----\n%s\n---- snip ----\n' "$out"
 - - exit 1
 - - fi
 - + for (( i=0 ; i < 2000 ; i++ )) ; do
 - + printf '#### Test cycle %d (usingbzip=%s,tarfileonlocaldisk=%s):\n' "$i" "$use_bzip2" "$use_localdiskfortar"
 - + /cygdrive/c/Windows/system32/tar -xvf "$(cygpath -w "${tarfilename}")"
 - +
 - + for currf in "${testfiles[@]}" ; do
 - + if [[ ! -r "$currf" ]] ; then
 - + printf '## ERROR: File %q not found.\n' "$currf"
 - + return 1
 - + fi
 - + if [[ ! -s "$currf" ]] ; then
 - + printf '## ERROR: File %q is empty (ls -l == "%s").\n' "$currf" "$(ls -l "$currf")"
 - + return 1
 - + fi
 - +
 - + out="$(od -A x -t x1 -v "$currf" | grep -F ' 00' | head -n 5)"
 - +
 - + if [[ "$out" != '' ]] ; then
 - + printf '## ERROR: Zero byte in plain /usr/bin/seq output %q found:\n' "$currf"
 - + printf -- '---- snip ----\n%s\n---- snip ----\n' "$out"
 - + return 1
 - + fi
 - + done
 - +
 - + rm -f -- "${testfiles[@]}"
 - + done
 - - rm -f '10000seq.txt'
 - -done
 - + printf '##### SUCCESS\n'
 - -printf '# SUCCESS\n'
 - + return 0
 - +}
 - +
 - +
 - +#
 - +# main
 - +#
 - +
 - +export PATH='/bin:/usr/bin'
 - +
 - +if [[ ! -x '/cygdrive/c/Windows/system32/tar' ]] ; then
 - + printf $"%s: %s not found.\n" \
 - + "$0" '/cygdrive/c/Windows/system32/tar' 1>&2
 - + exit 1
 - +fi
 - +
 - +# Set umask=0000 to avoid permission trouble on SMB filesystems
 - +umask 0000
 - -exit 0
 - +test_wintar_seq true true
 - +exit $?
 - # EOF.
 
Debug code to hung hunt down the native Windows tar issue
Posted by Anonymous on Fri 15th Nov 2024 17:08
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.
 nrubsig.kpaste.net RSS