Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve interactive shell #66

Merged
merged 2 commits into from
Feb 26, 2024
Merged

Conversation

chantra
Copy link
Collaborator

@chantra chantra commented Feb 23, 2024

Make it possible to use job control in interactive shell.

Before this change, when dropped in an interactive shell, Ctrl-C would kill the whole qemu process.

to make this work, we need 2 things:

  1. tell qemu to forward ctrl-c to the guest, this is done by using -serial mon:stdio instead of -serial stdio.
  2. run bash in a controlling terminal so it can set job control.

By using `-serial mon:stdio` we multiplex the guest'serial console and QEMU
monitor to the host's stdio. This gives us 2 features in interactive mode:

1) Access to the monitor via the `Ctrl-c a` keybinding
2) Intercept Ctrl-c and pass it to the guest instead of killing the guest.

In non-interactive mode, stdio is not hooked to qemu and this is a no-op.

https://www.qemu.org/docs/master/system/qemu-manpage.html#hxtool-9

```
mon:dev_string
This is a special option to allow the monitor to be multiplexed onto another serial port. The monitor is accessed with key sequence of Control-a and then pressing c. dev_string should be any one of the serial devices specified above. An example to multiplex the monitor onto a telnet server listening on port 4444 would be:

-serial mon:telnet::4444,server=on,wait=off

When the monitor is multiplexed to stdio in this way, Ctrl+C will not terminate QEMU any more but will be passed to the guest instead.
```

Testing:

In interactive mode, typed `Ctrl-a h`
```
root@(none):/#
C-a h    print this help
C-a x    exit emulator
C-a s    save disk data back to file (if -snapshot)
C-a t    toggle console timestamps
C-a b    send break (magic sysrq)
C-a c    switch between console and monitor
C-a C-a  sends C-a
```
and confirmed that Ctrl-c did not kill the guest.

Signed-off-by: Manu Bretelle <[email protected]>
Upon boot up, bash was reporting:

```
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
```

and as a side-effect, Ctrl-C,Ctrl-Z.... were disabled.

This change makes use of `setsid` to exec `bash` and setting the controlling
terminal to the current one.
This let `bash` successfully set up job control.

https://stackoverflow.com/a/77840840 has a detailed explanation.

Signed-off-by: Manu Bretelle <[email protected]>
Copy link
Owner

@danobi danobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! looks like this should close #13 as well right?

@chantra
Copy link
Collaborator Author

chantra commented Feb 26, 2024

lgtm! looks like this should close #13 as well right?

It will not as ran at the time, for a couple of reasons I can think of.

  1. stdin is not hooked to the VM when not running in interactive mode:
    if !qemu.interactive() {
  2. the command is ran through QGA which is disconnected from the terminal input. I suppose it would be possible handle/forward to the guest through executing kill -s ${signal_to_forward} ${pid_of_executed_command}.

But maybe in this specific case the solution to @javierhonduco issue is to drop in an interactive shell and run the command. Then signals will be forwarded from stdin to the guest's terminal.

@chantra chantra merged commit 51f11bf into danobi:master Feb 26, 2024
1 check passed
@chantra chantra deleted the improve_interactive_shell branch February 26, 2024 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants