summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2001-10-10 15:14:37 +1000
committerDamien Miller <djm@mindrot.org>2001-10-10 15:14:37 +1000
commit52b77beb6560c409dfaaec6e61a8f2a2bf53d7d8 (patch)
tree361b15f34c99af10cafad3198d7727893c019b81
parentc71f4e40b6d8cdf1c0d83381945841e66c127a95 (diff)
- markus@cvs.openbsd.org 2001/10/09 21:59:41
[channels.c channels.h serverloop.c session.c session.h] simplify session close: no more delayed session_close, no more blocking wait() calls.
-rw-r--r--ChangeLog6
-rw-r--r--channels.c18
-rw-r--r--channels.h4
-rw-r--r--serverloop.c38
-rw-r--r--session.c44
-rw-r--r--session.h4
6 files changed, 45 insertions, 69 deletions
diff --git a/ChangeLog b/ChangeLog
index 2eda5e1b3..9fd4abbb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -44,6 +44,10 @@
44 [serverloop.c] 44 [serverloop.c]
45 close all channels if the connection to the remote host has been closed, 45 close all channels if the connection to the remote host has been closed,
46 should fix sshd's hanging with WCHAN==wait 46 should fix sshd's hanging with WCHAN==wait
47 - markus@cvs.openbsd.org 2001/10/09 21:59:41
48 [channels.c channels.h serverloop.c session.c session.h]
49 simplify session close: no more delayed session_close, no more
50 blocking wait() calls.
47 51
4820011007 5220011007
49 - (bal) ssh-copy-id corrected permissions for .ssh/ and authorized_keys. 53 - (bal) ssh-copy-id corrected permissions for .ssh/ and authorized_keys.
@@ -6689,4 +6693,4 @@
6689 - Wrote replacements for strlcpy and mkdtemp 6693 - Wrote replacements for strlcpy and mkdtemp
6690 - Released 1.0pre1 6694 - Released 1.0pre1
6691 6695
6692$Id: ChangeLog,v 1.1597 2001/10/10 05:08:36 djm Exp $ 6696$Id: ChangeLog,v 1.1598 2001/10/10 05:14:37 djm Exp $
diff --git a/channels.c b/channels.c
index aaa0ea579..04efd7287 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.138 2001/10/08 11:48:57 markus Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.139 2001/10/09 21:59:41 markus Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -359,22 +359,6 @@ channel_free_all(void)
359 channel_free(channels[i]); 359 channel_free(channels[i]);
360} 360}
361 361
362void
363channel_detach_all(void)
364{
365 int i;
366 Channel *c;
367
368 for (i = 0; i < channels_alloc; i++) {
369 c = channels[i];
370 if (c != NULL && c->detach_user != NULL) {
371 debug("channel_detach_all: channel %d", c->self);
372 c->detach_user(c->self, NULL);
373 c->detach_user = NULL;
374 }
375 }
376}
377
378/* 362/*
379 * Closes the sockets/fds of all channels. This is used to close extra file 363 * Closes the sockets/fds of all channels. This is used to close extra file
380 * descriptors after a fork. 364 * descriptors after a fork.
diff --git a/channels.h b/channels.h
index 49a9df9dd..090d2ca6e 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35/* RCSID("$OpenBSD: channels.h,v 1.48 2001/10/07 17:49:40 markus Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.49 2001/10/09 21:59:41 markus Exp $"); */
36 36
37#ifndef CHANNEL_H 37#ifndef CHANNEL_H
38#define CHANNEL_H 38#define CHANNEL_H
@@ -143,7 +143,6 @@ Channel *channel_new(char *, int, int, int, int, int, int, int, char *, int);
143void channel_set_fds(int, int, int, int, int, int); 143void channel_set_fds(int, int, int, int, int, int);
144void channel_free(Channel *); 144void channel_free(Channel *);
145void channel_free_all(void); 145void channel_free_all(void);
146void channel_detach_all(void);
147void channel_stop_listening(void); 146void channel_stop_listening(void);
148 147
149void channel_send_open(int); 148void channel_send_open(int);
@@ -177,7 +176,6 @@ void channel_output_poll(void);
177 176
178int channel_not_very_much_buffered_data(void); 177int channel_not_very_much_buffered_data(void);
179void channel_close_all(void); 178void channel_close_all(void);
180void channel_free_all(void);
181int channel_still_open(void); 179int channel_still_open(void);
182char *channel_open_message(void); 180char *channel_open_message(void);
183int channel_find_open(void); 181int channel_find_open(void);
diff --git a/serverloop.c b/serverloop.c
index d7282fe2a..8a82af55b 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.80 2001/10/09 19:51:18 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.81 2001/10/09 21:59:41 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -674,6 +674,7 @@ server_loop2(Authctxt *authctxt)
674 fd_set *readset = NULL, *writeset = NULL; 674 fd_set *readset = NULL, *writeset = NULL;
675 int rekeying = 0, max_fd, status, nalloc = 0; 675 int rekeying = 0, max_fd, status, nalloc = 0;
676 pid_t pid; 676 pid_t pid;
677 sigset_t oset, nset;
677 678
678 debug("Entering interactive session for SSH2."); 679 debug("Entering interactive session for SSH2.");
679 680
@@ -696,12 +697,17 @@ server_loop2(Authctxt *authctxt)
696 channel_output_poll(); 697 channel_output_poll();
697 wait_until_can_do_something(&readset, &writeset, &max_fd, 698 wait_until_can_do_something(&readset, &writeset, &max_fd,
698 &nalloc, 0); 699 &nalloc, 0);
700
701 /* block SIGCHLD while we check for dead children */
702 sigemptyset(&nset);
703 sigaddset(&nset, SIGCHLD);
704 sigprocmask(SIG_BLOCK, &nset, &oset);
699 if (child_terminated) { 705 if (child_terminated) {
700 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) 706 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
701 session_close_by_pid(pid, status); 707 session_close_by_pid(pid, status);
702 /* XXX race */
703 child_terminated = 0; 708 child_terminated = 0;
704 } 709 }
710 sigprocmask(SIG_SETMASK, &oset, NULL);
705 if (!rekeying) 711 if (!rekeying)
706 channel_after_select(readset, writeset); 712 channel_after_select(readset, writeset);
707 process_input(readset); 713 process_input(readset);
@@ -709,35 +715,21 @@ server_loop2(Authctxt *authctxt)
709 break; 715 break;
710 process_output(writeset); 716 process_output(writeset);
711 } 717 }
712 /* close all channels, no more reads and writes */
713 channel_close_all();
714
715 if (readset) 718 if (readset)
716 xfree(readset); 719 xfree(readset);
717 if (writeset) 720 if (writeset)
718 xfree(writeset); 721 xfree(writeset);
719 722
720 mysignal(SIGCHLD, SIG_DFL); 723 /* free all channels, no more reads and writes */
724 channel_free_all();
721 725
722 /* collect dead children */ 726 /* collect remaining dead children, XXX not necessary? */
727 mysignal(SIGCHLD, SIG_DFL);
723 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) 728 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
724 session_close_by_pid(pid, status); 729 session_close_by_pid(pid, status);
725 /* 730
726 * there is a race between channel_detach_all() killing remaining 731 /* close remaining sessions, e.g remove wtmp entries */
727 * children and children dying before kill() 732 session_close_all();
728 */
729 channel_detach_all();
730
731 while (session_have_children()) {
732 pid = waitpid(-1, &status, 0);
733 if (pid > 0)
734 session_close_by_pid(pid, status);
735 else {
736 error("waitpid returned %d: %s", pid, strerror(errno));
737 break;
738 }
739 }
740 channel_free_all();
741} 733}
742 734
743static void 735static void
diff --git a/session.c b/session.c
index c1305da6a..0d6ebdaea 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.105 2001/10/09 19:32:49 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.106 2001/10/09 21:59:41 markus Exp $");
37 37
38#include "ssh.h" 38#include "ssh.h"
39#include "ssh1.h" 39#include "ssh1.h"
@@ -1949,22 +1949,6 @@ session_close_by_pid(pid_t pid, int status)
1949 session_close(s); 1949 session_close(s);
1950} 1950}
1951 1951
1952int
1953session_have_children(void)
1954{
1955 int i;
1956
1957 for(i = 0; i < MAX_SESSIONS; i++) {
1958 Session *s = &sessions[i];
1959 if (s->used && s->pid != -1) {
1960 debug("session_have_children: id %d pid %d", i, s->pid);
1961 return 1;
1962 }
1963 }
1964 debug("session_have_children: no more children");
1965 return 0;
1966}
1967
1968/* 1952/*
1969 * this is called when a channel dies before 1953 * this is called when a channel dies before
1970 * the session 'child' itself dies 1954 * the session 'child' itself dies
@@ -1982,15 +1966,29 @@ session_close_by_channel(int id, void *arg)
1982 s->chanid = -1; 1966 s->chanid = -1;
1983 1967
1984 debug("session_close_by_channel: channel %d kill %d", id, s->pid); 1968 debug("session_close_by_channel: channel %d kill %d", id, s->pid);
1985 if (s->pid == 0) { 1969 if (s->pid != 0) {
1986 /* close session immediately */ 1970 /* notify child */
1987 session_close(s); 1971 if (kill(s->pid, SIGHUP) < 0)
1988 } else {
1989 /* notify child, delay session cleanup */
1990 if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0)
1991 error("session_close_by_channel: kill %d: %s", 1972 error("session_close_by_channel: kill %d: %s",
1992 s->pid, strerror(errno)); 1973 s->pid, strerror(errno));
1993 } 1974 }
1975 session_close(s);
1976}
1977
1978void
1979session_close_all(void)
1980{
1981 int i;
1982 for(i = 0; i < MAX_SESSIONS; i++) {
1983 Session *s = &sessions[i];
1984 if (s->used) {
1985 if (s->chanid != -1) {
1986 channel_cancel_cleanup(s->chanid);
1987 s->chanid = -1;
1988 }
1989 session_close(s);
1990 }
1991 }
1994} 1992}
1995 1993
1996static char * 1994static char *
diff --git a/session.h b/session.h
index a04fa6f2b..d2b0d9364 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.h,v 1.11 2001/07/02 13:59:15 markus Exp $ */ 1/* $OpenBSD: session.h,v 1.12 2001/10/09 21:59:41 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -32,6 +32,6 @@ int session_open(Authctxt*, int);
32void session_input_channel_req(int, void *); 32void session_input_channel_req(int, void *);
33void session_close_by_pid(pid_t, int); 33void session_close_by_pid(pid_t, int);
34void session_close_by_channel(int, void *); 34void session_close_by_channel(int, void *);
35int session_have_children(void); 35void session_close_all(void);
36 36
37#endif 37#endif