Bug 1269 - linux kernel oplock break signal is not deliver to smbd after timeout_processing() call.
linux kernel oplock break signal is not deliver to smbd after timeout_process...
Status: RESOLVED FIXED
Product: Samba 3.0
Classification: Unclassified
Component: File Services
3.0.2a
All Linux
: P3 normal
: none
Assigned To: Samba Bugzilla Account
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2004-04-16 06:30 UTC by YAMASAKI Hiroyuki
Modified: 2007-04-10 13:56 UTC (History)
1 user (show)

See Also:


Attachments
smbd debug log (13.75 KB, application/x-gzip)
2007-04-10 04:05 UTC, Kevin Jamieson
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description YAMASAKI Hiroyuki 2004-04-16 06:30:30 UTC
Sorry for my poor english.

On Linux 2.4.x system(I test 2.4.17 and 2.4.20), smbd which is compiled with 
HAVE_KERNEL_OPLOCKS_LINUX sometime can't catch oplock break signal from linux 
kernel.

I cut-and-try various test and make sure reproduce condition.
To reprodule problem, do below procedure.
 1) Windows Client open server's file via smbd ,and oplock granted.
 2) Keep 1) handle open pass the time until call timeout_processing().
    Probabry the time is  60seconds. 
   (local.h -  #define SMBD_SELECT_TIMEOUT (60) )
 3) When the time pass, do "cat <opened-file>".
    "cat" can't open the file instantly,and waiting. 
@@And smbd don't catch oplock break signal from kernel, so smbd don't send 
oplock break LockingX request to Windows client.
 
 4) After 45seconds(/proc/sys/fs/lease-break-time), "cat" open the file.
    But ofcource smbd and Windows client oplock break. 
    It's bad file sharing status.

I search what is ill when timeout_processing(). 
And I found calling change_to_root_user() in timeout_processing() cause smbd to 
lose ability to catch oplock break signal from kernel.

Then, I search workaround by various cut-and-try,and I found.
In smbd/oplock_linux.c/linux_setlease(), do become_root() and unbecome_root() 
as below. I don't know this way is correct or incorrect.But do this, problem is 
not reproduce.
---------------------------------------------------------
static int linux_setlease(int fd, int leasetype)
{
	int ret;

         become_root() /******** ADD ************/
	if (fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {
		DEBUG(3,("Failed to set signal handler for kernel lease\n"));
         @@@@@unbecome_root() /************ ADD ************/
		return -1;
	}

	ret = fcntl(fd, F_SETLEASE, leasetype);
	if (ret == -1 && errno == EACCES) {
		set_capability(CAP_LEASE);
		ret = fcntl(fd, F_SETLEASE, leasetype);
	}
@@@@@unbecome_root() /************** ADD **************/
	return ret;
}
---------------------------------------------------------
 
I don't understand linux kernel. But I guess below checking code impact to this 
problem.

--linux/fs/fcntl.c----------------------------------------------------
static void send_sigio_to_task(struct task_struct *p,
			       struct fown_struct *fown, 
			       int fd,
			       int reason)
{
	if ((fown->euid != 0) &&
	    (fown->euid ^ p->suid) && (fown->euid ^ p->uid) &&
	    (fown->uid ^ p->suid) && (fown->uid ^ p->uid))
		return;
<snip>
---------------------------------------------------------

And I think that call become_root() when F_SETLEASE avoid above checking code 
(fown->euid != 0),because below code.

---------------------------------------------------------
int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
{
 <snip>
	list_add(&fl->fl_link, &file_lock_list);
	filp->f_owner.pid = current->pid;
	filp->f_owner.uid = current->uid;
	filp->f_owner.euid = current->euid;   /******** THIS *********/
out_unlock:
	unlock_kernel();
	return error;
}
---------------------------------------------------------
Comment 1 Gerald (Jerry) Carter 2005-11-14 09:27:18 UTC
database cleanup
Comment 2 Gerald (Jerry) Carter 2006-04-08 11:47:22 UTC
please reopen if the bug still exists in a current release.
Comment 3 Kevin Jamieson 2007-04-10 04:05:14 UTC
Created attachment 2363 [details]
smbd debug log

This problem appears to still exist in Samba 3.0.24. After timeout_processing() has changed the euid, the kernel does not send the break signal to the smbd process and the lease is not broken until the kernel forcibily breaks it after /proc/sys/fs/lease-break-time seconds.

root@kjamieson64:~# dpkg -l samba
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name                            Version                         Description
+++-===============================-===============================-==============================================================================
ii  samba                           3.0.24-6                        a LanManager-like file and printer server for Unix
root@kjamieson64:~# uname -a
Linux kjamieson64 2.6.20.070303-sgi #1 PREEMPT Sat Mar 3 13:55:21 PST 2007 x86_64 GNU/Linux
root@kjamieson64:~# mount -t cifs -o username=smbuser,password=smbuser //192.168.110.200/share /mnt/share
root@kjamieson64:~# echo hello > /mnt/share/file1
root@kjamieson64:~# cat >> /mnt/share/file1 & sleep 55 && time cat /share/file1
[1] 16978

[1]+  Stopped                 cat >>/mnt/share/file1
hello

real    0m0.002s
user    0m0.000s
sys     0m0.001s
root@kjamieson64:~# smbstatus --locks
Locked files:
Pid          Uid        DenyMode   Access      R/W        Oplock           SharePath   Name   Time
--------------------------------------------------------------------------------------------------
16974        2145       DENY_NONE  0x120116    WRONLY     NONE             /share   file1   Tue Apr 10 01:24:38 2007

root@kjamieson64:~# kill %1
root@kjamieson64:~# cat >> /mnt/share/file1 & sleep 65 && time cat /share/file1
[2] 16994
[1]   Terminated              cat >>/mnt/share/file1

[2]+  Stopped                 cat >>/mnt/share/file1
hello

real    0m44.995s
user    0m0.000s
sys     0m0.001s
root@kjamieson64:~# smbstatus --locks
Locked files:
Pid          Uid        DenyMode   Access      R/W        Oplock           SharePath   Name   Time
--------------------------------------------------------------------------------------------------
16974        2145       DENY_NONE  0x120116    WRONLY     EXCLUSIVE        /share   file1   Tue Apr 10 01:25:52 2007