1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

signals: support also SIGTERM for breaking command

If we are signaled with SIGTERM it should be at least as good
as with SIGINT - as the command should stop ASAP.
So when lvm2 command allows signal handling we also
enable SIGTERM handling. If there are some other signals
we should handle equally -  we could just extend array.
This commit is contained in:
Zdenek Kabelac 2021-04-01 11:32:29 +02:00
parent 287565fd5d
commit fe4f83171d

View File

@ -26,8 +26,19 @@ static volatile sig_atomic_t _handler_installed = 0;
/* Support 3 level nesting, increase if needed more */
#define MAX_SIGINTS 3
static struct sigaction _oldhandler[MAX_SIGINTS];
static int _oldmasked[MAX_SIGINTS];
struct ar_sigs {
int sig;
const char *name;
int oldmasked[MAX_SIGINTS];
struct sigaction oldhandler[MAX_SIGINTS];
};
/* List of signals we want to allow/restore */
static struct ar_sigs _ar_sigs[] = {
{ SIGINT, "SIGINT" },
{ SIGTERM, "SIGTERM" },
};
static void _catch_sigint(int unused __attribute__((unused)))
{
@ -58,6 +69,7 @@ void sigint_clear(void)
void sigint_allow(void)
{
int i, mask = 0;
struct sigaction handler;
sigset_t sigs;
@ -70,30 +82,37 @@ void sigint_allow(void)
if (++_handler_installed > MAX_SIGINTS)
return;
/* Grab old sigaction for SIGINT: shall not fail. */
if (sigaction(SIGINT, NULL, &handler))
log_sys_debug("sigaction", "SIGINT");
handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */
handler.sa_handler = _catch_sigint;
/* Override the signal handler: shall not fail. */
if (sigaction(SIGINT, &handler, &_oldhandler[_handler_installed - 1]))
log_sys_debug("sigaction", "SIGINT");
/* Unmask SIGINT. Remember to mask it again on restore. */
/* Unmask signals. Remember to mask it again on restore. */
if (sigprocmask(0, NULL, &sigs))
log_sys_debug("sigprocmask", "");
if ((_oldmasked[_handler_installed - 1] = sigismember(&sigs, SIGINT))) {
sigdelset(&sigs, SIGINT);
if (sigprocmask(SIG_SETMASK, &sigs, NULL))
log_sys_debug("sigprocmask", "SIG_SETMASK");
for (i = 0; i < DM_ARRAY_SIZE(_ar_sigs); ++i) {
/* Grab old sigaction for SIGNAL: shall not fail. */
if (sigaction(_ar_sigs[i].sig, NULL, &handler))
log_sys_debug("sigaction", _ar_sigs[i].name);
handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */
handler.sa_handler = _catch_sigint;
/* Override the signal handler: shall not fail. */
if (sigaction(_ar_sigs[i].sig, &handler, &_ar_sigs[i].oldhandler[_handler_installed - 1]))
log_sys_debug("sigaction", _ar_sigs[i].name);
if ((_ar_sigs[i].oldmasked[_handler_installed - 1] = sigismember(&sigs, _ar_sigs[i].sig))) {
sigdelset(&sigs, _ar_sigs[i].sig);
mask = 1;
}
}
if (mask && sigprocmask(SIG_SETMASK, &sigs, NULL))
log_sys_debug("sigprocmask", "SIG_SETMASK");
}
void sigint_restore(void)
{
int i, mask = 0;
sigset_t sigs;
if (memlock_count_daemon())
return;
@ -102,16 +121,19 @@ void sigint_restore(void)
return;
/* Nesting count went below MAX_SIGINTS. */
if (_oldmasked[_handler_installed]) {
sigset_t sigs;
sigprocmask(0, NULL, &sigs);
sigaddset(&sigs, SIGINT);
if (sigprocmask(SIG_SETMASK, &sigs, NULL))
log_sys_debug("sigprocmask", "SIG_SETMASK");
}
sigprocmask(0, NULL, &sigs);
for (i = 0; i < DM_ARRAY_SIZE(_ar_sigs); ++i)
if (_ar_sigs[i].oldmasked[_handler_installed]) {
sigaddset(&sigs, _ar_sigs[i].sig);
mask = 1;
}
if (sigaction(SIGINT, &_oldhandler[_handler_installed], NULL))
log_sys_debug("sigaction", "SIGINT restore");
if (mask && sigprocmask(SIG_SETMASK, &sigs, NULL))
log_sys_debug("sigprocmask", "SIG_SETMASK");
for (i = 0; i < DM_ARRAY_SIZE(_ar_sigs); ++i)
if (sigaction(_ar_sigs[i].sig, &_ar_sigs[i].oldhandler[_handler_installed], NULL))
log_sys_debug("sigaction", _ar_sigs[i].name);
}
void block_signals(uint32_t flags __attribute__((unused)))