diff options
author | Damien Miller <djm@mindrot.org> | 2001-10-10 15:14:37 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2001-10-10 15:14:37 +1000 |
commit | 52b77beb6560c409dfaaec6e61a8f2a2bf53d7d8 (patch) | |
tree | 361b15f34c99af10cafad3198d7727893c019b81 | |
parent | c71f4e40b6d8cdf1c0d83381945841e66c127a95 (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-- | ChangeLog | 6 | ||||
-rw-r--r-- | channels.c | 18 | ||||
-rw-r--r-- | channels.h | 4 | ||||
-rw-r--r-- | serverloop.c | 38 | ||||
-rw-r--r-- | session.c | 44 | ||||
-rw-r--r-- | session.h | 4 |
6 files changed, 45 insertions, 69 deletions
@@ -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 | ||
48 | 20011007 | 52 | 20011007 |
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" |
42 | RCSID("$OpenBSD: channels.c,v 1.138 2001/10/08 11:48:57 markus Exp $"); | 42 | RCSID("$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 | ||
362 | void | ||
363 | channel_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); | |||
143 | void channel_set_fds(int, int, int, int, int, int); | 143 | void channel_set_fds(int, int, int, int, int, int); |
144 | void channel_free(Channel *); | 144 | void channel_free(Channel *); |
145 | void channel_free_all(void); | 145 | void channel_free_all(void); |
146 | void channel_detach_all(void); | ||
147 | void channel_stop_listening(void); | 146 | void channel_stop_listening(void); |
148 | 147 | ||
149 | void channel_send_open(int); | 148 | void channel_send_open(int); |
@@ -177,7 +176,6 @@ void channel_output_poll(void); | |||
177 | 176 | ||
178 | int channel_not_very_much_buffered_data(void); | 177 | int channel_not_very_much_buffered_data(void); |
179 | void channel_close_all(void); | 178 | void channel_close_all(void); |
180 | void channel_free_all(void); | ||
181 | int channel_still_open(void); | 179 | int channel_still_open(void); |
182 | char *channel_open_message(void); | 180 | char *channel_open_message(void); |
183 | int channel_find_open(void); | 181 | int 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" |
38 | RCSID("$OpenBSD: serverloop.c,v 1.80 2001/10/09 19:51:18 markus Exp $"); | 38 | RCSID("$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 | ||
743 | static void | 735 | static void |
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.105 2001/10/09 19:32:49 markus Exp $"); | 36 | RCSID("$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 | ||
1952 | int | ||
1953 | session_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 | |||
1978 | void | ||
1979 | session_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 | ||
1996 | static char * | 1994 | static char * |
@@ -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); | |||
32 | void session_input_channel_req(int, void *); | 32 | void session_input_channel_req(int, void *); |
33 | void session_close_by_pid(pid_t, int); | 33 | void session_close_by_pid(pid_t, int); |
34 | void session_close_by_channel(int, void *); | 34 | void session_close_by_channel(int, void *); |
35 | int session_have_children(void); | 35 | void session_close_all(void); |
36 | 36 | ||
37 | #endif | 37 | #endif |