From 3b34486f6aaeb81376d9522a01bc6b69d34b4572 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 22 Jan 2009 12:13:29 +0100 Subject: Actually complete 3662c2b... --- source3/lib/netapi/cm.c | 3 +-- source3/rpcclient/rpcclient.c | 6 +++--- source3/utils/net_rpc.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index e616a2509f..d5ef09d831 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -184,8 +184,7 @@ WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx, status = pipe_cm_open(ctx, cli, interface, &result); if (!NT_STATUS_IS_OK(status)) { libnetapi_set_error_string(ctx, "failed to open PIPE %s: %s", - cli_get_pipe_name_from_iface(debug_ctx(), cli, - interface), + cli_get_pipe_name_from_iface(debug_ctx(), interface), get_friendly_nt_error_msg(status)); return WERR_DEST_NOT_FOUND; } diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 7e31862c34..050e78d274 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -620,7 +620,7 @@ static NTSTATUS do_cmd(struct cli_state *cli, DEBUG(0, ("Could not initialise %s. Invalid " "auth type %u\n", cli_get_pipe_name_from_iface( - debug_ctx(), cli, + debug_ctx(), cmd_entry->interface), pipe_default_auth_type )); return NT_STATUS_UNSUCCESSFUL; @@ -628,7 +628,7 @@ static NTSTATUS do_cmd(struct cli_state *cli, if (!NT_STATUS_IS_OK(ntresult)) { DEBUG(0, ("Could not initialise %s. Error was %s\n", cli_get_pipe_name_from_iface( - debug_ctx(), cli, + debug_ctx(), cmd_entry->interface), nt_errstr(ntresult) )); return ntresult; @@ -658,7 +658,7 @@ static NTSTATUS do_cmd(struct cli_state *cli, if (!NT_STATUS_IS_OK(ntresult)) { DEBUG(0, ("Could not initialise credentials for %s.\n", cli_get_pipe_name_from_iface( - debug_ctx(), cli, + debug_ctx(), cmd_entry->interface))); return ntresult; } diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index c000b58098..0f59f02746 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -182,7 +182,7 @@ int run_rpc_command(struct net_context *c, if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("Could not initialise pipe %s. Error was %s\n", cli_get_pipe_name_from_iface( - debug_ctx(), cli, interface), + debug_ctx(), interface), nt_errstr(nt_status) )); cli_shutdown(cli); return -1; -- cgit From f9dcd3d2b79e4c1e19ac1c81e3e75370c8716586 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Jan 2009 01:58:04 +0100 Subject: s3:events: always run_events() before sys_select() We might have pending signal events not only timed events. metze --- source3/lib/events.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/lib/events.c b/source3/lib/events.c index 74f30a709a..4484d5323b 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -180,17 +180,16 @@ static int s3_event_loop_once(struct tevent_context *ev) to.tv_sec = 9999; /* Max timeout */ to.tv_usec = 0; + if (run_events(ev, 0, NULL, NULL)) { + return 0; + } + GetTimeOfDay(&now); if (!event_add_to_select_args(ev, &now, &r_fds, &w_fds, &to, &maxfd)) { return -1; } - if (timeval_is_zero(&to)) { - run_events(ev, 0, NULL, NULL); - return 0; - } - ret = sys_select(maxfd+1, &r_fds, &w_fds, NULL, &to); if (ret == -1 && errno != EINTR) { -- cgit From 048f8dba141c2f9898aad67e09925f03394a946e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Jan 2009 04:14:20 +0100 Subject: s3: always call run_events() before and after sys_select() And always setup the fd events. metze --- source3/nmbd/nmbd_packets.c | 16 +++++++--------- source3/smbd/process.c | 10 ++++------ source3/smbd/server.c | 12 ++++++++---- source3/winbindd/winbindd.c | 2 ++ source3/winbindd/winbindd_dual.c | 33 ++++++++++++++++++++++++--------- 5 files changed, 45 insertions(+), 28 deletions(-) (limited to 'source3') diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index 66b584ad54..489034899e 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -1773,6 +1773,11 @@ bool listen_for_packets(bool run_election) } #endif + /* Process a signal and timer events now... */ + if (run_events(nmbd_event_context(), 0, NULL, NULL)) { + return False; + } + /* * During elections and when expecting a netbios response packet we * need to send election packets at tighter intervals. @@ -1789,13 +1794,6 @@ bool listen_for_packets(bool run_election) &r_fds, &w_fds, &timeout, &maxfd); } - if (timeval_is_zero(&timeout)) { - /* Process a timed event now... */ - if (run_events(nmbd_event_context(), 0, NULL, NULL)) { - return False; - } - } - /* Prepare for the select - allow certain signals. */ BlockSignals(False, SIGTERM); @@ -1806,11 +1804,11 @@ bool listen_for_packets(bool run_election) BlockSignals(True, SIGTERM); - if(selrtn == -1) { + if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) { return False; } - if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) { + if (selrtn == -1) { return False; } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 44cacfafdd..7847505f7c 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -818,13 +818,11 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection * &r_fds, &w_fds, &to, &maxfd); } - if (timeval_is_zero(&to)) { - /* Process a timed event now... */ - if (run_events(smbd_event_context(), 0, NULL, NULL)) { - return NT_STATUS_RETRY; - } + /* Process a signal and timed events now... */ + if (run_events(smbd_event_context(), 0, NULL, NULL)) { + return NT_STATUS_RETRY; } - + { int sav; START_PROFILE(smbd_idle); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 42c37f2056..163d0b81be 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -602,6 +602,10 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ } } + if (run_events(smbd_event_context(), 0, NULL, NULL)) { + continue; + } + idle_timeout = timeval_zero(); memcpy((char *)&r_fds, (char *)&listen_set, @@ -623,6 +627,10 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ timeval_is_zero(&idle_timeout) ? NULL : &idle_timeout); + if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) { + continue; + } + if (num == -1 && errno == EINTR) { if (got_sig_term) { exit_server_cleanly(NULL); @@ -653,10 +661,6 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ --num; } - if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) { - continue; - } - /* check if we need to reload services */ check_reload(time(NULL)); diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 821812925c..0bdc75ccd4 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -980,6 +980,8 @@ static void process_loop(void) no_fds_ready: + run_events(winbind_event_context(), selret, &r_fds, &w_fds); + #if 0 winbindd_check_cache_size(time(NULL)); #endif diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 4b57d08b03..2a85f6e0d4 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1371,7 +1371,9 @@ static bool fork_domain_child(struct winbindd_child *child) while (1) { int ret; - fd_set read_fds; + fd_set r_fds; + fd_set w_fds; + int maxfd; struct timeval t; struct timeval *tp; struct timeval now; @@ -1382,7 +1384,14 @@ static bool fork_domain_child(struct winbindd_child *child) winbind_check_sighup(override_logfile ? NULL : child->logfilename); - run_events(winbind_event_context(), 0, NULL, NULL); + /* Handle messages */ + + message_dispatch(winbind_messaging_context()); + + if (run_events(winbind_event_context(), 0, NULL, NULL)) { + TALLOC_FREE(frame); + continue; + } GetTimeOfDay(&now); @@ -1394,20 +1403,26 @@ static bool fork_domain_child(struct winbindd_child *child) child->domain->startup = False; } + FD_ZERO(&r_fds); + FD_ZERO(&w_fds); + FD_SET(state.sock, &r_fds); + maxfd = state.sock; + + event_add_to_select_args(winbind_event_context(), &now, + &r_fds, &w_fds, &t, &maxfd); tp = get_timed_events_timeout(winbind_event_context(), &t); if (tp) { DEBUG(11,("select will use timeout of %u.%u seconds\n", (unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec )); } - /* Handle messages */ - - message_dispatch(winbind_messaging_context()); - - FD_ZERO(&read_fds); - FD_SET(state.sock, &read_fds); + ret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, tp); - ret = sys_select(state.sock + 1, &read_fds, NULL, NULL, tp); + if (run_events(winbind_event_context(), ret, &r_fds, &w_fds)) { + /* We got a signal - continue. */ + TALLOC_FREE(frame); + continue; + } if (ret == 0) { DEBUG(11,("nothing is ready yet, continue\n")); -- cgit From 196028ab7b578526179d4fcff42a5d73ba07ccbb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Jan 2009 14:02:18 +0100 Subject: s3:smbd: restructure kernel oplocks code This converts the irix oplocks code to use a fd event and removes the last special case for file descriptors for the main sys_select(). metze --- source3/include/proto.h | 8 +-- source3/include/smb.h | 19 ++++--- source3/smbd/globals.c | 13 +---- source3/smbd/globals.h | 9 +--- source3/smbd/oplock.c | 33 ++++--------- source3/smbd/oplock_irix.c | 118 ++++++++++++++++++++++++++++---------------- source3/smbd/oplock_linux.c | 36 +++++++++----- source3/smbd/process.c | 44 +++-------------- 8 files changed, 134 insertions(+), 146 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 632f820b24..0c358a0429 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7026,8 +7026,8 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, /* The following definitions come from smbd/oplock.c */ int32 get_number_of_exclusive_open_oplocks(void); -bool oplock_message_waiting(fd_set *fds); -void process_kernel_oplocks(struct messaging_context *msg_ctx, fd_set *pfds); +bool oplock_message_waiting(); +void process_kernel_oplocks(struct messaging_context *msg_ctx); bool set_file_oplock(files_struct *fsp, int oplock_type); void release_file_oplock(files_struct *fsp); bool remove_oplock(files_struct *fsp); @@ -7041,14 +7041,14 @@ bool init_oplocks(struct messaging_context *msg_ctx); /* The following definitions come from smbd/oplock_irix.c */ -struct kernel_oplocks *irix_init_kernel_oplocks(void) ; +struct kernel_oplocks *irix_init_kernel_oplocks(TALLOC_CTX *mem_ctx) ; /* The following definitions come from smbd/oplock_linux.c */ void linux_set_lease_capability(void); int linux_set_lease_sighandler(int fd); int linux_setlease(int fd, int leasetype); -struct kernel_oplocks *linux_init_kernel_oplocks(void) ; +struct kernel_oplocks *linux_init_kernel_oplocks(TALLOC_CTX *mem_ctx) ; /* The following definitions come from smbd/password.c */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 799ffe1a46..19d2208ada 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1671,14 +1671,21 @@ enum smbd_capability { LEASE_CAPABILITY }; +struct kernel_oplocks_ops; +struct kernel_oplocks { + const struct kernel_oplocks_ops *ops; + void *private_data; +}; + /* if a kernel does support oplocks then a structure of the following typee is used to describe how to interact with the kernel */ -struct kernel_oplocks { - files_struct * (*receive_message)(fd_set *fds); - bool (*set_oplock)(files_struct *fsp, int oplock_type); - void (*release_oplock)(files_struct *fsp); - bool (*msg_waiting)(fd_set *fds); - int notification_fd; +struct kernel_oplocks_ops { + files_struct * (*receive_message)(struct kernel_oplocks *ctx); + bool (*set_oplock)(struct kernel_oplocks *ctx, + files_struct *fsp, int oplock_type); + void (*release_oplock)(struct kernel_oplocks *ctx, + files_struct *fsp); + bool (*msg_waiting)(struct kernel_oplocks *ctx); }; #include "smb_macros.h" diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c index 6fcf18da09..c5681223f9 100644 --- a/source3/smbd/globals.c +++ b/source3/smbd/globals.c @@ -175,20 +175,13 @@ char *LastDir = NULL; #if HAVE_KERNEL_OPLOCKS_LINUX SIG_ATOMIC_T oplock_signals_received = 0; SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE]; -struct kernel_oplocks linux_koplocks; -#endif - -#if HAVE_KERNEL_OPLOCKS_IRIX -int oplock_pipe_write = -1; -int oplock_pipe_read = -1; -struct kernel_oplocks irix_koplocks; #endif /* Current number of oplocks we have outstanding. */ int32_t exclusive_oplocks_open = 0; int32_t level_II_oplocks_open = 0; bool global_client_failed_oplock_break = false; -const struct kernel_oplocks *koplocks = NULL; +struct kernel_oplocks *koplocks = NULL; struct notify_mid_map *notify_changes_by_mid = NULL; @@ -215,9 +208,5 @@ void smbd_init_globals(void) #if HAVE_KERNEL_OPLOCKS_LINUX ZERO_STRUCT(fd_pending_array); - ZERO_STRUCT(linux_koplocks); -#endif -#if HAVE_KERNEL_OPLOCKS_IRIX - ZERO_STRUCT(irix_koplocks); #endif } diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 157089f37c..2c4f8b5821 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -188,20 +188,13 @@ extern char *LastDir; extern SIG_ATOMIC_T oplock_signals_received; #define FD_PENDING_SIZE 100 extern SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE]; -extern struct kernel_oplocks linux_koplocks; -#endif - -#if HAVE_KERNEL_OPLOCKS_IRIX -extern int oplock_pipe_write; -extern int oplock_pipe_read; -extern struct kernel_oplocks irix_koplocks; #endif /* Current number of oplocks we have outstanding. */ extern int32_t exclusive_oplocks_open; extern int32_t level_II_oplocks_open; extern bool global_client_failed_oplock_break; -extern const struct kernel_oplocks *koplocks; +extern struct kernel_oplocks *koplocks; extern struct notify_mid_map *notify_changes_by_mid; diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 3fd5afef22..e4b5016538 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -36,9 +36,9 @@ int32 get_number_of_exclusive_open_oplocks(void) Return True if an oplock message is pending. ****************************************************************************/ -bool oplock_message_waiting(fd_set *fds) +bool oplock_message_waiting(void) { - if (koplocks && koplocks->msg_waiting(fds)) { + if (koplocks && koplocks->ops->msg_waiting(koplocks)) { return True; } @@ -52,7 +52,7 @@ bool oplock_message_waiting(fd_set *fds) we're calling this in a shutting down state. ****************************************************************************/ -void process_kernel_oplocks(struct messaging_context *msg_ctx, fd_set *pfds) +void process_kernel_oplocks(struct messaging_context *msg_ctx) { /* * We need to check for kernel oplocks before going into the select @@ -64,11 +64,11 @@ void process_kernel_oplocks(struct messaging_context *msg_ctx, fd_set *pfds) return; } - while (koplocks->msg_waiting(pfds)) { + while (koplocks->ops->msg_waiting(koplocks)) { files_struct *fsp; char msg[MSG_SMB_KERNEL_BREAK_SIZE]; - fsp = koplocks->receive_message(pfds); + fsp = koplocks->ops->receive_message(koplocks); if (fsp == NULL) { DEBUG(3, ("Kernel oplock message announced, but none " @@ -99,7 +99,7 @@ bool set_file_oplock(files_struct *fsp, int oplock_type) if ((fsp->oplock_type != NO_OPLOCK) && (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && koplocks && - !koplocks->set_oplock(fsp, oplock_type)) { + !koplocks->ops->set_oplock(koplocks, fsp, oplock_type)) { return False; } @@ -129,7 +129,7 @@ void release_file_oplock(files_struct *fsp) if ((fsp->oplock_type != NO_OPLOCK) && (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && koplocks) { - koplocks->release_oplock(fsp); + koplocks->ops->release_oplock(koplocks, fsp); } if (fsp->oplock_type == LEVEL_II_OPLOCK) { @@ -161,7 +161,7 @@ void release_file_oplock(files_struct *fsp) static void downgrade_file_oplock(files_struct *fsp) { if (koplocks) { - koplocks->release_oplock(fsp); + koplocks->ops->release_oplock(koplocks, fsp); } fsp->oplock_type = LEVEL_II_OPLOCK; exclusive_oplocks_open--; @@ -226,19 +226,6 @@ bool downgrade_oplock(files_struct *fsp) return ret; } -/**************************************************************************** - Return the fd (if any) used for receiving oplock notifications. -****************************************************************************/ - -int oplock_notify_fd(void) -{ - if (koplocks) { - return koplocks->notification_fd; - } - - return -1; -} - /**************************************************************************** Set up an oplock break message. ****************************************************************************/ @@ -914,9 +901,9 @@ bool init_oplocks(struct messaging_context *msg_ctx) if (lp_kernel_oplocks()) { #if HAVE_KERNEL_OPLOCKS_IRIX - koplocks = irix_init_kernel_oplocks(); + koplocks = irix_init_kernel_oplocks(talloc_autofree_context()); #elif HAVE_KERNEL_OPLOCKS_LINUX - koplocks = linux_init_kernel_oplocks(); + koplocks = linux_init_kernel_oplocks(talloc_autofree_context()); #endif } diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c index 496b0b72ea..0cfa960425 100644 --- a/source3/smbd/oplock_irix.c +++ b/source3/smbd/oplock_irix.c @@ -23,6 +23,14 @@ #if HAVE_KERNEL_OPLOCKS_IRIX +struct irix_oplocks_context { + struct kernel_oplocks *ctx; + int write_fd; + int read_fd; + struct fd_event *read_fde; + bool pending; +}; + /**************************************************************************** Test to see if IRIX kernel oplocks work. ****************************************************************************/ @@ -100,22 +108,27 @@ static bool irix_oplocks_available(void) * oplock break protocol. ****************************************************************************/ -static files_struct *irix_oplock_receive_message(fd_set *fds) +static files_struct *irix_oplock_receive_message(struct kernel_oplocks *_ctx) { + struct irix_oplocks_context *ctx = talloc_get_type(_ctx->private_data, + struct irix_oplocks_context); oplock_stat_t os; char dummy; struct file_id fileid; files_struct *fsp; - /* Ensure we only get one call per select fd set. */ - FD_CLR(oplock_pipe_read, fds); + /* + * TODO: is it correct to assume we only get one + * oplock break, for each byte we read from the pipe? + */ + ctx->pending = false; /* * Read one byte of zero to clear the * kernel break notify message. */ - if(read(oplock_pipe_read, &dummy, 1) != 1) { + if(read(ctx->read_fd, &dummy, 1) != 1) { DEBUG(0,("irix_oplock_receive_message: read of kernel " "notification failed. Error was %s.\n", strerror(errno) )); @@ -128,7 +141,7 @@ static files_struct *irix_oplock_receive_message(fd_set *fds) * request outstanding. */ - if(sys_fcntl_ptr(oplock_pipe_read, F_OPLKSTAT, &os) < 0) { + if(sys_fcntl_ptr(ctx->read_fd, F_OPLKSTAT, &os) < 0) { DEBUG(0,("irix_oplock_receive_message: fcntl of kernel " "notification failed. Error was %s.\n", strerror(errno) )); @@ -170,9 +183,13 @@ static files_struct *irix_oplock_receive_message(fd_set *fds) Attempt to set an kernel oplock on a file. ****************************************************************************/ -static bool irix_set_kernel_oplock(files_struct *fsp, int oplock_type) +static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx, + files_struct *fsp, int oplock_type) { - if (sys_fcntl_long(fsp->fh->fd, F_OPLKREG, oplock_pipe_write) == -1) { + struct irix_oplocks_context *ctx = talloc_get_type(_ctx->private_data, + struct irix_oplocks_context); + + if (sys_fcntl_long(fsp->fh->fd, F_OPLKREG, ctx->write_fd) == -1) { if(errno != EAGAIN) { DEBUG(0,("irix_set_kernel_oplock: Unable to get " "kernel oplock on file %s, file_id %s " @@ -204,7 +221,8 @@ static bool irix_set_kernel_oplock(files_struct *fsp, int oplock_type) Release a kernel oplock on a file. ****************************************************************************/ -static void irix_release_kernel_oplock(files_struct *fsp) +static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx, + files_struct *fsp) { if (DEBUGLVL(10)) { /* @@ -234,63 +252,77 @@ static void irix_release_kernel_oplock(files_struct *fsp) } } -/**************************************************************************** - See if there is a message waiting in this fd set. - Note that fds MAY BE NULL ! If so we must do our own select. -****************************************************************************/ - -static bool irix_oplock_msg_waiting(fd_set *fds) +static bool irix_oplock_msg_waiting(struct kernel_oplocks *_ctx) { - int selrtn; - fd_set myfds; - struct timeval to; - - if (oplock_pipe_read == -1) - return False; - - if (fds) { - return FD_ISSET(oplock_pipe_read, fds); - } - - /* Do a zero-time select. We just need to find out if there - * are any outstanding messages. We use sys_select_intr as - * we need to ignore any signals. */ + struct irix_oplocks_context *ctx = talloc_get_type(_ctx->private_data, + struct irix_oplocks_context); + return ctx->pending; +} - FD_ZERO(&myfds); - FD_SET(oplock_pipe_read, &myfds); +static void irix_oplocks_read_fde_handler(struct event_context *ev, + struct fd_event *fde, + uint16_t flags, + void *private_data) +{ + struct irix_oplocks_context *ctx = talloc_get_type(private_data, + struct irix_oplocks_context); - to = timeval_set(0, 0); - selrtn = sys_select_intr(oplock_pipe_read+1,&myfds,NULL,NULL,&to); - return (selrtn == 1) ? True : False; + ctx->pending = true; + process_kernel_oplocks(smbd_messaging_context()); + ctx->pending = false; } /**************************************************************************** Setup kernel oplocks. ****************************************************************************/ -struct kernel_oplocks *irix_init_kernel_oplocks(void) +static const struct kernel_oplocks_ops irix_koplocks = { + .receive_message = irix_oplock_receive_message, + .set_oplock = irix_set_kernel_oplock, + .release_oplock = irix_release_kernel_oplock, + .msg_waiting = irix_oplock_msg_waiting +}; + +struct kernel_oplocks *irix_init_kernel_oplocks(TALLOC_CTX *mem_ctx) { + struct kernel_oplocks *_ctx; + struct irix_oplocks_context *ctx; int pfd[2]; if (!irix_oplocks_available()) return NULL; + _ctx = talloc_zero(mem_ctx, struct kernel_oplocks); + if (!_ctx) { + return NULL; + } + + ctx = talloc_zero(_ctx, struct irix_oplocks_context); + if (!ctx) { + talloc_free(_ctx); + return NULL; + } + _ctx->ops = &irix_koplocks; + _ctx->private_data = ctx; + ctx->ctx = _ctx; + if(pipe(pfd) != 0) { + talloc_free(_ctx); 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]; - - irix_koplocks.receive_message = irix_oplock_receive_message; - irix_koplocks.set_oplock = irix_set_kernel_oplock; - irix_koplocks.release_oplock = irix_release_kernel_oplock; - irix_koplocks.msg_waiting = irix_oplock_msg_waiting; - irix_koplocks.notification_fd = oplock_pipe_read; + ctx->read_fd = pfd[0]; + ctx->write_fd = pfd[1]; - return &irix_koplocks; + ctx->read_fde = event_add_fd(smbd_event_context(), + ctx, + ctx->read_fd, + EVENT_FD_READ, + irix_oplocks_read_fde_handler, + ctx); + return _ctx; } #else void oplock_irix_dummy(void); diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index cb37a81fb9..8087167ff4 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -101,7 +101,7 @@ int linux_setlease(int fd, int leasetype) * oplock break protocol. ****************************************************************************/ -static files_struct *linux_oplock_receive_message(fd_set *fds) +static files_struct *linux_oplock_receive_message(struct kernel_oplocks *ctx) { int fd; files_struct *fsp; @@ -125,7 +125,8 @@ static files_struct *linux_oplock_receive_message(fd_set *fds) Attempt to set an kernel oplock on a file. ****************************************************************************/ -static bool linux_set_kernel_oplock(files_struct *fsp, int oplock_type) +static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx, + files_struct *fsp, int oplock_type) { if ( SMB_VFS_LINUX_SETLEASE(fsp, F_WRLCK) == -1) { DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, " @@ -148,7 +149,8 @@ static bool linux_set_kernel_oplock(files_struct *fsp, int oplock_type) Release a kernel oplock on a file. ****************************************************************************/ -static void linux_release_kernel_oplock(files_struct *fsp) +static void linux_release_kernel_oplock(struct kernel_oplocks *ctx, + files_struct *fsp) { if (DEBUGLVL(10)) { /* @@ -181,7 +183,7 @@ static void linux_release_kernel_oplock(files_struct *fsp) See if a oplock message is waiting. ****************************************************************************/ -static bool linux_oplock_msg_waiting(fd_set *fds) +static bool linux_oplock_msg_waiting(struct kernel_oplocks *ctx) { return oplock_signals_received != 0; } @@ -205,15 +207,31 @@ static bool linux_oplocks_available(void) Setup kernel oplocks. ****************************************************************************/ -struct kernel_oplocks *linux_init_kernel_oplocks(void) +static const struct kernel_oplocks_ops linux_koplocks = { + .receive_message = linux_oplock_receive_message, + .set_oplock = linux_set_kernel_oplock, + .release_oplock = linux_release_kernel_oplock, + .msg_waiting = linux_oplock_msg_waiting +}; + +struct kernel_oplocks *linux_init_kernel_oplocks(TALLOC_CTX *mem_ctx) { struct sigaction act; + struct kernel_oplocks *ctx; if (!linux_oplocks_available()) { DEBUG(3,("Linux kernel oplocks not available\n")); return NULL; } + ctx = talloc_zero(mem_ctx, struct kernel_oplocks); + if (!ctx) { + DEBUG(0,("Linux Kernel oplocks talloc_Zero failed\n")); + return NULL; + } + + ctx->ops = &linux_koplocks; + ZERO_STRUCT(act); act.sa_handler = NULL; @@ -225,18 +243,12 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void) return NULL; } - linux_koplocks.receive_message = linux_oplock_receive_message; - linux_koplocks.set_oplock = linux_set_kernel_oplock; - linux_koplocks.release_oplock = linux_release_kernel_oplock; - linux_koplocks.msg_waiting = linux_oplock_msg_waiting; - linux_koplocks.notification_fd = -1; - /* the signal can start off blocked due to a bug in bash */ BlockSignals(False, RT_SIGNAL_LEASE); DEBUG(3,("Linux kernel oplocks enabled\n")); - return &linux_koplocks; + return ctx; } #else void oplock_linux_dummy(void); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 7847505f7c..78e66e4620 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -700,13 +700,13 @@ struct idle_event *event_add_idle(struct event_context *event_ctx, notify events etc. ****************************************************************************/ -static void async_processing(fd_set *pfds) +static void async_processing(void) { DEBUG(10,("async_processing: Doing async processing.\n")); process_aio_queue(); - process_kernel_oplocks(smbd_messaging_context(), pfds); + process_kernel_oplocks(smbd_messaging_context()); /* Do the aio check again after receive_local_message as it does a select and may have eaten our signal. */ @@ -726,20 +726,6 @@ static void async_processing(fd_set *pfds) } } -/**************************************************************************** - Add a fd to the set we will be select(2)ing on. -****************************************************************************/ - -static int select_on_fd(int fd, int maxfd, fd_set *fds) -{ - if (fd != -1) { - FD_SET(fd, fds); - maxfd = MAX(maxfd, fd); - } - - return maxfd; -} - /**************************************************************************** Do a select on an two fd's - with timeout. @@ -794,9 +780,9 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection * * This is hideously complex - *MUST* be simplified for 3.0 ! JRA. */ - if (oplock_message_waiting(&r_fds)) { + if (oplock_message_waiting()) { DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n")); - async_processing(&r_fds); + async_processing(); /* * After async processing we must go and do the select again, as * the state of the flag in fds for the server file descriptor is @@ -827,8 +813,6 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection * int sav; START_PROFILE(smbd_idle); - maxfd = select_on_fd(oplock_notify_fd(), maxfd, &r_fds); - selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to); sav = errno; @@ -845,7 +829,7 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection * is the best we can do until the oplock code knows more about signals */ if (selrtn == -1 && errno == EINTR) { - async_processing(&r_fds); + async_processing(); /* * After async processing we must go and do the select again, as * the state of the flag in fds for the server file descriptor is @@ -865,22 +849,6 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection * return NT_STATUS_RETRY; } - /* - * Ensure we process oplock break messages by preference. - * This is IMPORTANT ! Otherwise we can starve other processes - * sending us an oplock break message. JRA. - */ - - if (oplock_message_waiting(&r_fds)) { - async_processing(&r_fds); - /* - * After async processing we must go and do the select again, as - * the state of the flag in fds for the server file descriptor is - * indeterminate - we may have done I/O on it in the oplock processing. JRA. - */ - return NT_STATUS_RETRY; - } - /* * We've just woken up from a protentially long select sleep. * Ensure we process local messages as we need to synchronously @@ -935,7 +903,7 @@ void respond_to_all_remaining_local_messages(void) return; } - process_kernel_oplocks(smbd_messaging_context(), NULL); + process_kernel_oplocks(smbd_messaging_context()); return; } -- cgit From f029b2b05872f6cfe214241a614081f81c43c7bd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Jan 2009 18:14:04 +0100 Subject: s3:messaging: start with to use signal events instead of the raw signal interfaces metze --- source3/lib/messages_local.c | 102 +++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 37 deletions(-) (limited to 'source3') diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c index 9f7f88f783..636e70ced6 100644 --- a/source3/lib/messages_local.c +++ b/source3/lib/messages_local.c @@ -46,28 +46,32 @@ #include "librpc/gen_ndr/messaging.h" #include "librpc/gen_ndr/ndr_messaging.h" -static sig_atomic_t received_signal; +struct messaging_tdb_context { + struct messaging_context *msg_ctx; + struct tdb_wrap *tdb; + struct tevent_signal *se; + int received_messages; +}; static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx, struct server_id pid, int msg_type, const DATA_BLOB *data, struct messaging_backend *backend); -/**************************************************************************** - Notifications come in as signals. -****************************************************************************/ - -static void sig_usr1(void) +static void messaging_tdb_signal_handler(struct tevent_context *ev_ctx, + struct tevent_signal *se, + int signum, int count, + void *_info, void *private_data) { - received_signal = 1; - sys_select_signal(SIGUSR1); -} + struct messaging_tdb_context *ctx = talloc_get_type(private_data, + struct messaging_tdb_context); -static int messaging_tdb_destructor(struct messaging_backend *tdb_ctx) -{ - struct tdb_wrap *tdb = (struct tdb_wrap *)tdb_ctx->private_data; - TALLOC_FREE(tdb); - return 0; + ctx->received_messages++; + + DEBUG(10, ("messaging_tdb_signal_handler: sig[%d] count[%d] msgs[%d]\n", + signum, count, ctx->received_messages)); + + message_dispatch(ctx->msg_ctx); } /**************************************************************************** @@ -79,18 +83,29 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx, struct messaging_backend **presult) { struct messaging_backend *result; - struct tdb_wrap *tdb; + struct messaging_tdb_context *ctx; if (!(result = TALLOC_P(mem_ctx, struct messaging_backend))) { DEBUG(0, ("talloc failed\n")); return NT_STATUS_NO_MEMORY; } - tdb = tdb_wrap_open(result, lock_path("messages.tdb"), - 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR|O_CREAT,0600); + ctx = TALLOC_ZERO_P(result, struct messaging_tdb_context); + if (!ctx) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + result->private_data = ctx; + result->send_fn = messaging_tdb_send; + + ctx->msg_ctx = msg_ctx; + + ctx->tdb = tdb_wrap_open(ctx, lock_path("messages.tdb"), + 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR|O_CREAT,0600); - if (!tdb) { + if (!ctx->tdb) { NTSTATUS status = map_nt_error_from_unix(errno); DEBUG(0, ("ERROR: Failed to initialise messages database: " "%s\n", strerror(errno))); @@ -98,17 +113,23 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx, return status; } + ctx->se = tevent_add_signal(msg_ctx->event_ctx, + ctx, + SIGUSR1, 0, + messaging_tdb_signal_handler, + ctx); + if (!ctx->se) { + NTSTATUS status = map_nt_error_from_unix(errno); + DEBUG(0, ("ERROR: Failed to initialise messages signal handler: " + "%s\n", strerror(errno))); + TALLOC_FREE(result); + return status; + } + sec_init(); /* Activate the per-hashchain freelist */ - tdb_set_max_dead(tdb->tdb, 5); - - CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1); - - result->private_data = (void *)tdb; - result->send_fn = messaging_tdb_send; - - talloc_set_destructor(result, messaging_tdb_destructor); + tdb_set_max_dead(ctx->tdb->tdb, 5); *presult = result; return NT_STATUS_OK; @@ -289,11 +310,13 @@ static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx, const DATA_BLOB *data, struct messaging_backend *backend) { + struct messaging_tdb_context *ctx = talloc_get_type(backend->private_data, + struct messaging_tdb_context); struct messaging_array *msg_array; struct messaging_rec *rec; NTSTATUS status; TDB_DATA key; - struct tdb_wrap *tdb = (struct tdb_wrap *)backend->private_data; + struct tdb_wrap *tdb = ctx->tdb; TALLOC_CTX *frame = talloc_stackframe(); /* NULL pointer means implicit length zero. */ @@ -408,24 +431,29 @@ static NTSTATUS retrieve_all_messages(TDB_CONTEXT *msg_tdb, void message_dispatch(struct messaging_context *msg_ctx) { + struct messaging_tdb_context *ctx = talloc_get_type(msg_ctx->local->private_data, + struct messaging_tdb_context); struct messaging_array *msg_array = NULL; - struct tdb_wrap *tdb = (struct tdb_wrap *) - (msg_ctx->local->private_data); + struct tdb_wrap *tdb = ctx->tdb; + NTSTATUS status; uint32 i; - if (!received_signal) + if (ctx->received_messages == 0) { return; + } - DEBUG(10, ("message_dispatch: received_signal = %d\n", - received_signal)); - - received_signal = 0; + DEBUG(10, ("message_dispatch: received_messages = %d\n", + ctx->received_messages)); - if (!NT_STATUS_IS_OK(retrieve_all_messages(tdb->tdb, NULL, - &msg_array))) { + status = retrieve_all_messages(tdb->tdb, NULL, &msg_array); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("message_dispatch: failed to retrieve messages: %s\n", + nt_errstr(status))); return; } + ctx->received_messages = 0; + for (i=0; inum_messages; i++) { messaging_dispatch_rec(msg_ctx, &msg_array->messages[i]); } -- cgit From c44a0ae87aef333570ce588fc9b46392dd528030 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:30:13 +0100 Subject: s3:smbcontrol: don't call message_dispatch() anymore, it's triggered by tevent_loop_once() metze --- source3/utils/smbcontrol.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index b139ed7400..6ea200bfec 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -65,10 +65,10 @@ static bool send_message(struct messaging_context *msg_ctx, return ret; } -static void smbcontrol_timeout(struct event_context *event_ctx, - struct timed_event *te, - struct timeval now, - void *private_data) +static void smbcontrol_timeout(struct tevent_context *event_ctx, + struct tevent_timer *te, + struct timeval now, + void *private_data) { bool *timed_out = (bool *)private_data; TALLOC_FREE(te); @@ -80,21 +80,24 @@ static void smbcontrol_timeout(struct event_context *event_ctx, static void wait_replies(struct messaging_context *msg_ctx, bool multiple_replies) { - struct timed_event *te; + struct tevent_timer *te; bool timed_out = False; - if (!(te = event_add_timed(messaging_event_context(msg_ctx), NULL, - timeval_current_ofs(timeout, 0), - smbcontrol_timeout, (void *)&timed_out))) { - DEBUG(0, ("event_add_timed failed\n")); + if (!(te = tevent_add_timer(messaging_event_context(msg_ctx), NULL, + timeval_current_ofs(timeout, 0), + smbcontrol_timeout, (void *)&timed_out))) { + DEBUG(0, ("tevent_add_timer failed\n")); return; } while (!timed_out) { - message_dispatch(msg_ctx); + int ret; if (num_replies > 0 && !multiple_replies) break; - event_loop_once(messaging_event_context(msg_ctx)); + ret = tevent_loop_once(messaging_event_context(msg_ctx)); + if (ret != 0) { + break; + } } } @@ -1324,7 +1327,7 @@ int main(int argc, const char **argv) { poptContext pc; int opt; - struct event_context *evt_ctx; + struct tevent_context *evt_ctx; struct messaging_context *msg_ctx; static struct poptOption long_options[] = { @@ -1387,7 +1390,7 @@ int main(int argc, const char **argv) * routines mostly return True==1 for success, but * shell needs 0. */ - if (!(evt_ctx = event_context_init(NULL)) || + if (!(evt_ctx = tevent_context_init(NULL)) || !(msg_ctx = messaging_init(NULL, server_id_self(), evt_ctx))) { fprintf(stderr, "could not init messaging context\n"); TALLOC_FREE(frame); -- cgit From a4d605344bcd16d01b7049c477d99f8d9841f13c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:31:33 +0100 Subject: s3:msgtest: don't call message_dispatch() anymore, use tevent_loop_once() instead metze --- source3/torture/msgtest.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'source3') diff --git a/source3/torture/msgtest.c b/source3/torture/msgtest.c index 1bb616f6e1..c447ac63d0 100644 --- a/source3/torture/msgtest.c +++ b/source3/torture/msgtest.c @@ -39,11 +39,12 @@ static void pong_message(struct messaging_context *msg_ctx, int main(int argc, char *argv[]) { - struct event_context *evt_ctx; + struct tevent_context *evt_ctx; struct messaging_context *msg_ctx; pid_t pid; int i, n; char buf[12]; + int ret; load_case_tables(); @@ -51,7 +52,7 @@ static void pong_message(struct messaging_context *msg_ctx, lp_load(get_dyn_CONFIGFILE(),False,False,False,True); - if (!(evt_ctx = event_context_init(NULL)) || + if (!(evt_ctx = tevent_context_init(NULL)) || !(msg_ctx = messaging_init(NULL, server_id_self(), evt_ctx))) { fprintf(stderr, "could not init messaging context\n"); exit(1); @@ -74,8 +75,10 @@ static void pong_message(struct messaging_context *msg_ctx, } while (pong_count < i) { - message_dispatch(msg_ctx); - smb_msleep(1); + ret = tevent_loop_once(evt_ctx); + if (ret != 0) { + break; + } } /* Now test that the duplicate filtering code works. */ @@ -91,8 +94,10 @@ static void pong_message(struct messaging_context *msg_ctx, } for (i=0;i pong_count + 20) { - message_dispatch(msg_ctx); + ret = tevent_loop_once(evt_ctx); + if (ret != 0) { + break; + } } } printf("waiting for %d remaining replies (done %d)\n", (int)(ping_count - pong_count), pong_count); while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) { - message_dispatch(msg_ctx); + ret = tevent_loop_once(evt_ctx); + if (ret != 0) { + break; + } } if (ping_count != pong_count) { -- cgit From 830b31a41aeadf6b688c5f60f114f6137ea13afb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:33:19 +0100 Subject: s3:smbd: we don't need to call message_dispatch() anymore it's event triggered now metze --- source3/smbd/process.c | 25 ++----------------------- source3/smbd/server.c | 3 --- 2 files changed, 2 insertions(+), 26 deletions(-) (limited to 'source3') diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 78e66e4620..dc038b6b95 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -407,9 +407,6 @@ static void smbd_deferred_open_timer(struct event_context *ev, TALLOC_CTX *mem_ctx = talloc_tos(); uint8_t *inbuf; - /* TODO: remove this hack */ - message_dispatch(smbd_messaging_context()); - inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data, msg->buf.length); if (inbuf == NULL) { @@ -757,13 +754,6 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection * to.tv_sec = SMBD_SELECT_TIMEOUT; to.tv_usec = 0; - /* - * Note that this call must be before processing any SMB - * messages as we need to synchronously process any messages - * we may have sent to ourselves from the previous SMB. - */ - message_dispatch(smbd_messaging_context()); - /* * Setup the select fd sets. */ @@ -849,16 +839,8 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection * return NT_STATUS_RETRY; } - /* - * We've just woken up from a protentially long select sleep. - * Ensure we process local messages as we need to synchronously - * process any messages from other smbd's to avoid file rename race - * conditions. This call is cheap if there are no messages waiting. - * JRA. - */ - message_dispatch(smbd_messaging_context()); - - return NT_STATUS_OK; + /* should not be reached */ + return NT_STATUS_INTERNAL_ERROR; } /* @@ -1874,9 +1856,6 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c TALLOC_CTX *mem_ctx = talloc_tos(); NTSTATUS status; - /* TODO: remove this hack */ - message_dispatch(smbd_messaging_context()); - /* TODO: make this completely nonblocking */ status = receive_smb_talloc(mem_ctx, smbd_server_fd(), diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 163d0b81be..505763014e 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -573,9 +573,6 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ fd_set r_fds, w_fds; int num; - /* Ensure we respond to PING and DEBUG messages from the main smbd. */ - message_dispatch(smbd_messaging_context()); - if (got_sig_cld) { pid_t pid; int status; -- cgit From 4d413381a2496a4d73e4d406efbfd68c28fee3b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:34:49 +0100 Subject: s3:nmbd: we don't need to call message_dispatch() anymore it's event triggered now metze --- source3/nmbd/nmbd.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3') diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 10d6fe2378..0922e455a3 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -441,10 +441,6 @@ static void process(void) time_t t = time(NULL); TALLOC_CTX *frame = talloc_stackframe(); - /* Check for internal messages */ - - message_dispatch(nmbd_messaging_context()); - /* * Check all broadcast subnets to see if * we need to run an election on any of them. -- cgit From cf53e48fecf2a4410ff641eb6e0edd8578cccb15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:35:07 +0100 Subject: s3:winbindd: we don't need to call message_dispatch() anymore it's event triggered now metze --- source3/winbindd/winbindd.c | 6 ------ source3/winbindd/winbindd_dual.c | 4 ---- 2 files changed, 10 deletions(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 0bdc75ccd4..fad27ea224 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -840,12 +840,6 @@ static void process_loop(void) exit(1); } - /* We'll be doing this a lot */ - - /* Handle messages */ - - message_dispatch(winbind_messaging_context()); - run_events(winbind_event_context(), 0, NULL, NULL); /* refresh the trusted domain cache */ diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 2a85f6e0d4..c320e96746 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1384,10 +1384,6 @@ static bool fork_domain_child(struct winbindd_child *child) winbind_check_sighup(override_logfile ? NULL : child->logfilename); - /* Handle messages */ - - message_dispatch(winbind_messaging_context()); - if (run_events(winbind_event_context(), 0, NULL, NULL)) { TALLOC_FREE(frame); continue; -- cgit From 7a07fcdc1e1f01483ae9d509a9d42eea4d454529 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:37:07 +0100 Subject: s3:printing: handle tevent_context events in the sys_select() call metze --- source3/printing/printing.c | 58 ++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'source3') diff --git a/source3/printing/printing.c b/source3/printing/printing.c index fffe9178cf..bb29380007 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1439,15 +1439,47 @@ void start_background_queue(void) DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n")); while (1) { - fd_set pause_fds; - int pause_select; + fd_set r_fds, w_fds; + int ret; + struct timeval to; + int maxfd = 0; - FD_ZERO(&pause_fds); - FD_SET(pause_pipe[1], &pause_fds); - pause_select = sys_select(pause_pipe[1]+1, &pause_fds, NULL, NULL, NULL); - /* If pause_pipe[0] is closed it means the parent smbd + /* Process a signal and timed events now... */ + if (run_events(smbd_event_context(), 0, NULL, NULL)) { + continue; + } + + to.tv_sec = SMBD_SELECT_TIMEOUT; + to.tv_usec = 0; + + /* + * Setup the select fd sets. + */ + + FD_ZERO(&r_fds); + FD_ZERO(&w_fds); + + /* + * Are there any timed events waiting ? If so, ensure we don't + * select for longer than it would take to wait for them. + */ + + { + struct timeval now; + GetTimeOfDay(&now); + + event_add_to_select_args(smbd_event_context(), &now, + &r_fds, &w_fds, &to, &maxfd); + } + + FD_SET(pause_pipe[1], &r_fds); + maxfd = MAX(pause_pipe[1], maxfd); + + ret = sys_select(maxfd, &r_fds, &w_fds, NULL, &to); + + /* If pause_pipe[1] is closed it means the parent smbd * and children exited or aborted. */ - if (pause_select == 1) { + if (ret == 1 && FD_ISSET(pause_pipe[1], &r_fds)) { exit_server_cleanly(NULL); } @@ -1464,15 +1496,9 @@ void start_background_queue(void) reload_after_sighup = 0; } - /* now check for messages */ - - DEBUG(10,("start_background_queue: background LPQ thread got a message\n")); - message_dispatch(smbd_messaging_context()); - - /* process any pending print change notify messages */ - - print_notify_send_messages(smbd_messaging_context(), - 0); + if (run_events(smbd_event_context(), ret, &r_fds, &w_fds)) { + continue; + } } } -- cgit From 240762aefe1af16d56a0a1bc4880702a006fe050 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:39:56 +0100 Subject: s3:messages: finally make message_dispatch() static metze --- source3/include/messages.h | 1 - source3/lib/messages_local.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/include/messages.h b/source3/include/messages.h index 785f116e1c..2e42fc6554 100644 --- a/source3/include/messages.h +++ b/source3/include/messages.h @@ -109,7 +109,6 @@ struct messaging_backend { NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx, struct messaging_backend **presult); -void message_dispatch(struct messaging_context *msg_ctx); NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx, diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c index 636e70ced6..be848ac8ba 100644 --- a/source3/lib/messages_local.c +++ b/source3/lib/messages_local.c @@ -57,6 +57,7 @@ static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx, struct server_id pid, int msg_type, const DATA_BLOB *data, struct messaging_backend *backend); +static void message_dispatch(struct messaging_context *msg_ctx); static void messaging_tdb_signal_handler(struct tevent_context *ev_ctx, struct tevent_signal *se, @@ -429,7 +430,7 @@ static NTSTATUS retrieve_all_messages(TDB_CONTEXT *msg_tdb, messages on an *odd* byte boundary. ****************************************************************************/ -void message_dispatch(struct messaging_context *msg_ctx) +static void message_dispatch(struct messaging_context *msg_ctx) { struct messaging_tdb_context *ctx = talloc_get_type(msg_ctx->local->private_data, struct messaging_tdb_context); -- cgit From c5e242b1a39f0bb26c8c922f25cf7b072e5e834c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 07:39:28 +0100 Subject: s3:printing: make some functions static and use tevent functions metze --- source3/include/proto.h | 2 -- source3/printing/notify.c | 20 ++++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 0c358a0429..40ced543ec 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4722,7 +4722,6 @@ bool parse_lpq_entry(enum printing_types printing_type,char *line, /* The following definitions come from printing/notify.c */ int print_queue_snum(const char *qname); -bool print_notify_messages_pending(void); void print_notify_send_messages(struct messaging_context *msg_ctx, unsigned int timeout); void notify_printer_status_byname(const char *sharename, uint32 status); @@ -4745,7 +4744,6 @@ void notify_printer_printername(int snum, char *printername); void notify_printer_port(int snum, char *port_name); void notify_printer_location(int snum, char *location); void notify_printer_byname( const char *printername, uint32 change, const char *value ); -bool print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list); /* The following definitions come from printing/nt_printing.c */ diff --git a/source3/printing/notify.c b/source3/printing/notify.c index 860a400d64..d478b86f91 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -34,7 +34,10 @@ static struct notify_queue { size_t buflen; } *notify_queue_head = NULL; -static struct timed_event *notify_event; +static struct tevent_timer *notify_event; + +static bool print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, + size_t *p_num_pids, pid_t **pp_pid_list); static bool create_send_ctx(void) { @@ -63,7 +66,7 @@ int print_queue_snum(const char *qname) Used to decide if we need a short select timeout. *******************************************************************/ -bool print_notify_messages_pending(void) +static bool print_notify_messages_pending(void) { return (notify_queue_head != NULL); } @@ -219,10 +222,10 @@ void print_notify_send_messages(struct messaging_context *msg_ctx, Event handler to send the messages. *******************************************************************/ -static void print_notify_event_send_messages(struct event_context *event_ctx, - struct timed_event *te, - struct timeval now, - void *private_data) +static void print_notify_event_send_messages(struct tevent_context *event_ctx, + struct tevent_timer *te, + struct timeval now, + void *private_data) { /* Remove this timed event handler. */ TALLOC_FREE(notify_event); @@ -324,7 +327,7 @@ to notify_queue_head\n", msg->type, msg->field, msg->printer)); if ((notify_event == NULL) && (smbd_event_context() != NULL)) { /* Add an event for 1 second's time to send this queue. */ - notify_event = event_add_timed(smbd_event_context(), NULL, + notify_event = tevent_add_timer(smbd_event_context(), NULL, timeval_current_ofs(1,0), print_notify_event_send_messages, NULL); } @@ -535,7 +538,8 @@ void notify_printer_byname( const char *printername, uint32 change, const char * messages on this print queue. Used in printing/notify to send the messages. ****************************************************************************/ -bool print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list) +static bool print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, + size_t *p_num_pids, pid_t **pp_pid_list) { struct tdb_print_db *pdb = NULL; TDB_CONTEXT *tdb = NULL; -- cgit From 031f24694197ab2c90418c5a5285a2932b71e998 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 22 Jan 2009 17:53:22 +0100 Subject: Fix a segfault: rpccli_* expect the reply_pdu to always be initialized --- source3/rpc_client/cli_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bf19160436..cf2c833c28 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2367,6 +2367,11 @@ NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx, NTSTATUS status; if (async_req_is_error(req, &status)) { + /* + * We always have to initialize to reply pdu, even if there is + * none. The rpccli_* caller routines expect this. + */ + prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL); return status; } -- cgit From 2d81c9e957a21191c5b4e2b28a4599052c1357a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 2009 10:57:10 -0800 Subject: Another attempt to fix bug #4308 - Excel save operation corrupts file ACLs. Simo is completely correct. We should be doing the chown *first*, and fail the ACL set if this fails. The long standing assumption I made when writing the initial POSIX ACL code was that Windows didn't control who could chown a file in the same was as POSIX. In POSIX only root can do this whereas I wasn't sure who could do this in Windows at the time (I didn't understand the privilege model). So the assumption was that setting the ACL was more important (early tests showed many failed ACL set's due to inability to chown). But now we have privileges in smbd, and we must always fail an ACL set when we can't chown first. The key that Simo noticed is that the CREATOR_OWNER bits in the ACL incoming are relative to the *new* owner, not the old one. This is why the old user owner disappears on ACL set - their access was set via the USER_OBJ in the creator POSIX ACL and when the ownership changes they lose their access. Patch is simple - just ensure we do the chown first before evaluating the incoming ACL re-read the owners. We already have code to do this it just wasn't rigorously being applied. Jeremy. --- source3/smbd/posix_acls.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) (limited to 'source3') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 8fe7a9abe9..951046c562 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3428,7 +3428,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC NTSTATUS status; uid_t orig_uid; gid_t orig_gid; - bool need_chown = False; DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); @@ -3464,14 +3463,12 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC } /* - * Do we need to chown ? + * Do we need to chown ? If so this must be done first as the incoming + * CREATOR_OWNER acl will be relative to the *new* owner, not the old. + * Noticed by Simo. */ if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) { - need_chown = True; - } - - if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); @@ -3511,9 +3508,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC orig_mode = sbuf.st_mode; orig_uid = sbuf.st_uid; orig_gid = sbuf.st_gid; - - /* We did chown already, drop the flag */ - need_chown = False; } create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); @@ -3664,24 +3658,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC } free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); + free_canon_ace_list(dir_ace_list); } - /* Any chown pending? */ - if (need_chown) { - DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", - fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); - - if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) { - DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) )); - if (errno == EPERM) { - return NT_STATUS_INVALID_OWNER; - } - return map_nt_error_from_unix(errno); - } - } - return NT_STATUS_OK; } -- cgit From 8e2b48e1b7c7fd6b6080f2e56f654b682c6426a3 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Thu, 22 Jan 2009 13:14:04 -0800 Subject: s3: Fix warning --- source3/include/proto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 40ced543ec..d55546f94c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7024,7 +7024,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn, /* The following definitions come from smbd/oplock.c */ int32 get_number_of_exclusive_open_oplocks(void); -bool oplock_message_waiting(); +bool oplock_message_waiting(void); void process_kernel_oplocks(struct messaging_context *msg_ctx); bool set_file_oplock(files_struct *fsp, int oplock_type); void release_file_oplock(files_struct *fsp); -- cgit