Files
finit/doc/config/tty.md
T
Joachim Wiberg c584795202 doc: fix back-references and stale claims left by the conversion
Reference sections kept pointing at the line-based format they no longer
document.  `sysv` and `task` sent the reader to Services for "<COND>",
the cgroups chapter opened by listing three legacy directives and then
explained further down that only two of them exist here, and the logging
chapter still gave "log:prio:facility.level,tag:ident" as the full
syntax.

Some claims were wrong independent of the format:

  - a sysv is a supervised daemon, grouped with service in
    SVC_TYPE_DAEMON, not a variation on task
  - restart-max has no upper bound of 255, or any other
  - the built-in rescue fallback runs in 12345789, not 12345
  - conditional loading quotes system/10-hotplug.conf, not
    system/hotplug.conf
  - the key spells conflicts, not conflict
  - the built-in getty no longer wants TERM last, it is a key

`if` takes either a service name or, in angle brackets, a condition,
decided in svc_ifthen().  Only the examples showed this, so it is now
said.

Terminology follows the split index.md already draws: a block is the new
format, a stanza the line-based one.

src/rescue.conf was still line-based, missed because it sits in src/
rather than system/ or contrib/.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-07-30 15:23:35 +02:00

162 lines
5.5 KiB
Markdown

TTYs and Consoles
=================
**Syntax:** `tty NAME { device = DEV }` -- built-in getty
`tty NAME { command = "CMD ARGS" }` -- external getty
`tty NAME { notty = true }`, or `{ rescue = true }` -- bare shell, no device
The block title NAME is what `initctl` shows. The three variants differ
in what they open: `device` runs the built-in getty on that TTY, and DEV
may be the special keyword `@console`, expanded from
`/sys/class/tty/console/active`, useful on embedded systems. `command`
hands the TTY to an external getty. `notty` opens nothing at all.
Settings common to all three:
| Setting | Alias | Description |
|---|---|---|
| `runlevel` | | Runlevels to run in, e.g. `"12345"` |
| `conditions` | `cond` | Conditions to wait for |
| `noclear` | | Do not clear the TTY after each session |
| `nowait` | | Do not wait for Enter before the login prompt |
| `nologin` | | Skip login, give a shell straight away |
The `device` variant takes two more:
| Setting | Description |
|---|---|
| `baud` | Baud rate, default 0, i.e., keep kernel default |
| `term` | `$TERM` value, e.g. `"vt220"` |
> A `tty` block inherits runlevel, condition (and other feature)
> parsing from the `service` block. So TTYs can run in one or many
> runlevels and depend on any condition supported by Finit. This is
> useful e.g. to depend on `<pid/elogind>` before starting a TTY.
**Example:**
tty ttyAMA0 {
runlevel = "12345"
device = "/dev/ttyAMA0"
baud = 115200
term = "vt220"
noclear = true
}
The second `tty` syntax variant is for using an external getty, like
agetty or the BusyBox getty.
The third variant is for board bringup and the `rescue` boot mode. No
device node is required, the same output the kernel uses is reused for
stdio. With `notty` a shell is started (`nologin`, `noclear`, and
`nowait` are implied); with `rescue` the bundled
`/libexec/finit/sulogin` presents a bare-bones root login prompt. If
the root (uid:0, gid:0) user does not have a password set, no rescue is
possible. For more information, see the [Rescue Mode](rescue.md)
section.
By default, the first two syntax variants *clear* the TTY and *wait* for
the user to press enter before starting getty.
**Example:**
tty getty {
runlevel = "12345"
command = "/sbin/getty -L 115200 /dev/ttyAMA0 vt100"
}
tty agetty {
runlevel = "12345"
command = "/sbin/agetty -L ttyAMA0 115200 vt100"
nowait = true
}
The `noclear` setting disables clearing the TTY after each session.
Clearing the TTY when a user logs out is usually preferable.
The `nowait` setting disables the `press Enter to activate console`
message before actually starting the getty program. On small and
embedded systems running multiple unused getty wastes both memory
and CPU cycles, so `wait` is the preferred default.
The `nologin` setting disables getty and `/bin/login`, and gives the
user a root (login) shell on the given TTY immediately.
Needless to say, this is a rather insecure option, but can be very
useful for developer builds, during board bringup, or similar.
Embedded systems may want to enable automatic `DEV` by supplying the
special `@console` device. This works regardless whether the system
uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit figures
it out by querying sysfs: `/sys/class/tty/console/active`. Leave
`baud` out to keep the kernel default.
> Most systems get by fine by just using `console`, which will evaluate
> to `/dev/console`. If you have to use `@console` to get any output,
> you may have some issue with your kernel config.
**Example:**
tty console {
runlevel = "12345"
device = "@console"
term = "vt220"
noclear = true
}
On really bare bones systems, or for board bringup, Finit can give you a
shell prompt as soon as bootstrap is done, without opening any device
node:
tty board {
runlevel = "12345789"
notty = true
}
This should of course not be enabled on production systems. Because it
may give a user root access without having to log in. However, for
board bringup and system debugging it can come in handy.
One can also use a `service` block to start a stand-alone shell:
service shell {
runlevel = "12345"
command = "/bin/sh -l"
}
Controlling TTY for Services
----------------------------
The `tty` setting gives a `run`, `task`, or `service` a controlling
terminal on the given device. The device is opened, set as the
controlling terminal for the session (after `setsid()`), and connected to
the process's stdin, stdout, and stderr. A default `TERM` environment
variable is set based on the device type: `vt102` for serial lines and
`linux` for virtual terminals.
The value may be a device node like `/dev/ttyS0`, or the special
keyword `@console` (see above). Note that `@console` expands only to
the first console, not all.
When `tty` is combined with a `log` block, stdout and stderr are
redirected to the log sink instead of the TTY, but stdin remains
connected to the TTY device.
> The `tty` setting is for `run`, `task`, and `service` blocks only.
> A `tty` block (for getty/login) is a different thing entirely, see
> above.
**Example:**
service foo {
description = "Foo on serial console"
runlevel = "2345"
tty = "/dev/ttyS0"
command = "/usr/sbin/foo"
}
task setup {
description = "Board bringup on console"
runlevel = "S"
tty = "@console"
command = "my-setup-script"
}