> Date: Thu, 28 Nov 2019 03:48:04 +0100
> From: Klemens Nanni <[email protected]>
>
> On Thu, Nov 28, 2019 at 01:05:43AM +0100, Klemens Nanni wrote:
> > With that, the next step is to implement `ldomctl console guest01' in
> > analogy to vmctl(8).
> Here's a complete diff for updating the status output and implementing
> the console command, mainly to ease testing and review. I do want to
> plan those separately, though.
>
> Code and manual wording snatched from vmctl(8).
>
> > Code-wise, the only way to obtain the guest console's minor is to count
> > along as guests are printed; that is because the data strucutures
> > simply do not store this information.
> That's wrong, I just overcomplicated things. `struct guest' has a `gid'
> member which perfectly increments for each guest entry in the global
> `guests' list; a guest id of zero indicates the primary domain as
> already checked/used elsewhere in the code.
>
> > Feedback? OK?
> I've tested this diff on a T4-2 machine with all possible invocations
> of `ldomctl status [domain]' and `ldomctl console [domain]': it always
> prints and attaches to the correct serial console respectively, whether
> I pass an explicit domain or omit it to list all.
ok kettenis@
> Index: ldomctl.8
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldomctl/ldomctl.8,v
> retrieving revision 1.16
> diff -u -p -r1.16 ldomctl.8
> --- ldomctl.8 27 Nov 2019 19:54:10 -0000 1.16
> +++ ldomctl.8 28 Nov 2019 01:13:47 -0000
> @@ -34,6 +34,10 @@ information about domains running on the
> .Pp
> The following commands are available:
> .Bl -tag -width Ds
> +.It Cm console Ar domain
> +Using
> +.Xr cu 1
> +connect to the console of the guest domain.
> .It Cm delete Ar configuration
> Delete the specified configuration from non-volatile storage.
> .It Cm download Ar directory
> @@ -148,9 +152,9 @@ The primary domain should have less CPUs
> are now assigned to the guest domains:
> .Bd -literal -offset indent
> # ldomctl status
> -primary running OpenBSD running 1%
> -puffy running OpenBoot Primary Boot Loader 8%
> -salmah running OpenBoot Primary Boot Loader 12%
> +primary - running OpenBSD running 1%
> +puffy ttyV0 running OpenBoot Primary Boot Loader 8%
> +salmah ttyV1 running OpenBoot Primary Boot Loader 12%
> .Ed
> .Pp
> Configure the
> @@ -166,7 +170,7 @@ This example bridges guest domains into
> .Pp
> Access the console of the first domain and boot it:
> .Bd -literal -offset indent
> -# cu -l ttyV0
> +# ldomctl console puffy
> ok boot disk1
> .Ed
> .Sh SEE ALSO
> Index: ldomctl.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldomctl/ldomctl.c,v
> retrieving revision 1.23
> diff -u -p -r1.23 ldomctl.c
> --- ldomctl.c 27 Nov 2019 19:54:10 -0000 1.23
> +++ ldomctl.c 28 Nov 2019 02:40:14 -0000
> @@ -57,6 +57,7 @@ void guest_start(int argc, char **argv);
> void guest_stop(int argc, char **argv);
> void guest_panic(int argc, char **argv);
> void guest_status(int argc, char **argv);
> +void guest_console(int argc, char **argv);
> void init_system(int argc, char **argv);
>
> struct command commands[] = {
> @@ -70,6 +71,7 @@ struct command commands[] = {
> { "stop", guest_stop },
> { "panic", guest_panic },
> { "status", guest_status },
> + { "console", guest_console },
> { "init-system", init_system },
> { NULL, NULL }
> };
> @@ -156,14 +158,14 @@ main(int argc, char **argv)
> exit(EXIT_SUCCESS);
> }
>
> -void
> +__dead void
> usage(void)
> {
> fprintf(stderr, "usage:\t%1$s delete|select configuration\n"
> "\t%1$s download directory\n"
> "\t%1$s dump|list|list-io\n"
> "\t%1$s init-system file\n"
> - "\t%1$s panic|start|status|stop [domain]\n", getprogname());
> + "\t%1$s console|panic|start|status|stop [domain]\n", getprogname());
> exit(EXIT_FAILURE);
> }
>
> @@ -451,7 +453,8 @@ guest_status(int argc, char **argv)
> uint64_t total_cycles, yielded_cycles;
> double utilisation = 0.0;
> const char *state_str;
> - char buf[64];
> + char buf[32];
> + char console_str[8] = "-";
>
> if (argc < 1 || argc > 2)
> usage();
> @@ -554,10 +557,44 @@ guest_status(int argc, char **argv)
>
> if (state.state != GUEST_STATE_NORMAL)
> printf("%-16s %-16s\n", guest->name, state_str);
> - else
> - printf("%-16s %-16s %-32s %3.0f%%\n", guest->name,
> - state_str, softstate.soft_state_str,
> - utilisation);
> + else {
> + /* primary has no console */
> + if (guest->gid != 0) {
> + snprintf(console_str, sizeof(console_str),
> + "ttyV%llu", guest->gid - 1);
> + }
> +
> + printf("%-16s %-8s %-16s %-32s %3.0f%%\n", guest->name,
> + console_str, state_str, softstate.soft_state_str,
> + utilisation);
> + }
> + }
> +}
> +
> +void
> +guest_console(int argc, char **argv)
> +{
> + struct guest *guest;
> + uint64_t gid = -1;
> + char console_str[8];
> +
> + if (argc != 2)
> + usage();
> +
> + gid = find_guest(argv[1]);
> + if (gid == 0)
> + errx(1, "no console for primary domain");
> +
> + TAILQ_FOREACH(guest, &guest_list, link) {
> + if (gid != -1 && guest->gid != gid)
> + continue;
> + snprintf(console_str, sizeof(console_str),
> + "ttyV%llu", guest->gid - 1);
> +
> + closefrom(STDERR_FILENO + 1);
> + execl(LDOMCTL_CU, LDOMCTL_CU, "-l", console_str, "-s", "9600",
> + NULL);
> + err(1, "failed to open console");
> }
> }
>
> Index: ldomctl.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldomctl/ldomctl.h,v
> retrieving revision 1.10
> diff -u -p -r1.10 ldomctl.h
> --- ldomctl.h 27 Nov 2019 19:54:10 -0000 1.10
> +++ ldomctl.h 28 Nov 2019 01:09:59 -0000
> @@ -16,6 +16,8 @@
> * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> */
>
> +#define LDOMCTL_CU "/usr/bin/cu"
> +
> struct core;
> struct guest;
>
>
>