net: the DHCP lease goes to the log, not over the user's shell
"net: eth0 10.0.2.15/255.255.255.0 via 10.0.2.2" arrived on the display seconds after the prompt did, so the first thing anyone saw after booting was the kernel typing into their session. It lands wherever the cursor happens to be -- in the middle of a command, a fastfetch, or later a compositor's output. console_takeover() hands the framebuffer to userspace on the first exec, and after that the screen belongs to whoever is using the machine. cons_serial_only already encodes that rule for the boot path -- "the display is the product; the serial line is the diagnostics" -- and it starts set for exactly this reason. What was missing is the rule for messages that cannot be timed to happen before userspace starts, because they are waiting on a network. klog() is that: the serial port only, whatever cons_serial_only currently says. A macro rather than a function, because cprintf's varargs cannot be forwarded -- there is no vcprintf, and adding one to duplicate the formatter would cost more than it buys. cprintf holds cons.lock for the whole message, so the flag cannot be observed half-changed by another CPU printing at the same time. Nothing is lost. The line still goes out the UART, which is where bootcheck reads it from and where you want it when something is wrong, and a person who wants to know their address reads /proc/netif. Verified by screendumping the framebuffer after a boot and two fastfetch runs: no interruption on screen, still one occurrence on serial. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
This commit is contained in:
parent
1754cbf1aa
commit
d97dd9ed90
7 changed files with 42 additions and 76 deletions
|
|
@ -140,6 +140,13 @@ cannot run until the scheduler is entered.
|
||||||
DHCP obtains an address at boot. `/proc/netif` reports each interface's address,
|
DHCP obtains an address at boot. `/proc/netif` reports each interface's address,
|
||||||
netmask, gateway, MAC and frame counts, taken at the lwIP seam.
|
netmask, gateway, MAC and frame counts, taken at the lwIP seam.
|
||||||
|
|
||||||
|
The lease announcement goes to the **serial line only**, through `klog()` rather
|
||||||
|
than `cprintf()`. A lease arrives seconds *after* the shell prompt does, so on
|
||||||
|
the display it lands in the middle of whatever the user is doing — which is the
|
||||||
|
same rule that makes `cons_serial_only` start set: the display is the product,
|
||||||
|
the serial line is the diagnostics. Someone who wants to know their address
|
||||||
|
reads `/proc/netif`.
|
||||||
|
|
||||||
> It is `/proc/netif` and not `/proc/net` deliberately: on Linux `/proc/net` is a
|
> It is `/proc/netif` and not `/proc/net` deliberately: on Linux `/proc/net` is a
|
||||||
> directory of many files, and a single file by that name would be a lie about a
|
> directory of many files, and a single file by that name would be a lie about a
|
||||||
> well-known path.
|
> well-known path.
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrxJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrxJ
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrYJJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrYJJ
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrYJJJJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrYJJJJ
|
||||||
|
|
@ -46,12 +34,3 @@
|
||||||
bddddddddddddddddddddddddddddddddddddddddddddddddddddddkkkhh
|
bddddddddddddddddddddddddddddddddddddddddddddddddddddddkkkhh
|
||||||
bddddddddddddddddddddddddddddddddddddddddddddddddddddddkkh
|
bddddddddddddddddddddddddddddddddddddddddddddddddddddddkkh
|
||||||
dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbk
|
dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLJ
|
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLJ
|
||||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLJII
|
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLJII
|
||||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJIIII
|
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJIIII
|
||||||
|
|
@ -67,16 +50,3 @@
|
||||||
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED
|
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED
|
||||||
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED
|
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED
|
||||||
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
|
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrJJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrJJ
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrJJJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrJJJ
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrYJJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrYJJ
|
||||||
|
|
@ -21,7 +15,3 @@
|
||||||
mmmmmmmmmmmmmmmmmmmmmmmmmmkkh
|
mmmmmmmmmmmmmmmmmmmmmmmmmmkkh
|
||||||
ddddddddddddddddddddddddddkk
|
ddddddddddddddddddddddddddkk
|
||||||
bbbbbbbbbbbbbbbbbbbbbbbbbb
|
bbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrnJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrnJ
|
||||||
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrxJJJ
|
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrxJJJ
|
||||||
jrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrJJJJ
|
jrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrJJJJ
|
||||||
|
|
@ -29,9 +21,3 @@
|
||||||
wmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmkkkh
|
wmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmkkkh
|
||||||
dddddddddddddddddddddddddddddddddddbkk
|
dddddddddddddddddddddddddddddddddddbkk
|
||||||
dddddddddddddddddddddddddddddddddddbh
|
dddddddddddddddddddddddddddddddddddbh
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,36 @@ extern int tty_fg_pgrp;
|
||||||
void cons_get_termios(struct termios *);
|
void cons_get_termios(struct termios *);
|
||||||
void cons_set_termios(const struct termios *);
|
void cons_set_termios(const struct termios *);
|
||||||
void cprintf(char*, ...);
|
void cprintf(char*, ...);
|
||||||
|
|
||||||
|
// A log line: the serial port only, never the display.
|
||||||
|
//
|
||||||
|
// console_takeover() hands the framebuffer to userspace on the first exec, and
|
||||||
|
// after that the screen belongs to whoever is using the machine. A kernel
|
||||||
|
// message arriving then is not information they asked for -- it lands in the
|
||||||
|
// middle of their shell, or their editor, or a compositor's output. The DHCP
|
||||||
|
// lease is what made this necessary: it turns up seconds after the prompt does,
|
||||||
|
// so the first thing anyone sees after booting is the kernel talking over them.
|
||||||
|
//
|
||||||
|
// The same rule the boot path already follows, and the reason cons_serial_only
|
||||||
|
// starts set: the display is the product, the serial line is the diagnostics.
|
||||||
|
// klog is that rule for messages that cannot be timed to happen before
|
||||||
|
// userspace starts.
|
||||||
|
//
|
||||||
|
// A macro rather than a function because cprintf's varargs cannot be forwarded
|
||||||
|
// -- there is no vcprintf, and adding one to duplicate the formatter would cost
|
||||||
|
// more than it buys. cprintf holds cons.lock for the whole message, so the flag
|
||||||
|
// cannot be seen half-changed by another CPU printing at the same time.
|
||||||
|
//
|
||||||
|
// Nothing is lost: serial is where bootcheck reads from and where you want
|
||||||
|
// these when something is wrong, and anything a *user* should see belongs in a
|
||||||
|
// file they can read -- /proc/netif, for the example above.
|
||||||
|
extern int cons_serial_only;
|
||||||
|
#define klog(...) do { \
|
||||||
|
int _klog_was = cons_serial_only; \
|
||||||
|
cons_serial_only = 1; \
|
||||||
|
cprintf(__VA_ARGS__); \
|
||||||
|
cons_serial_only = _klog_was; \
|
||||||
|
} while (0)
|
||||||
void consoleintr(int(*)(void));
|
void consoleintr(int(*)(void));
|
||||||
void panic(char*) __attribute__((noreturn));
|
void panic(char*) __attribute__((noreturn));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,11 @@ net_thread(void)
|
||||||
const ip4_addr_t *a = netif_ip4_addr(nif);
|
const ip4_addr_t *a = netif_ip4_addr(nif);
|
||||||
const ip4_addr_t *m = netif_ip4_netmask(nif);
|
const ip4_addr_t *m = netif_ip4_netmask(nif);
|
||||||
const ip4_addr_t *gw = netif_ip4_gw(nif);
|
const ip4_addr_t *gw = netif_ip4_gw(nif);
|
||||||
cprintf("net: %s %d.%d.%d.%d/%d.%d.%d.%d via %d.%d.%d.%d\n",
|
// klog, not cprintf: a lease arrives seconds after the shell
|
||||||
|
// prompt does, so on the display this lands in the middle of
|
||||||
|
// whatever the user is doing. /proc/netif is where a person looks
|
||||||
|
// for an address; the serial line is where the log belongs.
|
||||||
|
klog("net: %s %d.%d.%d.%d/%d.%d.%d.%d via %d.%d.%d.%d\n",
|
||||||
net_eth_device(i)->name,
|
net_eth_device(i)->name,
|
||||||
ip4_addr1(a), ip4_addr2(a), ip4_addr3(a), ip4_addr4(a),
|
ip4_addr1(a), ip4_addr2(a), ip4_addr3(a), ip4_addr4(a),
|
||||||
ip4_addr1(m), ip4_addr2(m), ip4_addr3(m), ip4_addr4(m),
|
ip4_addr1(m), ip4_addr2(m), ip4_addr3(m), ip4_addr4(m),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue