summaryrefslogtreecommitdiff
path: root/source3/smbd/oplock.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2000-06-10 13:38:07 +0000
committerAndrew Tridgell <tridge@samba.org>2000-06-10 13:38:07 +0000
commit52cb05678a9b08b5aa7dbe13ae6b54ff9ee4ecac (patch)
tree3d8dfdc81837b743cbfd383b6f9203df5e4c5285 /source3/smbd/oplock.c
parenta9a512192d05d6559d0315be96e0bfcf8800f69e (diff)
downloadsamba-52cb05678a9b08b5aa7dbe13ae6b54ff9ee4ecac.tar.gz
samba-52cb05678a9b08b5aa7dbe13ae6b54ff9ee4ecac.tar.bz2
samba-52cb05678a9b08b5aa7dbe13ae6b54ff9ee4ecac.zip
continued the split of the kernel level oplocks code into a more
modular form. In this pass I added oplock_irix.c and added a "struct kernel_oplocks" that describes a kernel oplock implementation. (This used to be commit b5ceab810292602ea9a81696c20a781c16b706c2)
Diffstat (limited to 'source3/smbd/oplock.c')
-rw-r--r--source3/smbd/oplock.c499
1 files changed, 122 insertions, 377 deletions
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index af48b06ab0..33d82f3dde 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -28,11 +28,6 @@ extern int DEBUGLEVEL;
/* Oplock ipc UDP socket. */
static int oplock_sock = -1;
uint16 global_oplock_port = 0;
-static int oplock_pipe_read = -1;
-
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
-static int oplock_pipe_write = -1;
-#endif
/* Current number of oplocks we have outstanding. */
static int32 exclusive_oplocks_open = 0;
@@ -42,6 +37,8 @@ BOOL global_oplock_break = False;
extern int smb_read_error;
+static struct kernel_oplocks *koplocks;
+
static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local);
/****************************************************************************
@@ -54,200 +51,9 @@ int32 get_number_of_exclusive_open_oplocks(void)
}
-#if HAVE_KERNEL_OPLOCKS_IRIX
-/****************************************************************************
-test to see if IRIX kernel oplocks work
-****************************************************************************/
-static BOOL irix_oplocks_available(void)
-{
- int fd;
- int pfd[2];
- pstring tmpname;
-
- oplock_set_capability(True, True);
-
- slprintf(tmpname,sizeof(tmpname)-1, "%s/koplock.%d", lp_lockdir(), (int)sys_getpid());
-
- if(pipe(pfd) != 0) {
- DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
- strerror(errno) ));
- return False;
- }
-
- if((fd = sys_open(tmpname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600)) < 0) {
- DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
- tmpname, strerror(errno) ));
- unlink( tmpname );
- close(pfd[0]);
- close(pfd[1]);
- return False;
- }
-
- unlink( tmpname );
-
- if(fcntl(fd, F_OPLKREG, pfd[1]) == -1) {
- DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
-Disabling kernel oplock support.\n" ));
- close(pfd[0]);
- close(pfd[1]);
- close(fd);
- return False;
- }
-
- if(fcntl(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
- DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
-Disabling kernel oplock support.\n", strerror(errno) ));
- close(pfd[0]);
- close(pfd[1]);
- close(fd);
- return False;
- }
-
- close(pfd[0]);
- close(pfd[1]);
- close(fd);
-
- return True;
-}
-#endif
-
-/****************************************************************************
- Setup the kernel level oplock backchannel for this process.
-****************************************************************************/
-BOOL setup_kernel_oplock_pipe(void)
-{
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
- if(lp_kernel_oplocks()) {
- int pfd[2];
-
- if(pipe(pfd) != 0) {
- DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n",
- strerror(errno) ));
- return False;
- }
-
- oplock_pipe_read = pfd[0];
- oplock_pipe_write = pfd[1];
- }
-#endif /* HAVE_KERNEL_OPLOCKS_IRIX */
- return True;
-}
-
-/****************************************************************************
- Open the oplock IPC socket communication.
-****************************************************************************/
-
-BOOL open_oplock_ipc(void)
-{
- struct sockaddr_in sock_name;
- int len = sizeof(sock_name);
-
- DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
-
- /* Open a lookback UDP socket on a random port. */
- oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK),False);
- if (oplock_sock == -1)
- {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
-address %lx. Error was %s\n", (long)htonl(INADDR_LOOPBACK), strerror(errno)));
- global_oplock_port = 0;
- return(False);
- }
-
- /* Find out the transient UDP port we have been allocated. */
- if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
- {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
- strerror(errno)));
- close(oplock_sock);
- oplock_sock = -1;
- global_oplock_port = 0;
- return False;
- }
- global_oplock_port = ntohs(sock_name.sin_port);
-
- if(!setup_kernel_oplock_pipe())
- return False;
-
- DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
- (int)sys_getpid(), global_oplock_port));
-
- return True;
-}
-
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
-/****************************************************************************
- * Deal with the IRIX kernel <--> smbd
- * oplock break protocol.
-****************************************************************************/
-static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len, int timeout)
-{
- oplock_stat_t os;
- SMB_DEV_T dev;
- SMB_INO_T inode;
- char dummy;
-
- /*
- * Read one byte of zero to clear the
- * kernel break notify message.
- */
-
- if(read(oplock_pipe_read, &dummy, 1) != 1) {
- DEBUG(0,("receive_local_message: read of kernel notification failed. \
-Error was %s.\n", strerror(errno) ));
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /*
- * Do a query to get the
- * device and inode of the file that has the break
- * request outstanding.
- */
-
- if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
- DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
-Error was %s.\n", strerror(errno) ));
- if(errno == EAGAIN) {
- /*
- * Duplicate kernel break message - ignore.
- */
- memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
- return True;
- }
- smb_read_error = READ_ERROR;
- return False;
- }
-
- dev = (SMB_DEV_T)os.os_dev;
- inode = (SMB_INO_T)os.os_ino;
-
- DEBUG(5,("receive_local_message: kernel oplock break request received for \
-dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
-
- /*
- * Create a kernel oplock break message.
- */
-
- /* Setup the message header */
- SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
- SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
-
- buffer += OPBRK_CMD_HEADER_LEN;
-
- SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
-
- memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));
-
- return True;
-}
-#endif /* HAVE_KERNEL_OPLOCKS_IRIX */
-
-
/****************************************************************************
Read an oplock break message from either the oplock UDP fd or the
- kernel oplock pipe fd (if kernel oplocks are supported).
+ kernel (if kernel oplocks are supported).
If timeout is zero then *fds contains the file descriptors that
are ready to be read and acted upon. If timeout is non-zero then
@@ -269,8 +75,9 @@ BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeou
int selrtn;
int maxfd = oplock_sock;
- if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
- maxfd = MAX(maxfd, oplock_pipe_read);
+ if (koplocks && koplocks->notification_fd != -1) {
+ FD_SET(koplocks->notification_fd, fds);
+ }
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
@@ -291,11 +98,9 @@ BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeou
}
}
-#if HAVE_KERNEL_OPLOCKS_IRIX
- if (FD_ISSET(oplock_pipe_read,fds)) {
- return irix_receive_message(fds, buffer, buffer_len, timeout);
+ if (koplocks && koplocks->msg_waiting(fds)) {
+ return koplocks->receive_message(fds, buffer, buffer_len);
}
-#endif
/*
* From here down we deal with the smbd <--> smbd
@@ -337,42 +142,12 @@ BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeou
}
/****************************************************************************
- Attempt to set an kernel oplock on a file. Always returns True if kernel
- oplocks not available.
-****************************************************************************/
-static BOOL set_kernel_oplock(files_struct *fsp, int oplock_type)
-{
- if(!lp_kernel_oplocks()) return True;
-
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
- if (fcntl(fsp->fd, F_OPLKREG, oplock_pipe_write) < 0 ) {
- if(errno != EAGAIN) {
- DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
-inode = %.0f. Error was %s\n",
- fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode,
- strerror(errno) ));
- } else {
- DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
-inode = %.0f. Another process had the file open.\n",
- fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode ));
- }
- return False;
- }
-
- DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
- fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode));
-#endif /* HAVE_KERNEL_OPLOCKS_IRIX */
-
- return True;
-}
-
-/****************************************************************************
Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
disabled (just sets flags). Returns True if oplock set.
****************************************************************************/
BOOL set_file_oplock(files_struct *fsp, int oplock_type)
{
- if (!set_kernel_oplock(fsp, oplock_type))
+ if (koplocks && !koplocks->set_oplock(fsp, oplock_type))
return False;
fsp->oplock_type = oplock_type;
@@ -390,46 +165,12 @@ BOOL set_file_oplock(files_struct *fsp, int oplock_type)
}
/****************************************************************************
- Release a kernel oplock on a file.
-****************************************************************************/
-static void release_kernel_oplock(files_struct *fsp)
-{
- if (!lp_kernel_oplocks()) return;
-
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
- if (DEBUGLVL(10)) {
- /*
- * Check and print out the current kernel
- * oplock state of this file.
- */
- int state = fcntl(fsp->fd, F_OPLKACK, -1);
- dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \
-oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, state );
- }
-
- /*
- * Remove the kernel oplock on this file.
- */
- if(fcntl(fsp->fd, F_OPLKACK, OP_REVOKE) < 0) {
- if( DEBUGLVL( 0 )) {
- dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
- dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
- fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, strerror(errno) );
- }
- }
-#endif /* HAVE_KERNEL_OPLOCKS_IRIX */
-}
-
-
-/****************************************************************************
Attempt to release an oplock on a file. Decrements oplock count.
****************************************************************************/
void release_file_oplock(files_struct *fsp)
{
- release_kernel_oplock(fsp);
+ if (koplocks) koplocks->release_oplock(fsp);
if (fsp->oplock_type == LEVEL_II_OPLOCK)
level_II_oplocks_open--;
@@ -448,11 +189,11 @@ void release_file_oplock(files_struct *fsp)
static void downgrade_file_oplock(files_struct *fsp)
{
- release_kernel_oplock(fsp);
- fsp->oplock_type = LEVEL_II_OPLOCK;
- exclusive_oplocks_open--;
- level_II_oplocks_open++;
- fsp->sent_oplock_break = NO_BREAK_SENT;
+ if (koplocks) koplocks->release_oplock(fsp);
+ fsp->oplock_type = LEVEL_II_OPLOCK;
+ exclusive_oplocks_open--;
+ level_II_oplocks_open++;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
}
/****************************************************************************
@@ -462,48 +203,44 @@ static void downgrade_file_oplock(files_struct *fsp)
BOOL remove_oplock(files_struct *fsp)
{
- SMB_DEV_T dev = fsp->dev;
- SMB_INO_T inode = fsp->inode;
- BOOL ret = True;
-
- /* Remove the oplock flag from the sharemode. */
- if (lock_share_entry_fsp(fsp) == False) {
- DEBUG(0,("remove_oplock: failed to lock share entry for file %s\n",
- fsp->fsp_name ));
- ret = False;
- }
-
- if (fsp->sent_oplock_break == EXCLUSIVE_BREAK_SENT) {
+ SMB_DEV_T dev = fsp->dev;
+ SMB_INO_T inode = fsp->inode;
+ BOOL ret = True;
+
+ /* Remove the oplock flag from the sharemode. */
+ if (lock_share_entry_fsp(fsp) == False) {
+ DEBUG(0,("remove_oplock: failed to lock share entry for file %s\n",
+ fsp->fsp_name ));
+ ret = False;
+ }
- /*
- * Deal with a reply when a break-to-none was sent.
- */
+ if (fsp->sent_oplock_break == EXCLUSIVE_BREAK_SENT) {
+ /*
+ * Deal with a reply when a break-to-none was sent.
+ */
- if(remove_share_oplock(fsp)==False) {
- DEBUG(0,("remove_oplock: failed to remove share oplock for file %s fnum %d, \
+ if(remove_share_oplock(fsp)==False) {
+ DEBUG(0,("remove_oplock: failed to remove share oplock for file %s fnum %d, \
dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
- ret = False;
- }
-
- release_file_oplock(fsp);
-
- } else {
-
- /*
- * Deal with a reply when a break-to-level II was sent.
- */
+ ret = False;
+ }
- if(downgrade_share_oplock(fsp)==False) {
- DEBUG(0,("remove_oplock: failed to downgrade share oplock for file %s fnum %d, \
+ release_file_oplock(fsp);
+ } else {
+ /*
+ * Deal with a reply when a break-to-level II was sent.
+ */
+ if(downgrade_share_oplock(fsp)==False) {
+ DEBUG(0,("remove_oplock: failed to downgrade share oplock for file %s fnum %d, \
dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
- ret = False;
- }
-
- downgrade_file_oplock(fsp);
- }
+ ret = False;
+ }
+
+ downgrade_file_oplock(fsp);
+ }
- unlock_share_entry_fsp(fsp);
- return ret;
+ unlock_share_entry_fsp(fsp);
+ return ret;
}
/****************************************************************************
@@ -514,26 +251,25 @@ dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)
int setup_oplock_select_set( fd_set *fds)
{
- int maxfd = oplock_sock;
+ int maxfd = oplock_sock;
- if(oplock_sock == -1)
- return 0;
+ if(oplock_sock == -1)
+ return 0;
- FD_SET(oplock_sock,fds);
+ FD_SET(oplock_sock,fds);
- if(lp_kernel_oplocks() && (oplock_pipe_read != -1)) {
- FD_SET(oplock_pipe_read,fds);
- maxfd = MAX(maxfd,oplock_pipe_read);
- }
+ if (koplocks && koplocks->notification_fd != -1) {
+ FD_SET(koplocks->notification_fd, fds);
+ maxfd = MAX(maxfd, koplocks->notification_fd);
+ }
- return maxfd;
+ return maxfd;
}
/****************************************************************************
Process an oplock break message - whether it came from the UDP socket
or from the kernel.
****************************************************************************/
-
BOOL process_local_message(char *buffer, int buf_size)
{
int32 msg_len;
@@ -562,26 +298,15 @@ BOOL process_local_message(char *buffer, int buf_size)
switch(break_cmd_type)
{
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
case KERNEL_OPLOCK_BREAK_CMD:
- /* Ensure that the msg length is correct. */
- if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN)
- {
- DEBUG(0,("process_local_message: incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, \
-should be %d).\n", msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
- return False;
- }
- {
- memcpy((char *)&inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(inode));
- memcpy((char *)&dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(dev));
-
- ptval = NULL;
-
- DEBUG(5,("process_local_message: kernel oplock break request for \
-file dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode));
- }
- break;
-#endif /* HAVE_KERNEL_OPLOCKS_IRIX */
+ if (!koplocks) {
+ DEBUG(0,("unexpected kernel oplock break!\n"));
+ break;
+ }
+ if (!koplocks->parse_message(msg_start, msg_len, &inode, &dev)) {
+ DEBUG(0,("kernel oplock break parse failure!\n"));
+ }
+ break;
case OPLOCK_BREAK_CMD:
case LEVEL_II_OPLOCK_BREAK_CMD:
@@ -708,18 +433,18 @@ pid %d, port %d, for file dev = %x, inode = %.0f\n",
static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
{
- memset(outbuf,'\0',smb_size);
- set_message(outbuf,8,0,True);
-
- SCVAL(outbuf,smb_com,SMBlockingX);
- SSVAL(outbuf,smb_tid,fsp->conn->cnum);
- SSVAL(outbuf,smb_pid,0xFFFF);
- SSVAL(outbuf,smb_uid,0);
- SSVAL(outbuf,smb_mid,0xFFFF);
- SCVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,fsp->fnum);
- SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
- SCVAL(outbuf,smb_vwv3+1,level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
+ memset(outbuf,'\0',smb_size);
+ set_message(outbuf,8,0,True);
+
+ SCVAL(outbuf,smb_com,SMBlockingX);
+ SSVAL(outbuf,smb_tid,fsp->conn->cnum);
+ SSVAL(outbuf,smb_pid,0xFFFF);
+ SSVAL(outbuf,smb_uid,0);
+ SSVAL(outbuf,smb_mid,0xFFFF);
+ SCVAL(outbuf,smb_vwv0,0xFF);
+ SSVAL(outbuf,smb_vwv2,fsp->fnum);
+ SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
+ SCVAL(outbuf,smb_vwv3+1,level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
}
/****************************************************************************
@@ -749,7 +474,6 @@ static void wait_before_sending_break(BOOL local_request)
/****************************************************************************
Ensure that we have a valid oplock.
****************************************************************************/
-
static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
{
files_struct *fsp = NULL;
@@ -966,7 +690,10 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
/* Prepare the SMBlockingX message. */
- if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && !lp_kernel_oplocks() && lp_level2_oplocks(SNUM(fsp->conn))) {
+ if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
+ !koplocks && /* NOTE: we force levelII off for kernel oplocks -
+ this will change when it is supported */
+ lp_level2_oplocks(SNUM(fsp->conn))) {
using_levelII = True;
} else {
using_levelII = False;
@@ -1244,8 +971,10 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
FD_ZERO(&fds);
FD_SET(oplock_sock,&fds);
- if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
- FD_SET(oplock_pipe_read,&fds);
+
+ if (koplocks && koplocks->notification_fd != -1) {
+ FD_SET(koplocks->notification_fd, &fds);
+ }
if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
time_left ? time_left * 1000 : 1) == False)
@@ -1292,7 +1021,7 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
+#if HAVE_KERNEL_OPLOCKS_IRIX
if((reply_msg_len != OPLOCK_BREAK_MSG_LEN) && (reply_msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN))
#else
if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
@@ -1354,7 +1083,6 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
Used as a last ditch attempt to free a space in the
file table when we have run out.
****************************************************************************/
-
BOOL attempt_close_oplocked_file(files_struct *fsp)
{
@@ -1371,30 +1099,47 @@ BOOL attempt_close_oplocked_file(files_struct *fsp)
return False;
}
+
/****************************************************************************
- Init function to check if kernel level oplocks are available.
+setup oplocks for this process
****************************************************************************/
-
-void check_kernel_oplocks(void)
+BOOL init_oplocks(void)
{
- static BOOL done;
-
- /*
- * We only do this check once on startup.
- */
- if(done) return;
-
- done = True;
- lp_set_kernel_oplocks(False);
-
-#if defined(HAVE_KERNEL_OPLOCKS_IRIX)
- if (irix_oplocks_available()) {
- lp_set_kernel_oplocks(True);
-
- DEBUG(0,("check_kernel_oplocks: Kernel oplocks available and set to %s.\n",
- lp_kernel_oplocks() ? "True" : "False" ));
+ struct sockaddr_in sock_name;
+ int len = sizeof(sock_name);
+
+ DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
+
+ /* Open a lookback UDP socket on a random port. */
+ oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK),False);
+ if (oplock_sock == -1) {
+ DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
+address %lx. Error was %s\n", (long)htonl(INADDR_LOOPBACK), strerror(errno)));
+ global_oplock_port = 0;
+ return(False);
+ }
+
+ /* Find out the transient UDP port we have been allocated. */
+ if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0) {
+ DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
+ strerror(errno)));
+ close(oplock_sock);
+ oplock_sock = -1;
+ global_oplock_port = 0;
+ return False;
}
-#endif /* HAVE_KERNEL_OPLOCKS_IRIX */
+ global_oplock_port = ntohs(sock_name.sin_port);
+
+ if (lp_kernel_oplocks()) {
+#if HAVE_KERNEL_OPLOCKS_IRIX
+ koplocks = irix_init_kernel_oplocks();
+#endif
+ }
+
+ DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
+ (int)sys_getpid(), global_oplock_port));
+
+ return True;
}
#undef OLD_NTDOMAIN