git: 8ec6d7be2e27 - main - kern: console: make /dev/console backing console more predictable
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 05 Jan 2024 15:55:03 UTC
The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=8ec6d7be2e27622b8b9e192b4da9ce88a4118636 commit 8ec6d7be2e27622b8b9e192b4da9ce88a4118636 Author: Kyle Evans <kevans@FreeBSD.org> AuthorDate: 2024-01-05 06:09:31 +0000 Commit: Kyle Evans <kevans@FreeBSD.org> CommitDate: 2024-01-05 15:52:29 +0000 kern: console: make /dev/console backing console more predictable Specifically, altering the console list with conscontrol has some weird behavior: 1. If you remove the first configured console, /dev/console will become unconfigured 2. Any console added becomes the /dev/console In a multicons situation, #1 is clearly a bug and #2 is perhaps slightly less clear. If we have ttyu0, ttyv0, then it seems obvious that one would want ttyv0 to take over the console if ttyu0 is removed. If we add ttyu0 back in, then it's debatable whether it should take over the console or not. Fix it now to make the /dev/console selection more FIFO-ish, with respect to how conscontrol affects it. A `primary` verb for conscontrol(8) might be a good addition. --- sys/kern/kern_cons.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_cons.c b/sys/kern/kern_cons.c index 462cd0c45758..d4a858cb12fd 100644 --- a/sys/kern/kern_cons.c +++ b/sys/kern/kern_cons.c @@ -239,15 +239,31 @@ cnremove(struct consdev *cn) { struct cn_device *cnd; int i; + bool primary = true; STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { - if (cnd->cnd_cn != cn) + if (cnd->cnd_cn != cn) { + primary = false; continue; - if (STAILQ_FIRST(&cn_devlist) == cnd) - ttyconsdev_select(NULL); + } + STAILQ_REMOVE(&cn_devlist, cnd, cn_device, cnd_next); cnd->cnd_cn = NULL; + /* + * We only need to select a new console if we've removed all + * consoles or if we're removing the primary console. + */ + if (primary) { + struct cn_device *next; + + next = STAILQ_FIRST(&cn_devlist); + if (next == NULL) + ttyconsdev_select(NULL); + else + ttyconsdev_select(next->cnd_cn->cn_name); + } + /* Remove this device from available mask. */ for (i = 0; i < CNDEVTAB_SIZE; i++) if (cnd == &cn_devtab[i]) { @@ -356,8 +372,6 @@ sysctl_kern_console(SYSCTL_HANDLER_ARGS) error = 0; } else { error = cnadd(cp); - if (error == 0) - cnselect(cp); } break; }