Re: the second open(2) call to file in samba 2.0 cifs mountpoint hang

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Fri, Mar 23, 2018 at 11:43:03AM -0700, Pavel Shilovsky wrote:
> 2018-03-23 11:26 GMT-07:00 Pavel Shilovsky <piastryyy@xxxxxxxxx>:
> > 2018-03-22 20:34 GMT-07:00 Xiong Zhou <xzhou@xxxxxxxxxx>:
> >> On Fri, Mar 23, 2018 at 03:08:53AM +0000, Steve French wrote:
> >>> Do you mean smb2 vs smb3 dialect? Or do you mean the 10 year old samba
> >>> server
> >>
> >> I mean this:
> >> "
> >>     vers=
> >>            SMB protocol version. Allowed values are:
> >>            ·   1.0 - The classic CIFS/SMBv1 protocol. This is the default.
> >>            ·   2.0 - The SMBv2.002 protocol. This was initially introduced in Windows Vista Service Pack 1, and Windows Server 2008. Note that the
> >>                initial release version of Windows Vista spoke a slightly different dialect (2.000) that is not supported.
> >>            ·   2.1 - The SMBv2.1 protocol that was introduced in Microsoft Windows 7 and Windows Server 2008R2.
> >>            ·   3.0 - The SMBv3.0 protocol that was introduced in Microsoft Windows 8 and Windows Server 2012.
> >> "
> >>
> >> Do you mean v2 is not worth the time..
> >>
> >> Thanks,
> >> Xiong
> >>
> >>>
> >>> On Thu, Mar 22, 2018, 22:05 Xiong Zhou <xzhou@xxxxxxxxxx> wrote:
> >>>
> >>> > Hi,
> >>> >
> >>> > Process A open(2) file1 in samba 2.0 cifs mountpoint then sleep.
> >>> > Process B try to open(2) the same file1. B is blocked in open
> >>> > until A stops sleep and exit.
> >>> >
> >>> > O_NONBLOCK is not working either.
> >>> >
> >>> > This does not happen on samba 3.0.
> >>> >
> >>> > Reproduced on 4.16-rc5 Linus tree.
> >>> >
> >>> > Thanks,
> >>> > Xiong
> >>> >
> >>> > Reproducer:
> >>> >
> >>> > --------------------- start test.sh ------------------------------
> >>> > #! /bin/bash
> >>> >
> >>> > err_exit() { echo -e $1; exit 1; }
> >>> >
> >>> > setup_cifs()
> >>> > {
> >>> >         local cifs_tst_export=/export/cifstest
> >>> >         local cifs_sch_export=/export/cifsscratch
> >>> >         mkdir -p $cifs_tst_export $cifs_sch_export
> >>> >
> >>> >         \cp -f /etc/samba/smb.conf{,.bak}
> >>> >         cat > /etc/samba/smb.conf << EOF
> >>> > [test]
> >>> >     path = $cifs_tst_export
> >>> >     writeable = yes
> >>> > [scratch]
> >>> >     path = $cifs_sch_export
> >>> >     writeable = yes
> >>> > EOF
> >>> >         which systemctl && systemctl restart smb > /dev/null 2>&1
> >>> >         service stop smb > /dev/null 2>&1
> >>> >         restorecon /etc/samba/smb.conf
> >>> >         testparm -s
> >>> >         chcon -t samba_share_t $cifs_sch_export
> >>> >         chcon -t samba_share_t $cifs_tst_export
> >>> >         echo -e "redhat\nredhat" | smbpasswd -a root
> >>> >         service start smb > /dev/null 2>&1
> >>> > }
> >>> >
> >>> > preset_cifs()
> >>> > {
> >>> >         local vers=${1:-3.0}
> >>> >         echo Testing $vers
> >>> >         TEST_DEV=//localhost/test
> >>> >         SCRATCH_DEV=//localhost/scratch
> >>> >         TEST_DIR=/cifsmnt
> >>> >         SCRATCH_MNT=/cifssch
> >>> >         umount $TEST_DEV $SCRATCH_DEV $TEST_DIR $SCRATCH_MNT > /dev/null
> >>> > 2>&1
> >>> >         mkdir -p $TEST_DIR $SCRATCH_MNT
> >>> >         MOUNT_OPTIONS="-o vers=${vers},username=root,password=redhat"
> >>> >         TEST_FS_MOUNT_OPTS="-o vers=${vers},username=root,password=redhat"
> >>> >
> >>> >         mount.cifs $TEST_DEV $TEST_DIR $MOUNT_OPTIONS || err_exit "cifs
> >>> > mount $TEST_DEV failed"
> >>> >         mount.cifs $SCRATCH_DEV $SCRATCH_MNT $MOUNT_OPTIONS || err_exit
> >>> > "cifs mount $SCRATCH_DEV failed"
> >>> > }
> >>> >
> >>> > cleanup_cifs()
> >>> > {
> >>> >         umount $SCRATCH_MNT $TEST_DIR
> >>> >         \cp -f /etc/samba/smb.conf{.bak,}
> >>> >         which systemctl && systemctl restart smb
> >>> >         service stop smb > /dev/null 2>&1
> >>> >         service start smb > /dev/null 2>&1
> >>> > }
> >>> >
> >>> > do_test()
> >>> > {
> >>> >         touch $SCRATCH_MNT/testfile
> >>> >         mount | grep $SCRATCH_MNT
> >>> >         ./open_wait $SCRATCH_MNT/testfile &
> >>> >         ./open $SCRATCH_MNT/testfile
> >>> >         echo ""
> >>> >         wait
> >>> > }
> >>> >
> >>> > rpm -qv cifs-utils || yum intsall -y cifs-utils
> >>> > rpm -qv samba || yum intsall -y samba samba-client
> >>> > setup_cifs
> >>> > cc open_wait.c -o open_wait
> >>> > cc open.c -o open
> >>> > preset_cifs 3.0
> >>> > do_test
> >>> > preset_cifs 2.0
> >>> > do_test
> >>> > preset_cifs 2.1
> >>> > do_test
> >>> > preset_cifs 1.0
> >>> > do_test
> >>> > cleanup_cifs
> >>> > rm -f open_wait open a.out
> >>> > exit
> >>> > --------------------- end test.sh ------------------------------
> >>> > --------------------- start open.c  ------------------------------
> >>> > #ifndef _GNU_SOURCE
> >>> > #define _GNU_SOURCE
> >>> > #endif
> >>> > #include <unistd.h>
> >>> > #include <fcntl.h>
> >>> > #include <errno.h>
> >>> > #include <stdio.h>
> >>> > #include <unistd.h>
> >>> > #include <string.h>
> >>> > #include <stdlib.h>
> >>> > #include <sched.h>
> >>> > #include <sys/stat.h>
> >>> > #include <sys/types.h>
> >>> > #include <sys/wait.h>
> >>> > #include <sys/ipc.h>
> >>> > #include <sys/sem.h>
> >>> >
> >>> > static int fd;
> >>> >
> >>> > static void err_exit(char *op, int errn)
> >>> > {
> >>> >         fprintf(stderr, "%s: %s\n", op, strerror(errn));
> >>> >         if (fd > 0)
> >>> >                 close(fd);
> >>> >         exit(errn);
> >>> > }
> >>> >
> >>> > int main(int argc, char **argv)
> >>> > {
> >>> >         struct timeval tv1, tv2;
> >>> >         long double t1, t2;
> >>> >
> >>> >         gettimeofday(&tv1, NULL);
> >>> >         //fd = open(argv[1], O_RDWR|O_NONBLOCK);
> >>> >         fd = open(argv[1], O_RDWR);
> >>> >         gettimeofday(&tv2, NULL);
> >>> >
> >>> >         t1 = (long double)(tv1.tv_sec) + (long
> >>> > double)(tv1.tv_usec/1000000.0);
> >>> >         t2 = (long double)(tv2.tv_sec) + (long
> >>> > double)(tv2.tv_usec/1000000.0);
> >>> >         printf("open %s: %llf seconds\n", argv[1], t2 - t1);
> >>> >         err_exit("open", errno);
> >>> > }
> >>> > --------------------- end open.c  ------------------------------
> >>> > --------------------- start open_wait.c  ------------------------------
> >>> > #ifndef _GNU_SOURCE
> >>> > #define _GNU_SOURCE
> >>> > #endif
> >>> > #include <errno.h>
> >>> > #include <stdio.h>
> >>> > #include <stdlib.h>
> >>> > #include <unistd.h>
> >>> > #include <sys/types.h>
> >>> > #include <sys/stat.h>
> >>> > #include <fcntl.h>
> >>> >
> >>> > static int fd;
> >>> >
> >>> > static void err_exit(char *op, int errn)
> >>> > {
> >>> >         fprintf(stderr, "%s: %s\n", op, strerror(errn));
> >>> >         if (fd > 0)
> >>> >                 close(fd);
> >>> >         exit(errn);
> >>> > }
> >>> >
> >>> > int main(int argc, char **argv)
> >>> > {
> >>> >         fd = open(argv[1], O_RDWR);
> >>> >         if (fd == -1)
> >>> >                 err_exit("open", errno);
> >>> >
> >>> >         sleep(2);
> >>> >         close(fd);
> >>> >         return 0;
> >>> > }
> >>> > --------------------- end open_wait.c  ------------------------------
> >
> > I suspect there might be a problem with handling SMB 2.0 oplock break
> > by the client. Adding Ronnie and Long to take a look since they
> > changed the request handling code recently.
> >
> 
> Xiong,
> 
> In the meantime could you provide a kernel debug output during the
> execution of your test program as described in
> https://wiki.samba.org/index.php/LinuxCIFS_troubleshooting ?

samba version:

cifs-utils-6.2-10.el7.x86_64
samba-4.7.1-7.el7.x86_64

Kernel info: 4.16.0-rc6+  latest commit: 99fec39

Mount info:
//localhost/scratch on /cifssch type cifs (rw,relatime,vers=2.0,cache=strict,username=root,domain=,uid=0,noforceuid,gid=0,noforcegid,addr=0000:0000:0000:0000:0000:0000:0000:0001,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,rsize=65536,wsize=65536,echo_interval=60,actimeo=1)

Reproduced test output:
#The second open wait for 2 seconds.
open /cifssch/testfile: 2.001102 seconds
open: Success

debug output:

[  199.989602] Key type dns_resolver registered
[  200.450304] Key type cifs.spnego registered
[  200.469343] Key type cifs.idmap registered
[  200.677975] Status code returned 0xc0000016 STATUS_MORE_PROCESSING_REQUIRED
[  200.875950] Status code returned 0xc0000225 STATUS_NOT_FOUND
[  200.903850] Status code returned 0xc0000225 STATUS_NOT_FOUND

Thanks,
Xiong

updated test.sh:

#! /bin/bash

err_exit() { echo -e $1; exit 1; }

setup_cifs()
{
	local cifs_tst_export=/export/cifstest
	local cifs_sch_export=/export/cifsscratch
	mkdir -p $cifs_tst_export $cifs_sch_export

	\cp -f /etc/samba/smb.conf{,.bak}
	cat > /etc/samba/smb.conf << EOF
[test]
    path = $cifs_tst_export
    writeable = yes
[scratch]
    path = $cifs_sch_export
    writeable = yes
EOF
	which systemctl && systemctl restart smb > /dev/null 2>&1
	service stop smb > /dev/null 2>&1
	restorecon /etc/samba/smb.conf
	testparm -s
	chcon -t samba_share_t $cifs_sch_export
	chcon -t samba_share_t $cifs_tst_export
	echo -e "redhat\nredhat" | smbpasswd -a root
	service start smb > /dev/null 2>&1
}

preset_cifs()
{
	local vers=${1:-3.0}
	echo Testing $vers
	TEST_DEV=//localhost/test
	SCRATCH_DEV=//localhost/scratch
	TEST_DIR=/cifsmnt
	SCRATCH_MNT=/cifssch
	umount $TEST_DEV $SCRATCH_DEV $TEST_DIR $SCRATCH_MNT > /dev/null 2>&1
	mkdir -p $TEST_DIR $SCRATCH_MNT
	MOUNT_OPTIONS="-o vers=${vers},username=root,password=redhat"
	TEST_FS_MOUNT_OPTS="-o vers=${vers},username=root,password=redhat"

	mount.cifs $TEST_DEV $TEST_DIR $MOUNT_OPTIONS || err_exit "cifs mount $TEST_DEV failed"
	mount.cifs $SCRATCH_DEV $SCRATCH_MNT $MOUNT_OPTIONS || err_exit "cifs mount $SCRATCH_DEV failed"
}

cleanup_cifs()
{
	umount $SCRATCH_MNT $TEST_DIR
	\cp -f /etc/samba/smb.conf{.bak,}
	which systemctl && systemctl restart smb
	service stop smb > /dev/null 2>&1
	service start smb > /dev/null 2>&1
}

do_test()
{
	touch $SCRATCH_MNT/testfile
	mount | grep $SCRATCH_MNT
	./open_wait $SCRATCH_MNT/testfile &
	./open $SCRATCH_MNT/testfile
	echo ""
	wait
	echo 0 > /proc/fs/cifs/cifsFYI
	dmesg
}

rpm -qv cifs-utils || yum intsall -y cifs-utils
rpm -qv samba || yum intsall -y samba samba-client
uname -r
setup_cifs
cc open_wait.c -o open_wait
cc open.c -o open
#preset_cifs 3.0
#do_test
	dmesg -C
	modprobe cifs
	echo 7 > /proc/fs/cifs/cifsFYI
preset_cifs 2.0
do_test
#preset_cifs 2.1
#do_test
#preset_cifs 1.0
#do_test
cleanup_cifs
rm -f open_wait open a.out
exit
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux