2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL
;
26 /* Oplock ipc UDP socket. */
27 static int oplock_sock
= -1;
28 uint16 global_oplock_port
= 0;
29 #if defined(HAVE_KERNEL_OPLOCKS)
30 static int oplock_pipe_read
= -1;
31 static int oplock_pipe_write
= -1;
32 #endif /* HAVE_KERNEL_OPLOCKS */
34 /* Current number of oplocks we have outstanding. */
35 int32 global_oplocks_open
= 0;
36 BOOL global_oplock_break
= False
;
38 extern int smb_read_error
;
40 static BOOL
oplock_break(SMB_DEV_T dev
, SMB_INO_T inode
, struct timeval
*tval
);
42 /****************************************************************************
43 open the oplock IPC socket communication
44 ****************************************************************************/
45 BOOL
open_oplock_ipc(void)
47 struct sockaddr_in sock_name
;
48 int len
= sizeof(sock_name
);
50 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
52 /* Open a lookback UDP socket on a random port. */
53 oplock_sock
= open_socket_in(SOCK_DGRAM
, 0, 0, htonl(INADDR_LOOPBACK
));
54 if (oplock_sock
== -1)
56 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
57 address %x. Error was %s\n", htonl(INADDR_LOOPBACK
), strerror(errno
)));
58 global_oplock_port
= 0;
62 /* Find out the transient UDP port we have been allocated. */
63 if(getsockname(oplock_sock
, (struct sockaddr
*)&sock_name
, &len
)<0)
65 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
69 global_oplock_port
= 0;
72 global_oplock_port
= ntohs(sock_name
.sin_port
);
74 DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
75 (int)getpid(), global_oplock_port
));
80 /****************************************************************************
81 Read an oplock break message from the either the oplock UDP fd
82 or the kernel oplock pipe fd (if kernel oplocks are supported).
84 If timeout is zero then *fds contains the file descriptors that
85 are ready to be read and acted upon. If timeout is non-zero then
86 *fds contains the file descriptors to be selected on for read.
87 The timeout is in milliseconds
89 ****************************************************************************/
91 BOOL
receive_local_message(fd_set
*fds
, char *buffer
, int buffer_len
, int timeout
)
93 struct sockaddr_in from
;
94 int fromlen
= sizeof(from
);
102 int maxfd
= oplock_sock
;
104 #if defined(HAVE_KERNEL_OPLOCKS)
105 if(lp_kernel_oplocks())
106 maxfd
= MAX(maxfd
, oplock_pipe_read
);
107 #endif /* HAVE_KERNEL_OPLOCKS */
109 to
.tv_sec
= timeout
/ 1000;
110 to
.tv_usec
= (timeout
% 1000) * 1000;
112 selrtn
= sys_select(maxfd
+1,fds
,&to
);
116 /* something is wrong. Maybe the socket is dead? */
117 smb_read_error
= READ_ERROR
;
121 /* Did we timeout ? */
123 smb_read_error
= READ_TIMEOUT
;
128 #if defined(HAVE_KERNEL_OPLOCKS)
129 if(FD_ISSET(oplock_pipe_read
,fds
)) {
131 * Deal with the kernel <--> smbd
132 * oplock break protocol.
141 * Read one byte of zero to clear the
142 * kernel break notify message.
145 if(read(oplock_pipe_read
, &dummy
, 1) != 1) {
146 DEBUG(0,("receive_local_message: read of kernel notification failed. \
147 Error was %s.\n", strerror(errno
) ));
148 smb_read_error
= READ_ERROR
;
153 * Do a query to get the
154 * device and inode of the file that has the break
155 * request outstanding.
158 if(fcntl(oplock_pipe_read
, F_OPLKSTAT
, &os
) < 0) {
159 DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
160 Error was %s.\n", strerror(errno
) ));
161 smb_read_error
= READ_ERROR
;
165 dev
= (SMB_DEV_T
)os
.os_dev
;
166 inode
= (SMB_DEV_T
)os
.os_ino
;
168 DEBUG(5,("receive_local_message: kernel oplock break request received for \
169 dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
));
172 * Create a kernel oplock break message.
175 /* Setup the message header */
176 SIVAL(buffer
,OPBRK_CMD_LEN_OFFSET
,KERNEL_OPLOCK_BREAK_MSG_LEN
);
177 SSVAL(buffer
,OPBRK_CMD_PORT_OFFSET
,0);
179 buffer
+= OPBRK_CMD_HEADER_LEN
;
181 SSVAL(buffer
,OPBRK_MESSAGE_CMD_OFFSET
,KERNEL_OPLOCK_BREAK_CMD
);
182 SIVAL(buffer
,KERNEL_OPLOCK_BREAK_DEV_OFFSET
,dev
);
184 #ifdef LARGE_SMB_INO_T
185 SIVAL(buffer
,KERNEL_OPLOCK_BREAK_INODE_OFFSET
,inode
& 0xFFFFFFFF);
186 SIVAL(buffer
,KERNEL_OPLOCK_BREAK_INODE_OFFSET
+4, (inode
>> 32 ) & 0xFFFFFFFF );
187 #else /* LARGE_SMB_INO_T */
188 SIVAL(buffer
,KERNEL_OPLOCK_BREAK_INODE_OFFSET
,inode
);
189 #endif /* LARGE_SMB_INO_T */
193 #endif /* HAVE_KERNEL_OPLOCKS */
196 * From here down we deal with the smbd <--> smbd
197 * oplock break protocol only.
201 * Read a loopback udp message.
203 msg_len
= recvfrom(oplock_sock
, &buffer
[OPBRK_CMD_HEADER_LEN
],
204 buffer_len
- OPBRK_CMD_HEADER_LEN
, 0,
205 (struct sockaddr
*)&from
, &fromlen
);
208 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno
)));
212 /* Validate message length. */
213 if(msg_len
> (buffer_len
- OPBRK_CMD_HEADER_LEN
)) {
214 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
216 buffer_len
- OPBRK_CMD_HEADER_LEN
));
220 /* Validate message from address (must be localhost). */
221 if(from
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) {
222 DEBUG(0,("receive_local_message: invalid 'from' address \
223 (was %x should be 127.0.0.1\n", from
.sin_addr
.s_addr
));
227 /* Setup the message header */
228 SIVAL(buffer
,OPBRK_CMD_LEN_OFFSET
,msg_len
);
229 SSVAL(buffer
,OPBRK_CMD_PORT_OFFSET
,ntohs(from
.sin_port
));
234 /****************************************************************************
235 Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
236 disabled (just sets flags). Returns True if oplock set.
237 ****************************************************************************/
239 BOOL
set_file_oplock(files_struct
*fsp
)
241 #if defined(HAVE_KERNEL_OPLOCKS)
242 if(lp_kernel_oplocks()) {
244 if(fcntl(fsp
->fd_ptr
->fd
, F_OPLKREG
, oplock_pipe_write
) < 0 ) {
245 if(errno
!= EAGAIN
) {
246 DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
247 inode = %.0f. Error was %s\n",
248 fsp
->fsp_name
, (unsigned int)fsp
->fd_ptr
->dev
, (double)fsp
->fd_ptr
->inode
,
251 DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
252 inode = %.0f. Another process had the file open.\n",
253 fsp
->fsp_name
, fsp
->fd_ptr
->fd
, (unsigned int)fsp
->fd_ptr
->dev
, (double)fsp
->fd_ptr
->inode
));
258 DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
259 fsp
->fsp_name
, (unsigned int)fsp
->fd_ptr
->dev
, (double)fsp
->fd_ptr
->inode
));
262 #endif /* HAVE_KERNEL_OPLOCKS */
264 DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f\n",
265 fsp
->fsp_name
, (unsigned int)fsp
->fd_ptr
->dev
, (double)fsp
->fd_ptr
->inode
));
267 fsp
->granted_oplock
= True
;
268 fsp
->sent_oplock_break
= False
;
269 global_oplocks_open
++;
274 /****************************************************************************
275 Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
276 disabled (just clears flags).
277 ****************************************************************************/
279 static void release_file_oplock(files_struct
*fsp
)
281 #if defined(HAVE_KERNEL_OPLOCKS)
283 if(lp_kernel_oplocks())
288 * Check and print out the current kernel
289 * oplock state of this file.
291 int state
= fcntl(fsp
->fd_ptr
->fd
, F_OPLKACK
, -1);
292 dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
293 oplock state of %x.\n", fsp
->fsp_name
, (unsigned int)fsp
->fd_ptr
->dev
,
294 (double)fsp
->fd_ptr
->inode
, state
);
298 * Remote the kernel oplock on this file.
301 if(fcntl(fsp
->fd_ptr
->fd
, F_OPLKACK
, OP_REVOKE
) < 0)
305 dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
306 dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
307 fsp
->fsp_name
, (unsigned int)fsp
->fd_ptr
->dev
,
308 (double)fsp
->fd_ptr
->inode
, strerror(errno
) );
312 #endif /* HAVE_KERNEL_OPLOCKS */
314 fsp
->granted_oplock
= False
;
315 fsp
->sent_oplock_break
= False
;
316 global_oplocks_open
--;
319 /****************************************************************************
320 Setup the listening set of file descriptors for an oplock break
321 message either from the UDP socket or from the kernel. Returns the maximum
323 ****************************************************************************/
325 int setup_oplock_select_set( fd_set
*fds
)
327 int maxfd
= oplock_sock
;
328 FD_SET(oplock_sock
,fds
);
330 #if defined(HAVE_KERNEL_OPLOCKS)
331 if(lp_kernel_oplocks()) {
332 FD_SET(oplock_pipe_read
,fds
);
333 maxfd
= MAX(maxfd
,oplock_pipe_read
);
335 #endif /* HAVE_KERNEL_OPLOCKS */
340 /****************************************************************************
341 Process an oplock break message - whether it came from the UDP socket
343 ****************************************************************************/
345 BOOL
process_local_message(char *buffer
, int buf_size
)
354 struct timeval
*ptval
= NULL
;
356 msg_len
= IVAL(buffer
,OPBRK_CMD_LEN_OFFSET
);
357 from_port
= SVAL(buffer
,OPBRK_CMD_PORT_OFFSET
);
359 msg_start
= &buffer
[OPBRK_CMD_HEADER_LEN
];
361 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
362 msg_len
, from_port
));
365 * Pull the info out of the requesting packet.
368 switch(SVAL(msg_start
,OPBRK_MESSAGE_CMD_OFFSET
))
370 #if defined(HAVE_KERNEL_OPLOCKS)
371 case KERNEL_OPLOCK_BREAK_CMD
:
372 /* Ensure that the msg length is correct. */
373 if(msg_len
!= KERNEL_OPLOCK_BREAK_MSG_LEN
)
375 DEBUG(0,("process_local_message: incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, \
376 should be %d).\n", msg_len
, KERNEL_OPLOCK_BREAK_MSG_LEN
));
381 * Warning - beware of SMB_INO_T <> 4 bytes. !!
383 #ifdef LARGE_SMB_INO_T
384 SMB_INO_T inode_low
= IVAL(msg_start
, KERNEL_OPLOCK_BREAK_INODE_OFFSET
);
385 SMB_INO_T inode_high
= IVAL(msg_start
, KERNEL_OPLOCK_BREAK_INODE_OFFSET
+ 4);
386 inode
= inode_low
| (inode_high
<< 32);
387 #else /* LARGE_SMB_INO_T */
388 inode
= IVAL(msg_start
, KERNEL_OPLOCK_BREAK_INODE_OFFSET
);
389 #endif /* LARGE_SMB_INO_T */
391 dev
= IVAL(msg_start
,KERNEL_OPLOCK_BREAK_DEV_OFFSET
);
395 DEBUG(5,("process_local_message: kernel oplock break request for \
396 file dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
));
399 #endif /* HAVE_KERNEL_OPLOCKS */
401 case OPLOCK_BREAK_CMD
:
402 /* Ensure that the msg length is correct. */
403 if(msg_len
!= OPLOCK_BREAK_MSG_LEN
)
405 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
406 should be %d).\n", msg_len
, OPLOCK_BREAK_MSG_LEN
));
411 * Warning - beware of SMB_INO_T <> 4 bytes. !!
413 #ifdef LARGE_SMB_INO_T
414 SMB_INO_T inode_low
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
415 SMB_INO_T inode_high
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
+ 4);
416 inode
= inode_low
| (inode_high
<< 32);
417 #else /* LARGE_SMB_INO_T */
418 inode
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
419 #endif /* LARGE_SMB_INO_T */
421 dev
= IVAL(msg_start
,OPLOCK_BREAK_DEV_OFFSET
);
423 tval
.tv_sec
= (time_t)IVAL(msg_start
, OPLOCK_BREAK_SEC_OFFSET
);
424 tval
.tv_usec
= (long)IVAL(msg_start
, OPLOCK_BREAK_USEC_OFFSET
);
428 remotepid
= IVAL(msg_start
,OPLOCK_BREAK_PID_OFFSET
);
430 DEBUG(5,("process_local_message: oplock break request from \
431 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid
, from_port
, (unsigned int)dev
, (double)inode
));
436 * Keep this as a debug case - eventually we can remove it.
439 DEBUG(0,("process_local_message: Received unsolicited break \
440 reply - dumping info.\n"));
442 if(msg_len
!= OPLOCK_BREAK_MSG_LEN
)
444 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
445 (was %d, should be %d).\n", msg_len
, OPLOCK_BREAK_MSG_LEN
));
451 * Warning - beware of SMB_INO_T <> 4 bytes. !!
453 #ifdef LARGE_SMB_INO_T
454 SMB_INO_T inode_low
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
455 SMB_INO_T inode_high
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
+ 4);
456 inode
= inode_low
| (inode_high
<< 32);
457 #else /* LARGE_SMB_INO_T */
458 inode
= IVAL(msg_start
, OPLOCK_BREAK_INODE_OFFSET
);
459 #endif /* LARGE_SMB_INO_T */
461 remotepid
= IVAL(msg_start
,OPLOCK_BREAK_PID_OFFSET
);
462 dev
= IVAL(msg_start
,OPLOCK_BREAK_DEV_OFFSET
);
464 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
465 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid
, from_port
, (unsigned int)dev
, (double)inode
));
471 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
472 (unsigned int)SVAL(msg_start
,0)));
477 * Now actually process the break request.
480 if(global_oplocks_open
!= 0)
482 if(oplock_break(dev
, inode
, ptval
) == False
)
484 DEBUG(0,("process_local_message: oplock break failed.\n"));
491 * If we have no record of any currently open oplocks,
492 * it's not an error, as a close command may have
493 * just been issued on the file that was oplocked.
494 * Just log a message and return success in this case.
496 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
497 oplocks. Returning success.\n"));
501 * Do the appropriate reply - none in the kernel case.
504 if(SVAL(msg_start
,OPBRK_MESSAGE_CMD_OFFSET
) == OPLOCK_BREAK_CMD
)
506 struct sockaddr_in toaddr
;
508 /* Send the message back after OR'ing in the 'REPLY' bit. */
509 SSVAL(msg_start
,OPBRK_MESSAGE_CMD_OFFSET
,OPLOCK_BREAK_CMD
| CMD_REPLY
);
511 bzero((char *)&toaddr
,sizeof(toaddr
));
512 toaddr
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
513 toaddr
.sin_port
= htons(from_port
);
514 toaddr
.sin_family
= AF_INET
;
516 if(sendto( oplock_sock
, msg_start
, OPLOCK_BREAK_MSG_LEN
, 0,
517 (struct sockaddr
*)&toaddr
, sizeof(toaddr
)) < 0)
519 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
520 remotepid
, strerror(errno
)));
524 DEBUG(5,("process_local_message: oplock break reply sent to \
525 pid %d, port %d, for file dev = %x, inode = %.0f\n",
526 remotepid
, from_port
, (unsigned int)dev
, (double)inode
));
532 /****************************************************************************
533 Process an oplock break directly.
534 ****************************************************************************/
536 static BOOL
oplock_break(SMB_DEV_T dev
, SMB_INO_T inode
, struct timeval
*tval
)
538 extern struct current_user current_user
;
542 files_struct
*fsp
= NULL
;
544 BOOL shutdown_server
= False
;
545 connection_struct
*saved_conn
;
551 dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev
, (double)inode
);
552 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open
);
555 /* We need to search the file open table for the
556 entry containing this dev and inode, and ensure
557 we have an oplock on it. */
558 fsp
= file_find_dit(dev
, inode
, tval
);
562 /* The file could have been closed in the meantime - return success. */
565 dbgtext( "oplock_break: cannot find open file with " );
566 dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev
, (double)inode
);
567 dbgtext( "allowing break to succeed.\n" );
572 /* Ensure we have an oplock on the file */
574 /* There is a potential race condition in that an oplock could
575 have been broken due to another udp request, and yet there are
576 still oplock break messages being sent in the udp message
577 queue for this file. So return true if we don't have an oplock,
578 as we may have just freed it.
581 if(!fsp
->granted_oplock
)
585 dbgtext( "oplock_break: file %s ", fsp
->fsp_name
);
586 dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev
, (double)inode
);
587 dbgtext( "Allowing break to succeed regardless.\n" );
592 /* mark the oplock break as sent - we don't want to send twice! */
593 if (fsp
->sent_oplock_break
)
597 dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
598 dbgtext( "file %s ", fsp
->fsp_name
);
599 dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev
, (double)inode
);
602 /* We have to fail the open here as we cannot send another oplock break on
603 this file whilst we are awaiting a response from the client - neither
604 can we allow another open to succeed while we are waiting for the
610 /* Now comes the horrid part. We must send an oplock break to the client,
611 and then process incoming messages until we get a close or oplock release.
612 At this point we know we need a new inbuf/outbuf buffer pair.
613 We cannot use these staticaly as we may recurse into here due to
614 messages crossing on the wire.
617 if((inbuf
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
))==NULL
)
619 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
623 if((outbuf
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
))==NULL
)
625 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
631 /* Prepare the SMBlockingX message. */
632 bzero(outbuf
,smb_size
);
633 set_message(outbuf
,8,0,True
);
635 SCVAL(outbuf
,smb_com
,SMBlockingX
);
636 SSVAL(outbuf
,smb_tid
,fsp
->conn
->cnum
);
637 SSVAL(outbuf
,smb_pid
,0xFFFF);
638 SSVAL(outbuf
,smb_uid
,0);
639 SSVAL(outbuf
,smb_mid
,0xFFFF);
640 SCVAL(outbuf
,smb_vwv0
,0xFF);
641 SSVAL(outbuf
,smb_vwv2
,fsp
->fnum
);
642 SCVAL(outbuf
,smb_vwv3
,LOCKING_ANDX_OPLOCK_RELEASE
);
643 /* Change this when we have level II oplocks. */
644 SCVAL(outbuf
,smb_vwv3
+1,OPLOCKLEVEL_NONE
);
646 send_smb(Client
, outbuf
);
648 /* Remember we just sent an oplock break on this file. */
649 fsp
->sent_oplock_break
= True
;
651 /* We need this in case a readraw crosses on the wire. */
652 global_oplock_break
= True
;
654 /* Process incoming messages. */
656 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
657 seconds we should just die.... */
659 start_time
= time(NULL
);
662 * Save the information we need to re-become the
663 * user, then unbecome the user whilst we're doing this.
665 saved_conn
= fsp
->conn
;
666 saved_vuid
= current_user
.vuid
;
669 /* Save the chain fnum. */
672 while(OPEN_FSP(fsp
) && fsp
->granted_oplock
)
674 if(receive_smb(Client
,inbuf
,OPLOCK_BREAK_TIMEOUT
* 1000) == False
)
677 * Die if we got an error.
680 if (smb_read_error
== READ_EOF
)
681 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
683 if (smb_read_error
== READ_ERROR
)
684 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno
)) );
686 if (smb_read_error
== READ_TIMEOUT
)
687 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
688 OPLOCK_BREAK_TIMEOUT
) );
690 DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp
->fsp_name
) );
691 DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev
, (double)inode
));
693 shutdown_server
= True
;
698 * There are certain SMB requests that we shouldn't allow
699 * to recurse. opens, renames and deletes are the obvious
700 * ones. This is handled in the switch_message() function.
701 * If global_oplock_break is set they will push the packet onto
702 * the pending smb queue and return -1 (no reply).
706 process_smb(inbuf
, outbuf
);
709 * Die if we go over the time limit.
712 if((time(NULL
) - start_time
) > OPLOCK_BREAK_TIMEOUT
)
716 dbgtext( "oplock_break: no break received from client " );
717 dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT
);
718 dbgtext( "oplock_break failed for file %s ", fsp
->fsp_name
);
719 dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev
, (double)inode
);
721 shutdown_server
= True
;
727 * Go back to being the user who requested the oplock
730 if(!become_user(saved_conn
, saved_vuid
))
732 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
733 DEBUGADD( 0, ( "Shutting down server\n" ) );
736 exit_server("unable to re-become user");
738 /* Including the directory. */
741 /* Restore the chain fnum. */
742 file_chain_restore();
744 /* Free the buffers we've been using to recurse. */
748 /* We need this in case a readraw crossed on the wire. */
749 if(global_oplock_break
)
750 global_oplock_break
= False
;
753 * If the client did not respond we must die.
758 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
759 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
762 exit_server("oplock break failure");
767 /* The lockingX reply will have removed the oplock flag
768 from the sharemode. */
769 release_file_oplock(fsp
);
772 /* Santity check - remove this later. JRA */
773 if(global_oplocks_open
< 0)
775 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
776 global_oplocks_open
));
777 exit_server("oplock_break: global_oplocks_open < 0");
783 dbgtext( "oplock_break: returning success for " );
784 dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
);
785 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open
);
791 /****************************************************************************
792 Send an oplock break message to another smbd process. If the oplock is held
793 by the local smbd then call the oplock break function directly.
794 ****************************************************************************/
796 BOOL
request_oplock_break(share_mode_entry
*share_entry
,
797 SMB_DEV_T dev
, SMB_INO_T inode
)
799 char op_break_msg
[OPLOCK_BREAK_MSG_LEN
];
800 struct sockaddr_in addr_out
;
805 if(pid
== share_entry
->pid
)
807 /* We are breaking our own oplock, make sure it's us. */
808 if(share_entry
->op_port
!= global_oplock_port
)
810 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
811 should be %d\n", pid
, share_entry
->op_port
, global_oplock_port
));
815 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
817 /* Call oplock break direct. */
818 return oplock_break(dev
, inode
, &share_entry
->time
);
821 /* We need to send a OPLOCK_BREAK_CMD message to the
822 port in the share mode entry. */
824 SSVAL(op_break_msg
,OPBRK_MESSAGE_CMD_OFFSET
,OPLOCK_BREAK_CMD
);
825 SIVAL(op_break_msg
,OPLOCK_BREAK_PID_OFFSET
,pid
);
826 SIVAL(op_break_msg
,OPLOCK_BREAK_SEC_OFFSET
,(uint32
)share_entry
->time
.tv_sec
);
827 SIVAL(op_break_msg
,OPLOCK_BREAK_USEC_OFFSET
,(uint32
)share_entry
->time
.tv_usec
);
828 SIVAL(op_break_msg
,OPLOCK_BREAK_DEV_OFFSET
,dev
);
830 * WARNING - beware of SMB_INO_T <> 4 bytes.
832 #ifdef LARGE_SMB_INO_T
833 SIVAL(op_break_msg
,OPLOCK_BREAK_INODE_OFFSET
,(inode
& 0xFFFFFFFFL
));
834 SIVAL(op_break_msg
,OPLOCK_BREAK_INODE_OFFSET
+4,((inode
>> 32) & 0xFFFFFFFFL
));
835 #else /* LARGE_SMB_INO_T */
836 SIVAL(op_break_msg
,OPLOCK_BREAK_INODE_OFFSET
,inode
);
837 #endif /* LARGE_SMB_INO_T */
839 /* set the address and port */
840 bzero((char *)&addr_out
,sizeof(addr_out
));
841 addr_out
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
842 addr_out
.sin_port
= htons( share_entry
->op_port
);
843 addr_out
.sin_family
= AF_INET
;
847 dbgtext( "request_oplock_break: sending a oplock break message to " );
848 dbgtext( "pid %d on port %d ", share_entry
->pid
, share_entry
->op_port
);
849 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
);
852 if(sendto(oplock_sock
,op_break_msg
,OPLOCK_BREAK_MSG_LEN
,0,
853 (struct sockaddr
*)&addr_out
,sizeof(addr_out
)) < 0)
857 dbgtext( "request_oplock_break: failed when sending a oplock " );
858 dbgtext( "break message to pid %d ", share_entry
->pid
);
859 dbgtext( "on port %d ", share_entry
->op_port
);
860 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
);
861 dbgtext( "Error was %s\n", strerror(errno
) );
867 * Now we must await the oplock broken message coming back
868 * from the target smbd process. Timeout if it fails to
869 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
870 * While we get messages that aren't ours, loop.
873 start_time
= time(NULL
);
874 time_left
= OPLOCK_BREAK_TIMEOUT
+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR
;
876 while(time_left
>= 0)
878 char op_break_reply
[OPBRK_CMD_HEADER_LEN
+OPLOCK_BREAK_MSG_LEN
];
880 uint16 reply_from_port
;
881 char *reply_msg_start
;
885 FD_SET(oplock_sock
,&fds
);
886 #if defined(HAVE_KERNEL_OPLOCKS)
887 if(lp_kernel_oplocks())
888 FD_SET(oplock_pipe_read
,&fds
);
889 #endif /* HAVE_KERNEL_OPLOCKS */
891 if(receive_local_message(&fds
, op_break_reply
, sizeof(op_break_reply
),
892 time_left
? time_left
* 1000 : 1) == False
)
894 if(smb_read_error
== READ_TIMEOUT
)
898 dbgtext( "request_oplock_break: no response received to oplock " );
899 dbgtext( "break request to pid %d ", share_entry
->pid
);
900 dbgtext( "on port %d ", share_entry
->op_port
);
901 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
);
905 * This is a hack to make handling of failing clients more robust.
906 * If a oplock break response message is not received in the timeout
907 * period we may assume that the smbd servicing that client holding
908 * the oplock has died and the client changes were lost anyway, so
909 * we should continue to try and open the file.
916 dbgtext( "request_oplock_break: error in response received " );
917 dbgtext( "to oplock break request to pid %d ", share_entry
->pid
);
918 dbgtext( "on port %d ", share_entry
->op_port
);
919 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
);
920 dbgtext( "Error was (%s).\n", strerror(errno
) );
925 reply_msg_len
= IVAL(op_break_reply
,OPBRK_CMD_LEN_OFFSET
);
926 reply_from_port
= SVAL(op_break_reply
,OPBRK_CMD_PORT_OFFSET
);
928 reply_msg_start
= &op_break_reply
[OPBRK_CMD_HEADER_LEN
];
931 #if defined(HAVE_KERNEL_OPLOCKS)
932 if((reply_msg_len
!= OPLOCK_BREAK_MSG_LEN
) && (reply_msg_len
!= KERNEL_OPLOCK_BREAK_MSG_LEN
))
934 if(reply_msg_len
!= OPLOCK_BREAK_MSG_LEN
)
938 DEBUG( 0, ( "request_oplock_break: invalid message length (%d) received.", reply_msg_len
) );
939 DEBUGADD( 0, ( " Ignoring.\n" ) );
944 * Test to see if this is the reply we are awaiting.
947 if((SVAL(reply_msg_start
,OPBRK_MESSAGE_CMD_OFFSET
) & CMD_REPLY
) &&
948 ((SVAL(reply_msg_start
,OPBRK_MESSAGE_CMD_OFFSET
) & ~CMD_REPLY
) == OPLOCK_BREAK_CMD
) &&
949 (reply_from_port
== share_entry
->op_port
) &&
950 (memcmp(&reply_msg_start
[OPLOCK_BREAK_PID_OFFSET
],
951 &op_break_msg
[OPLOCK_BREAK_PID_OFFSET
],
952 OPLOCK_BREAK_MSG_LEN
- OPLOCK_BREAK_PID_OFFSET
) == 0))
955 * This is the reply we've been waiting for.
962 * This is another message - a break request.
963 * Note that both kernel oplock break requests
964 * and UDP inter-smbd oplock break requests will
967 * Process it to prevent potential deadlock.
968 * Note that the code in switch_message() prevents
969 * us from recursing into here as any SMB requests
970 * we might process that would cause another oplock
971 * break request to be made will be queued.
975 process_local_message(op_break_reply
, sizeof(op_break_reply
));
978 time_left
-= (time(NULL
) - start_time
);
981 DEBUG(3,("request_oplock_break: broke oplock.\n"));
986 /****************************************************************************
987 Attempt to break an oplock on a file (if oplocked).
988 Returns True if the file was closed as a result of
989 the oplock break, False otherwise.
990 Used as a last ditch attempt to free a space in the
991 file table when we have run out.
992 ****************************************************************************/
993 BOOL
attempt_close_oplocked_file(files_struct
*fsp
)
996 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp
->fsp_name
));
998 if (fsp
->open
&& fsp
->granted_oplock
&& !fsp
->sent_oplock_break
) {
1000 /* Try and break the oplock. */
1001 file_fd_struct
*fd_ptr
= fsp
->fd_ptr
;
1002 if(oplock_break( fd_ptr
->dev
, fd_ptr
->inode
, &fsp
->open_time
)) {
1003 if(!fsp
->open
) /* Did the oplock break close the file ? */
1011 /****************************************************************************
1012 Init function to check if kernel level oplocks are available.
1013 ****************************************************************************/
1015 void check_kernel_oplocks(void)
1020 * We only do this check once on startup.
1027 lp_set_kernel_oplocks(False
);
1029 #if defined(HAVE_KERNEL_OPLOCKS)
1035 set_process_capability(KERNEL_OPLOCK_CAPABILITY
,True
);
1036 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY
,True
);
1038 slprintf( tmpname
, sizeof(tmpname
)-1, "/tmp/ot.%d.XXXXXX", (unsigned int)getpid());
1041 if(pipe(pfd
) != 0) {
1042 DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
1047 if((fd
= open(tmpname
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600)) < 0) {
1048 DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
1049 tmpname
, strerror(errno
) ));
1058 if(fcntl(fd
, F_OPLKREG
, pfd
[1]) == -1) {
1059 DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
1060 Disabling kernel oplock support.\n" ));
1067 if(fcntl(fd
, F_OPLKACK
, OP_REVOKE
) < 0 ) {
1068 DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
1069 Disabling kernel oplock support.\n", strerror(errno
) ));
1076 oplock_pipe_read
= pfd
[0];
1077 oplock_pipe_write
= pfd
[1];
1080 DEBUG(3,("check_kernel_oplocks: Kernel oplocks enabled.\n"));
1082 lp_set_kernel_oplocks(True
);
1084 #endif /* HAVE_KERNEL_OPLOCKS */