1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

signals: better nesting support

Support upto 3 levels os nesting signal blocking.
As of today - code blocks signals immediatelly when it opens
VG in read-write mode - this however makes current prompt usage
then partially unusable since user may not 'break' command
during prompt (something most user would expect).

Until a better fix for prompting is implemented, put in support
for signal nesting - thus when prompt enables signal acceptance,
make it possible to really break command at this point.
This commit is contained in:
Zdenek Kabelac 2014-05-02 17:30:27 +02:00
parent 31ac200a37
commit e585a6bbcf
2 changed files with 15 additions and 21 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.107 - Version 2.02.107 -
================================== ==================================
Better support for nesting of blocking signals.
Use only sigaction handler and drop duplicate signal handler. Use only sigaction handler and drop duplicate signal handler.
Separate signal handling and flock code out into lib/misc. Separate signal handling and flock code out into lib/misc.
Don't start dmeventd checking seg_monitor and monitoring is disabled. Don't start dmeventd checking seg_monitor and monitoring is disabled.

View File

@ -21,9 +21,12 @@
static sigset_t _oldset; static sigset_t _oldset;
static int _signals_blocked = 0; static int _signals_blocked = 0;
static volatile sig_atomic_t _sigint_caught = 0; static volatile sig_atomic_t _sigint_caught = 0;
static volatile sig_atomic_t _handler_installed2; static volatile sig_atomic_t _handler_installed;
static struct sigaction _oldhandler2;
static int _oldmasked; /* Support 3 level nesting, increase if needed more */
#define MAX_SIGINTS 3
static struct sigaction _oldhandler[MAX_SIGINTS];
static int _oldmasked[MAX_SIGINTS];
static void _catch_sigint(int unused __attribute__((unused))) static void _catch_sigint(int unused __attribute__((unused)))
{ {
@ -61,10 +64,8 @@ void sigint_allow(void)
* Do not overwrite the backed-up handler data - * Do not overwrite the backed-up handler data -
* just increase nesting count. * just increase nesting count.
*/ */
if (_handler_installed2) { if (++_handler_installed >= MAX_SIGINTS)
_handler_installed2++;
return; return;
}
/* Grab old sigaction for SIGINT: shall not fail. */ /* Grab old sigaction for SIGINT: shall not fail. */
if (sigaction(SIGINT, NULL, &handler)) if (sigaction(SIGINT, NULL, &handler))
@ -73,17 +74,15 @@ void sigint_allow(void)
handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */ handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */
handler.sa_handler = _catch_sigint; handler.sa_handler = _catch_sigint;
_handler_installed2 = 1;
/* Override the signal handler: shall not fail. */ /* Override the signal handler: shall not fail. */
if (sigaction(SIGINT, &handler, &_oldhandler2)) if (sigaction(SIGINT, &handler, &_oldhandler[_handler_installed - 1]))
log_sys_debug("sigaction", "SIGINT"); log_sys_debug("sigaction", "SIGINT");
/* Unmask SIGINT. Remember to mask it again on restore. */ /* Unmask SIGINT. Remember to mask it again on restore. */
if (sigprocmask(0, NULL, &sigs)) if (sigprocmask(0, NULL, &sigs))
log_sys_debug("sigprocmask", ""); log_sys_debug("sigprocmask", "");
if ((_oldmasked = sigismember(&sigs, SIGINT))) { if ((_oldmasked[_handler_installed] = sigismember(&sigs, SIGINT))) {
sigdelset(&sigs, SIGINT); sigdelset(&sigs, SIGINT);
if (sigprocmask(SIG_SETMASK, &sigs, NULL)) if (sigprocmask(SIG_SETMASK, &sigs, NULL))
log_sys_debug("sigprocmask", "SIG_SETMASK"); log_sys_debug("sigprocmask", "SIG_SETMASK");
@ -92,18 +91,12 @@ void sigint_allow(void)
void sigint_restore(void) void sigint_restore(void)
{ {
if (!_handler_installed2) if (!_handler_installed ||
--_handler_installed >= MAX_SIGINTS)
return; return;
if (_handler_installed2 > 1) { /* Nesting count went bellow MAX_SIGINTS. */
_handler_installed2--; if (_oldmasked[_handler_installed]) {
return;
}
/* Nesting count went down to 0. */
_handler_installed2 = 0;
if (_oldmasked) {
sigset_t sigs; sigset_t sigs;
sigprocmask(0, NULL, &sigs); sigprocmask(0, NULL, &sigs);
sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGINT);
@ -111,7 +104,7 @@ void sigint_restore(void)
log_sys_debug("sigprocmask", "SIG_SETMASK"); log_sys_debug("sigprocmask", "SIG_SETMASK");
} }
if (sigaction(SIGINT, &_oldhandler2, NULL)) if (sigaction(SIGINT, &_oldhandler[_handler_installed], NULL))
log_sys_debug("sigaction", "SIGINT restore"); log_sys_debug("sigaction", "SIGINT restore");
} }