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()) {
243 if(fcntl(fsp->fd_ptr->fd, F_OPLKREG, oplock_pipe_write) < 0) {
244 if(errno != EAGAIN) {
245 DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
246 inode = %.0f. Error was %s\n",
247 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
250 DEBUG(5,("set_file_oplock: Refused oplock on file %s, dev = %x, \
251 inode = %.0f. Another process had the file open.\n",
252 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode ));
257 #endif /* HAVE_KERNEL_OPLOCKS */
259 DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f\n",
260 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
262 fsp->granted_oplock = True;
263 fsp->sent_oplock_break = False;
264 global_oplocks_open++;
269 /****************************************************************************
270 Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
271 disabled (just clears flags).
272 ****************************************************************************/
274 static void release_file_oplock(files_struct *fsp)
276 #if defined(HAVE_KERNEL_OPLOCKS)
277 if(fsp->granted_oplock && lp_kernel_oplocks())
282 * Check and print out the current kernel
283 * oplock state of this file.
285 int state = fcntl(fsp->fd_ptr->fd, F_OPLKACK, -1);
286 dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
287 oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
288 (double)fsp->fd_ptr->inode, state );
292 * Remove the kernel oplock on this file.
295 if(fcntl(fsp->fd_ptr->fd, F_OPLKACK, OP_REVOKE) < 0)
299 dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
300 dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
301 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
302 (double)fsp->fd_ptr->inode, strerror(errno) );
306 #endif /* HAVE_KERNEL_OPLOCKS */
308 fsp->granted_oplock = False;
309 fsp->sent_oplock_break = False;
310 global_oplocks_open--;
313 /****************************************************************************
314 Setup the listening set of file descriptors for an oplock break
315 message either from the UDP socket or from the kernel. Returns the maximum
317 ****************************************************************************/
319 int setup_oplock_select_set( fd_set *fds)
321 int maxfd = oplock_sock;
322 FD_SET(oplock_sock,fds);
324 #if defined(HAVE_KERNEL_OPLOCKS)
325 if(lp_kernel_oplocks()) {
326 FD_SET(oplock_pipe_read,fds);
327 maxfd = MAX(maxfd,oplock_pipe_read);
329 #endif /* HAVE_KERNEL_OPLOCKS */
334 /****************************************************************************
335 Process an oplock break message - whether it came from the UDP socket
337 ****************************************************************************/
339 BOOL process_local_message(char *buffer, int buf_size)
348 struct timeval *ptval = NULL;
350 msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
351 from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
353 msg_start = &buffer[OPBRK_CMD_HEADER_LEN];
355 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
356 msg_len, from_port));
359 * Pull the info out of the requesting packet.
362 switch(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET))
364 #if defined(HAVE_KERNEL_OPLOCKS)
365 case KERNEL_OPLOCK_BREAK_CMD:
366 /* Ensure that the msg length is correct. */
367 if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN)
369 DEBUG(0,("process_local_message: incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, \
370 should be %d).\n", msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
375 * Warning - beware of SMB_INO_T <> 4 bytes. !!
377 #ifdef LARGE_SMB_INO_T
378 SMB_INO_T inode_low = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
379 SMB_INO_T inode_high = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET + 4);
380 inode = inode_low | (inode_high << 32);
381 #else /* LARGE_SMB_INO_T */
382 inode = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
383 #endif /* LARGE_SMB_INO_T */
385 dev = IVAL(msg_start,KERNEL_OPLOCK_BREAK_DEV_OFFSET);
389 DEBUG(5,("process_local_message: kernel oplock break request for \
390 file dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode));
393 #endif /* HAVE_KERNEL_OPLOCKS */
395 case OPLOCK_BREAK_CMD:
396 /* Ensure that the msg length is correct. */
397 if(msg_len != OPLOCK_BREAK_MSG_LEN)
399 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
400 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
405 * Warning - beware of SMB_INO_T <> 4 bytes. !!
407 #ifdef LARGE_SMB_INO_T
408 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
409 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
410 inode = inode_low | (inode_high << 32);
411 #else /* LARGE_SMB_INO_T */
412 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
413 #endif /* LARGE_SMB_INO_T */
415 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
417 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
418 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
422 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
424 DEBUG(5,("process_local_message: oplock break request from \
425 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
430 * Keep this as a debug case - eventually we can remove it.
433 DEBUG(0,("process_local_message: Received unsolicited break \
434 reply - dumping info.\n"));
436 if(msg_len != OPLOCK_BREAK_MSG_LEN)
438 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
439 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
445 * Warning - beware of SMB_INO_T <> 4 bytes. !!
447 #ifdef LARGE_SMB_INO_T
448 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
449 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
450 inode = inode_low | (inode_high << 32);
451 #else /* LARGE_SMB_INO_T */
452 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
453 #endif /* LARGE_SMB_INO_T */
455 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
456 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
458 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
459 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
465 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
466 (unsigned int)SVAL(msg_start,0)));
471 * Now actually process the break request.
474 if(global_oplocks_open != 0)
476 if(oplock_break(dev, inode, ptval) == False)
478 DEBUG(0,("process_local_message: oplock break failed.\n"));
485 * If we have no record of any currently open oplocks,
486 * it's not an error, as a close command may have
487 * just been issued on the file that was oplocked.
488 * Just log a message and return success in this case.
490 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
491 oplocks. Returning success.\n"));
495 * Do the appropriate reply - none in the kernel case.
498 if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
500 struct sockaddr_in toaddr;
502 /* Send the message back after OR'ing in the 'REPLY' bit. */
503 SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
505 bzero((char *)&toaddr,sizeof(toaddr));
506 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
507 toaddr.sin_port = htons(from_port);
508 toaddr.sin_family = AF_INET;
510 if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
511 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
513 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
514 remotepid, strerror(errno)));
518 DEBUG(5,("process_local_message: oplock break reply sent to \
519 pid %d, port %d, for file dev = %x, inode = %.0f\n",
520 remotepid, from_port, (unsigned int)dev, (double)inode));
526 /****************************************************************************
527 Process an oplock break directly.
528 ****************************************************************************/
530 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
532 extern struct current_user current_user;
536 files_struct *fsp = NULL;
538 BOOL shutdown_server = False;
539 connection_struct *saved_conn;
545 dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
546 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
549 /* We need to search the file open table for the
550 entry containing this dev and inode, and ensure
551 we have an oplock on it. */
552 fsp = file_find_dit(dev, inode, tval);
556 /* The file could have been closed in the meantime - return success. */
559 dbgtext( "oplock_break: cannot find open file with " );
560 dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
561 dbgtext( "allowing break to succeed.\n" );
566 /* Ensure we have an oplock on the file */
568 /* There is a potential race condition in that an oplock could
569 have been broken due to another udp request, and yet there are
570 still oplock break messages being sent in the udp message
571 queue for this file. So return true if we don't have an oplock,
572 as we may have just freed it.
575 if(!fsp->granted_oplock)
579 dbgtext( "oplock_break: file %s ", fsp->fsp_name );
580 dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
581 dbgtext( "Allowing break to succeed regardless.\n" );
586 /* mark the oplock break as sent - we don't want to send twice! */
587 if (fsp->sent_oplock_break)
591 dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
592 dbgtext( "file %s ", fsp->fsp_name);
593 dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
596 /* We have to fail the open here as we cannot send another oplock break on
597 this file whilst we are awaiting a response from the client - neither
598 can we allow another open to succeed while we are waiting for the
604 /* Now comes the horrid part. We must send an oplock break to the client,
605 and then process incoming messages until we get a close or oplock release.
606 At this point we know we need a new inbuf/outbuf buffer pair.
607 We cannot use these staticaly as we may recurse into here due to
608 messages crossing on the wire.
611 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
613 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
617 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
619 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
625 /* Prepare the SMBlockingX message. */
626 bzero(outbuf,smb_size);
627 set_message(outbuf,8,0,True);
629 SCVAL(outbuf,smb_com,SMBlockingX);
630 SSVAL(outbuf,smb_tid,fsp->conn->cnum);
631 SSVAL(outbuf,smb_pid,0xFFFF);
632 SSVAL(outbuf,smb_uid,0);
633 SSVAL(outbuf,smb_mid,0xFFFF);
634 SCVAL(outbuf,smb_vwv0,0xFF);
635 SSVAL(outbuf,smb_vwv2,fsp->fnum);
636 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
637 /* Change this when we have level II oplocks. */
638 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
640 send_smb(Client, outbuf);
642 /* Remember we just sent an oplock break on this file. */
643 fsp->sent_oplock_break = True;
645 /* We need this in case a readraw crosses on the wire. */
646 global_oplock_break = True;
648 /* Process incoming messages. */
650 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
651 seconds we should just die.... */
653 start_time = time(NULL);
656 * Save the information we need to re-become the
657 * user, then unbecome the user whilst we're doing this.
659 saved_conn = fsp->conn;
660 saved_vuid = current_user.vuid;
663 /* Save the chain fnum. */
666 while(OPEN_FSP(fsp) && fsp->granted_oplock)
668 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
671 * Die if we got an error.
674 if (smb_read_error == READ_EOF)
675 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
677 if (smb_read_error == READ_ERROR)
678 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
680 if (smb_read_error == READ_TIMEOUT)
681 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
682 OPLOCK_BREAK_TIMEOUT ) );
684 DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
685 DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
687 shutdown_server = True;
692 * There are certain SMB requests that we shouldn't allow
693 * to recurse. opens, renames and deletes are the obvious
694 * ones. This is handled in the switch_message() function.
695 * If global_oplock_break is set they will push the packet onto
696 * the pending smb queue and return -1 (no reply).
700 process_smb(inbuf, outbuf);
703 * Die if we go over the time limit.
706 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
710 dbgtext( "oplock_break: no break received from client " );
711 dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
712 dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
713 dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
715 shutdown_server = True;
721 * Go back to being the user who requested the oplock
724 if(!become_user(saved_conn, saved_vuid))
726 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
727 DEBUGADD( 0, ( "Shutting down server\n" ) );
730 exit_server("unable to re-become user");
732 /* Including the directory. */
735 /* Restore the chain fnum. */
736 file_chain_restore();
738 /* Free the buffers we've been using to recurse. */
742 /* We need this in case a readraw crossed on the wire. */
743 if(global_oplock_break)
744 global_oplock_break = False;
747 * If the client did not respond we must die.
752 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
753 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
756 exit_server("oplock break failure");
761 /* The lockingX reply will have removed the oplock flag
762 from the sharemode. */
763 release_file_oplock(fsp);
766 /* Santity check - remove this later. JRA */
767 if(global_oplocks_open < 0)
769 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
770 global_oplocks_open));
771 exit_server("oplock_break: global_oplocks_open < 0");
777 dbgtext( "oplock_break: returning success for " );
778 dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
779 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
785 /****************************************************************************
786 Send an oplock break message to another smbd process. If the oplock is held
787 by the local smbd then call the oplock break function directly.
788 ****************************************************************************/
790 BOOL request_oplock_break(share_mode_entry *share_entry,
791 SMB_DEV_T dev, SMB_INO_T inode)
793 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
794 struct sockaddr_in addr_out;
799 if(pid == share_entry->pid)
801 /* We are breaking our own oplock, make sure it's us. */
802 if(share_entry->op_port != global_oplock_port)
804 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
805 should be %d\n", pid, share_entry->op_port, global_oplock_port));
809 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
811 /* Call oplock break direct. */
812 return oplock_break(dev, inode, &share_entry->time);
815 /* We need to send a OPLOCK_BREAK_CMD message to the
816 port in the share mode entry. */
818 SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
819 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
820 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
821 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
822 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
824 * WARNING - beware of SMB_INO_T <> 4 bytes.
826 #ifdef LARGE_SMB_INO_T
827 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
828 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
829 #else /* LARGE_SMB_INO_T */
830 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
831 #endif /* LARGE_SMB_INO_T */
833 /* set the address and port */
834 bzero((char *)&addr_out,sizeof(addr_out));
835 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
836 addr_out.sin_port = htons( share_entry->op_port );
837 addr_out.sin_family = AF_INET;
841 dbgtext( "request_oplock_break: sending a oplock break message to " );
842 dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
843 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
846 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
847 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
851 dbgtext( "request_oplock_break: failed when sending a oplock " );
852 dbgtext( "break message to pid %d ", share_entry->pid );
853 dbgtext( "on port %d ", share_entry->op_port );
854 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
855 dbgtext( "Error was %s\n", strerror(errno) );
861 * Now we must await the oplock broken message coming back
862 * from the target smbd process. Timeout if it fails to
863 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
864 * While we get messages that aren't ours, loop.
867 start_time = time(NULL);
868 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
870 while(time_left >= 0)
872 char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
874 uint16 reply_from_port;
875 char *reply_msg_start;
879 FD_SET(oplock_sock,&fds);
880 #if defined(HAVE_KERNEL_OPLOCKS)
881 if(lp_kernel_oplocks())
882 FD_SET(oplock_pipe_read,&fds);
883 #endif /* HAVE_KERNEL_OPLOCKS */
885 if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
886 time_left ? time_left * 1000 : 1) == False)
888 if(smb_read_error == READ_TIMEOUT)
892 dbgtext( "request_oplock_break: no response received to oplock " );
893 dbgtext( "break request to pid %d ", share_entry->pid );
894 dbgtext( "on port %d ", share_entry->op_port );
895 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
899 * This is a hack to make handling of failing clients more robust.
900 * If a oplock break response message is not received in the timeout
901 * period we may assume that the smbd servicing that client holding
902 * the oplock has died and the client changes were lost anyway, so
903 * we should continue to try and open the file.
910 dbgtext( "request_oplock_break: error in response received " );
911 dbgtext( "to oplock break request to pid %d ", share_entry->pid );
912 dbgtext( "on port %d ", share_entry->op_port );
913 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
914 dbgtext( "Error was (%s).\n", strerror(errno) );
919 reply_msg_len = IVAL(op_break_reply,OPBRK_CMD_LEN_OFFSET);
920 reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
922 reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
925 #if defined(HAVE_KERNEL_OPLOCKS)
926 if((reply_msg_len != OPLOCK_BREAK_MSG_LEN) && (reply_msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN))
928 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
932 DEBUG( 0, ( "request_oplock_break: invalid message length (%d) received.", reply_msg_len ) );
933 DEBUGADD( 0, ( " Ignoring.\n" ) );
938 * Test to see if this is the reply we are awaiting.
941 if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
942 ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == OPLOCK_BREAK_CMD) &&
943 (reply_from_port == share_entry->op_port) &&
944 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
945 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
946 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
949 * This is the reply we've been waiting for.
956 * This is another message - a break request.
957 * Note that both kernel oplock break requests
958 * and UDP inter-smbd oplock break requests will
961 * Process it to prevent potential deadlock.
962 * Note that the code in switch_message() prevents
963 * us from recursing into here as any SMB requests
964 * we might process that would cause another oplock
965 * break request to be made will be queued.
969 process_local_message(op_break_reply, sizeof(op_break_reply));
972 time_left -= (time(NULL) - start_time);
975 DEBUG(3,("request_oplock_break: broke oplock.\n"));
980 /****************************************************************************
981 Attempt to break an oplock on a file (if oplocked).
982 Returns True if the file was closed as a result of
983 the oplock break, False otherwise.
984 Used as a last ditch attempt to free a space in the
985 file table when we have run out.
986 ****************************************************************************/
987 BOOL attempt_close_oplocked_file(files_struct *fsp)
990 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
992 if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
994 /* Try and break the oplock. */
995 file_fd_struct *fd_ptr = fsp->fd_ptr;
996 if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
997 if(!fsp->open) /* Did the oplock break close the file ? */
1005 /****************************************************************************
1006 Init function to check if kernel level oplocks are available.
1007 ****************************************************************************/
1009 void check_kernel_oplocks(void)
1014 * We only do this check once on startup.
1021 lp_set_kernel_oplocks(False);
1023 #if defined(HAVE_KERNEL_OPLOCKS)
1029 slprintf( tmpname, sizeof(tmpname)-1, "/tmp/ot.%d.XXXXXX", (unsigned int)getpid());
1032 if(pipe(pfd) != 0) {
1033 DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
1038 if((fd = open(tmpname, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) {
1039 DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
1040 tmpname, strerror(errno) ));
1049 if(fcntl(fd, F_OPLKREG, pfd[1]) == -1) {
1050 DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
1051 Disabling kernel oplock support.\n" ));
1058 if(fcntl(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
1059 DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
1060 Disabling kernel oplock support.\n", strerror(errno) ));
1067 oplock_pipe_read = pfd[0];
1068 oplock_pipe_write = pfd[1];
1071 DEBUG(3,("check_kernel_oplocks: Kernel oplocks enabled.\n"));
1073 lp_set_kernel_oplocks(True);
1075 #endif /* HAVE_KERNEL_OPLOCKS */