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;
}