When allocating a new keyboard at vt_upgrade() time, unwind any cngrabs
done on the old keyboard and then do the corresponding number of grabs on the new keyboard. This fixes a race that can leave the system with a non-functioning keyboard. It goes like this... - The bios claims there is an AT keyboard, atkbd attaches. - SI_SUB_INT_CONFIG_HOOKS runs. - USB probes devices. Devices begin attaching, including disks. - GELI prompts for a password for a just-attached disk, which results in a cngrab() while atkbd is the keyboard. - A USB keyboard attaches. - vt_upgrade() runs and switches the keyboard to the new USB keyboard, but because cngrab was never called for it, it's not activated and keystrokes are ignored. - Now there is no functional keyboard and no way to get one; even plugging in a different USB keyboard doesn't help, because the console is still grabbed, still waiting for a GELI pw. Discussed with: ray@
This commit is contained in:
parent
8e6a06102c
commit
17962d0222
@ -977,10 +977,22 @@ vt_kbdevent(keyboard_t *kbd, int event, void *arg)
|
||||
static int
|
||||
vt_allocate_keyboard(struct vt_device *vd)
|
||||
{
|
||||
int idx0, idx;
|
||||
int grabbed, i, idx0, idx;
|
||||
keyboard_t *k0, *k;
|
||||
keyboard_info_t ki;
|
||||
|
||||
/*
|
||||
* If vt_upgrade() happens while the console is grabbed, we are
|
||||
* potentially going to switch keyboard devices while the keyboard is in
|
||||
* use. Unwind the grabbing of the current keyboard first, then we will
|
||||
* re-grab the new keyboard below, before we return.
|
||||
*/
|
||||
if (vd->vd_curwindow == &vt_conswindow) {
|
||||
grabbed = vd->vd_curwindow->vw_grabbed;
|
||||
for (i = 0; i < grabbed; ++i)
|
||||
vtterm_cnungrab(vd->vd_curwindow->vw_terminal);
|
||||
}
|
||||
|
||||
idx0 = kbd_allocate("kbdmux", -1, vd, vt_kbdevent, vd);
|
||||
if (idx0 >= 0) {
|
||||
DPRINTF(20, "%s: kbdmux allocated, idx = %d\n", __func__, idx0);
|
||||
@ -1012,6 +1024,11 @@ vt_allocate_keyboard(struct vt_device *vd)
|
||||
vd->vd_keyboard = idx0;
|
||||
DPRINTF(20, "%s: vd_keyboard = %d\n", __func__, vd->vd_keyboard);
|
||||
|
||||
if (vd->vd_curwindow == &vt_conswindow) {
|
||||
for (i = 0; i < grabbed; ++i)
|
||||
vtterm_cngrab(vd->vd_curwindow->vw_terminal);
|
||||
}
|
||||
|
||||
return (idx0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user