1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-02-25 21:57:45 +03:00

Allow keyboard interrupts in yes_no_prompt(). Add code to toollib.c

loops and to pvcreate.c, lvchange.c and lvresize.c to handle
interrupted prompts.
This commit is contained in:
Petr Rockai 2007-06-15 10:11:14 +00:00
parent 0106e4df9d
commit 10e4254e7d
8 changed files with 146 additions and 0 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.26 -
=================================
Allow keyboard interrupt in user prompts where appropriate.
Remove system-lv code from clvmd. It's highly dodgy and never used.
Convert a lot of code pv dereferences to use get_pv_* functions.
Suppress a couple benign warnings by adding variable initializations.

View File

@ -34,6 +34,87 @@ static int _vg_lock_count = 0; /* Number of locks held */
static int _vg_write_lock_held = 0; /* VG write lock held? */
static int _signals_blocked = 0;
static volatile sig_atomic_t _sigint_caught = 0;
static volatile sig_atomic_t _handler_installed;
static struct sigaction _oldhandler;
static int _oldmasked;
static void _catch_sigint(int unused __attribute__((unused)))
{
_sigint_caught = 1;
}
int sigint_caught() {
return _sigint_caught;
}
void sigint_clear()
{
_sigint_caught = 0;
}
/* Temporarily allow keyboard interrupts to be intercepted and noted;
saves interrupt handler state for sigint_restore(). Users should
use the sigint_caught() predicate to check whether interrupt was
requested and act appropriately. Interrupt flags are never
automatically cleared by this code, but lvm_run_command() clears
the flag before running any command. All other places where the
flag needs to be cleared need to call sigint_clear(). */
void sigint_allow()
{
struct sigaction handler;
sigset_t sigs;
/* do not overwrite the backed up handler data with our
override ones; we just increase nesting count */
if (_handler_installed) {
_handler_installed++;
return;
}
/* grab old sigaction for SIGINT; shall not fail */
sigaction(SIGINT, NULL, &handler);
handler.sa_flags &= ~SA_RESTART; /* clear restart flag */
handler.sa_handler = _catch_sigint;
_handler_installed = 1;
/* override the signal handler; shall not fail */
sigaction(SIGINT, &handler, &_oldhandler);
/* unmask SIGINT, remember to mask it again on restore */
sigprocmask(0, NULL, &sigs);
if ((_oldmasked = sigismember(&sigs, SIGINT))) {
sigdelset(&sigs, SIGINT);
sigprocmask(SIG_SETMASK, &sigs, NULL);
}
}
void sigint_restore()
{
/* extra call, ignore */
if (!_handler_installed)
return;
if (_handler_installed > 1) {
_handler_installed--;
return;
}
/* nesting count went down to 0 */
_handler_installed = 0;
if (_oldmasked) {
sigset_t sigs;
sigprocmask(0, NULL, &sigs);
sigaddset(&sigs, SIGINT);
sigprocmask(SIG_SETMASK, &sigs, NULL);
}
sigaction(SIGINT, &_oldhandler, NULL);
}
static void _block_signals(int flags __attribute((unused)))
{
sigset_t set;

View File

@ -115,4 +115,11 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
int resume_lvs(struct cmd_context *cmd, struct list *lvs);
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
/* interrupt handling */
void sigint_clear();
void sigint_allow();
void sigint_restore();
int sigint_caught();
#endif

View File

@ -212,6 +212,9 @@ static int lvchange_resync(struct cmd_context *cmd,
return ECMD_FAILED;
}
if (sigint_caught())
return ECMD_FAILED;
active = 1;
}
}
@ -454,6 +457,10 @@ static int lvchange_persistent(struct cmd_context *cmd,
lv->name);
return 0;
}
if (sigint_caught())
return 0;
log_verbose("Ensuring %s is inactive.", lv->name);
if (!deactivate_lv(cmd, lv)) {
log_error("%s: deactivation failed", lv->name);
@ -626,6 +633,8 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
return ECMD_FAILED;
archived = 1;
doit += lvchange_persistent(cmd, lv);
if (sigint_caught())
return ECMD_FAILED;
}
/* add tag */

View File

@ -373,6 +373,7 @@ char yes_no_prompt(const char *prompt, ...)
int c = 0, ret = 0;
va_list ap;
sigint_allow();
do {
if (c == '\n' || !c) {
va_start(ap, prompt);
@ -390,6 +391,8 @@ char yes_no_prompt(const char *prompt, ...)
ret = c;
} while (!ret || c != '\n');
sigint_restore();
if (c != '\n')
printf("\n");
@ -865,6 +868,9 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
int ret = 0;
int locking_type;
/* each command should start out with sigint flag cleared */
sigint_clear();
if (!(cmd->cmd_line = _copy_command_line(cmd, argc, argv)))
return ECMD_FAILED;

View File

@ -485,6 +485,8 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
"reduced", lp->lv_name);
return ECMD_FAILED;
}
if (sigint_caught())
return ECMD_FAILED;
}
}
}

View File

@ -58,6 +58,9 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
return 0;
}
if (sigint_caught())
return 0;
dev = dev_cache_get(name, cmd->filter);
/* Is there an md superblock here? */
@ -103,6 +106,9 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
}
}
if (sigint_caught())
return 0;
if (pv && !is_orphan(pv) && arg_count(cmd, force_ARG)) {
log_print("WARNING: Forcing physical volume creation on "
"%s%s%s%s", name,
@ -173,6 +179,9 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
if (!pvcreate_check(cmd, pv_name))
goto error;
if (sigint_caught())
goto error;
if (arg_sign_value(cmd, physicalvolumesize_ARG, 0) == SIGN_MINUS) {
log_error("Physical volume size may not be negative");
goto error;
@ -309,6 +318,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
r = pvcreate_single(cmd, argv[i], &pp);
if (r > ret)
ret = r;
if (sigint_caught())
return ret;
}
return ret;

View File

@ -209,6 +209,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
ret = process_single(cmd, lvl->lv, handle);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
if (lvargs_supplied && lvargs_matched != list_size(arg_lvnames)) {
@ -407,6 +409,8 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
unlock_vg(cmd, vgname);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
return ret_max;
@ -429,6 +433,8 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
ret = process_single(cmd, vg, pvseg, handle);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
return ret_max;
@ -449,6 +455,8 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
ret = process_single(cmd, seg, handle);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
return ret_max;
@ -498,6 +506,9 @@ static int _process_one_vg(struct cmd_context *cmd, const char *vg_name,
ret_max = ret;
}
if (sigint_caught())
return ret_max;
unlock_vg(cmd, vg_name);
return ret_max;
@ -573,6 +584,8 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
&arg_vgnames,
lock_type, consistent, handle,
ret_max, process_single);
if (sigint_caught())
return ret_max;
}
} else {
list_iterate_items(sl, vgnames) {
@ -583,6 +596,8 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
&arg_vgnames,
lock_type, consistent, handle,
ret_max, process_single);
if (sigint_caught())
return ret_max;
}
}
@ -607,6 +622,8 @@ int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
}
if ((ret = process_single(cmd, vg, pvl->pv, handle)) > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
return ret_max;
@ -643,6 +660,8 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle,
ret = process_single(cmd, NULL, pv, handle);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
dev_iter_destroy(iter);
@ -715,6 +734,8 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
ret = process_single(cmd, vg, pv, handle);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
if (!list_empty(&tags) && (vgnames = get_vgs(cmd, 0)) &&
!list_empty(vgnames)) {
@ -735,6 +756,8 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
process_single);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
}
} else {
@ -745,10 +768,14 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
process_single);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
} else if (arg_count(cmd, all_ARG)) {
ret = _process_all_devs(cmd, handle, process_single);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
} else {
log_verbose("Scanning for physical volume names");
if (!(pvslist = get_pvs(cmd)))
@ -759,6 +786,8 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
handle);
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
return ret_max;
}
}
}