From: Bill Kendall <wkendall@sgi.com>
To: xfs@oss.sgi.com
Subject: [PATCH v2 4/7] xfsdump: rework dialog timeout and EINTR reliance
Date: Thu, 4 Aug 2011 17:30:08 -0500 [thread overview]
Message-ID: <1312497011-24840-5-git-send-email-wkendall@sgi.com> (raw)
In-Reply-To: <1312497011-24840-1-git-send-email-wkendall@sgi.com>
The current dialog code uses alarm(2) to implement the dialog timeout.
This is suboptimal as the main loop already makes use of alarm.
Additionally the existing code relies on its blocking read(2) being
interrupted if a signal is received. This is not guaranteed to work
as a signal may be delivered to a different thread.
Both of these issues can be resolved by using select(2) rather than
a blocking read.
This also changes dlog_desist() to not change 'dlog_ttyfd', as that
could impact a dialog already in progress. Clearing 'dlog_allowed_flag'
is sufficient to disable dialogs.
Signed-off-by: Bill Kendall <wkendall@sgi.com>
---
common/dlog.c | 57 +++++++++++++++++++++++++++++++++------------------------
1 files changed, 33 insertions(+), 24 deletions(-)
diff --git a/common/dlog.c b/common/dlog.c
index 6a243ef..cbaa5cb 100644
--- a/common/dlog.c
+++ b/common/dlog.c
@@ -20,6 +20,7 @@
#include <xfs/jdm.h>
#include <sys/stat.h>
+#include <sys/select.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
@@ -131,7 +132,6 @@ void
dlog_desist( void )
{
dlog_allowed_flag = BOOL_FALSE;
- dlog_ttyfd = -1;
}
intgen_t
@@ -373,13 +373,12 @@ promptinput( char *buf,
... )
{
va_list args;
- u_intgen_t alarm_save = 0;
- void (* sigalrm_save)(int) = NULL;
void (* sigint_save)(int) = NULL;
void (* sighup_save)(int) = NULL;
void (* sigterm_save)(int) = NULL;
void (* sigquit_save)(int) = NULL;
- intgen_t nread;
+ time32_t now = time( NULL );
+ intgen_t nread = -1;
pid_t pid = getpid( );
/* display the pre-prompt
@@ -399,16 +398,17 @@ promptinput( char *buf,
#endif /* NOTYET */
mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE, promptstr );
- /* set up signal handling
+ /* set up timeout
*/
- dlog_signo_received = -1;
if ( dlog_timeouts_flag && timeoutix != IXMAX ) {
- if ( pid == parentpid && ! miniroot ) {
- ( void )sigrelse( SIGALRM );
- }
- sigalrm_save = sigset( SIGALRM, sighandler );
- alarm_save = alarm( ( u_intgen_t )timeout );
+ timeout += now;
+ } else {
+ timeout = TIMEMAX;
}
+
+ /* set up signal handling
+ */
+ dlog_signo_received = -1;
if ( sigintix != IXMAX ) {
if ( pid == parentpid && ! miniroot ) {
( void )sigrelse( SIGINT );
@@ -432,10 +432,27 @@ promptinput( char *buf,
sigquit_save = sigset( SIGQUIT, sighandler );
}
- /* wait for input, timeout, or interrupt
+ /* wait for input, timeout, or interrupt.
+ * note we come out of the select() frequently in order to
+ * check for a signal. the signal may have been handled by the
+ * the main thread, so we can't rely on the signal waking us
+ * up from the select().
*/
- ASSERT( dlog_ttyfd >= 0 );
- nread = read( dlog_ttyfd, buf, bufsz - 1 );
+ while ( now < timeout && dlog_signo_received == -1 && dlog_allowed_flag ) {
+ int rc;
+ fd_set rfds;
+ struct timeval tv = { 0, 100000 }; // 100 ms
+
+ FD_ZERO( &rfds );
+ FD_SET( dlog_ttyfd, &rfds );
+
+ rc = select( dlog_ttyfd + 1, &rfds, NULL, NULL, &tv );
+ if ( rc > 0 && FD_ISSET( dlog_ttyfd, &rfds ) ) {
+ nread = read( dlog_ttyfd, buf, bufsz - 1 );
+ break;
+ }
+ now = time( NULL );
+ }
/* restore signal handling
*/
@@ -461,18 +478,11 @@ promptinput( char *buf,
( void )sighold( SIGINT );
}
}
- if ( dlog_timeouts_flag && timeoutix != IXMAX ) {
- ( void )alarm( alarm_save );
- ( void )sigset( SIGALRM, sigalrm_save );
- if ( pid == parentpid && ! miniroot ) {
- ( void )sighold( SIGALRM );
- }
- }
/* check for timeout or interrupt
*/
if ( nread < 0 ) {
- if ( dlog_signo_received == SIGALRM ) {
+ if ( now >= timeout ) {
mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
_("timeout\n") );
*exceptionixp = timeoutix;
@@ -496,8 +506,7 @@ promptinput( char *buf,
*exceptionixp = sigquitix;
} else {
mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
- _("unknown signal during dialog: %d\n"),
- dlog_signo_received );
+ _("abnormal dialog termination\n"));
*exceptionixp = sigquitix;
}
return BOOL_FALSE;
--
1.7.0.4
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2011-08-04 22:31 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-04 22:30 [PATCH v2 0/7] xfsdump: convert to using the POSIX signal API Bill Kendall
2011-08-04 22:30 ` [PATCH v2 1/7] xfsdump: remove conditional OPENMASKED code Bill Kendall
2011-08-09 22:40 ` Alex Elder
2011-08-04 22:30 ` [PATCH v2 2/7] xfsdump: process EPIPE instead of catching SIGPIPE Bill Kendall
2011-08-09 22:40 ` Alex Elder
2011-08-04 22:30 ` [PATCH v2 3/7] xfsdump: remove SIGCHLD handling Bill Kendall
2011-08-10 21:47 ` Alex Elder
2011-08-04 22:30 ` Bill Kendall [this message]
2011-08-10 21:47 ` [PATCH v2 4/7] xfsdump: rework dialog timeout and EINTR reliance Alex Elder
2011-08-04 22:30 ` [PATCH v2 5/7] xfsdump: rework dialog to use main signal handler Bill Kendall
2011-08-10 21:47 ` Alex Elder
2011-08-04 22:30 ` [PATCH v2 6/7] xfsdump: convert to the POSIX signal API Bill Kendall
2011-08-10 21:48 ` Alex Elder
2011-08-12 19:15 ` Bill Kendall
2011-08-12 20:45 ` Christoph Hellwig
2011-08-15 13:10 ` Bill Kendall
2011-08-04 22:30 ` [PATCH v2 7/7] xfsdump: refactor inventory session creation Bill Kendall
2011-08-10 21:48 ` Alex Elder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1312497011-24840-5-git-send-email-wkendall@sgi.com \
--to=wkendall@sgi.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox