mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
qemu-monitor: migrate to Python!
Just came across the telnet in the stdlib, and got rid of the ugly expect dependency, nice. Also implement stdin input now that we have a sane language.
This commit is contained in:
@@ -8017,12 +8017,16 @@ or send one command such as `info qtree` and quit the monitor:
|
|||||||
./qemu-monitor info qtree
|
./qemu-monitor info qtree
|
||||||
....
|
....
|
||||||
|
|
||||||
|
or equivalently:
|
||||||
|
|
||||||
|
....
|
||||||
|
echo 'info qtree' | ./qemu-monitor
|
||||||
|
....
|
||||||
|
|
||||||
Source: link:qemu-monitor[]
|
Source: link:qemu-monitor[]
|
||||||
|
|
||||||
`qemu-monitor` uses the `-monitor` QEMU command line option, which makes the monitor listen from a socket.
|
`qemu-monitor` uses the `-monitor` QEMU command line option, which makes the monitor listen from a socket.
|
||||||
|
|
||||||
`qemu-monitor` does not support input from an stdin pipe currently, see comments on the source for rationale.
|
|
||||||
|
|
||||||
Alternatively, from text mode:
|
Alternatively, from text mode:
|
||||||
|
|
||||||
....
|
....
|
||||||
|
|||||||
@@ -88,9 +88,9 @@ automake \
|
|||||||
bc \
|
bc \
|
||||||
bison \
|
bison \
|
||||||
build-essential \
|
build-essential \
|
||||||
|
ccache \
|
||||||
coreutils \
|
coreutils \
|
||||||
cpio \
|
cpio \
|
||||||
expect \
|
|
||||||
flex \
|
flex \
|
||||||
gcc-aarch64-linux-gnu \
|
gcc-aarch64-linux-gnu \
|
||||||
gcc-arm-linux-gnueabihf \
|
gcc-arm-linux-gnueabihf \
|
||||||
@@ -114,7 +114,6 @@ pexpect==4.6.0 \
|
|||||||
"
|
"
|
||||||
if "$gem5"; then
|
if "$gem5"; then
|
||||||
pkgs="${pkgs}\
|
pkgs="${pkgs}\
|
||||||
ccache \
|
|
||||||
diod \
|
diod \
|
||||||
libgoogle-perftools-dev \
|
libgoogle-perftools-dev \
|
||||||
protobuf-compiler \
|
protobuf-compiler \
|
||||||
|
|||||||
66
qemu-monitor
66
qemu-monitor
@@ -1,24 +1,44 @@
|
|||||||
#!/usr/bin/env expect
|
#!/usr/bin/env python3
|
||||||
# Ee have to use expect since QEMU 2.12: just piping commands
|
|
||||||
# into telnet stopped working at that version.
|
|
||||||
spawn telnet localhost 45454
|
|
||||||
set prompt "\n(qemu) "
|
|
||||||
expect $prompt
|
|
||||||
if {$argc > 0} {
|
|
||||||
send "[concat [join $argv " "]]\r"
|
|
||||||
expect $prompt
|
|
||||||
} else {
|
|
||||||
interact
|
|
||||||
}
|
|
||||||
|
|
||||||
# In order to treat input from stdin, we would need to differentiate between input from pipe vs terminal.
|
import os
|
||||||
# For bash we can do it as:
|
import sys
|
||||||
# https://stackoverflow.com/questions/911168/how-to-detect-if-my-shell-script-is-running-through-a-pipe
|
import telnetlib
|
||||||
# but no one knows for Tcl:
|
|
||||||
# https://stackoverflow.com/questions/43660612/how-to-check-if-stdin-stdout-are-connected-to-a-terminal-in-tcl
|
import common
|
||||||
# One option would also be to have a bash wrapper that calls this tcl script.
|
|
||||||
# Related: https://stackoverflow.com/questions/10237872/expect-redirect-stdin
|
prompt = b'\n(qemu) '
|
||||||
#while {[gets stdin line] > 0} {
|
|
||||||
#expect $prompt
|
parser = common.get_argparse({
|
||||||
#send "$line\r"
|
'description': '''\
|
||||||
#}
|
Run a command on the QEMU monitor of a running QEMU instance
|
||||||
|
|
||||||
|
If the stdin is a terminal, open an interact shell. Otherwise,
|
||||||
|
run commands from stdin and quit.
|
||||||
|
'''
|
||||||
|
})
|
||||||
|
parser.add_argument(
|
||||||
|
'command',
|
||||||
|
help='If given, run this command and quit',
|
||||||
|
nargs='*',
|
||||||
|
)
|
||||||
|
args = common.setup(parser)
|
||||||
|
|
||||||
|
def write_and_read(tn, cmd, prompt):
|
||||||
|
tn.write(cmd.encode('utf-8'))
|
||||||
|
return '\n'.join(tn.read_until(prompt).decode('utf-8').splitlines()[1:])[:-len(prompt)]
|
||||||
|
|
||||||
|
with telnetlib.Telnet('localhost', common.qemu_monitor_port) as tn:
|
||||||
|
# Couldn't disable server echo, so just removing the write for now.
|
||||||
|
# https://stackoverflow.com/questions/12421799/how-to-disable-telnet-echo-in-python-telnetlib
|
||||||
|
# sock = tn.get_socket()
|
||||||
|
# sock.send(telnetlib.IAC + telnetlib.WILL + telnetlib.ECHO)
|
||||||
|
if os.isatty(sys.stdin.fileno()):
|
||||||
|
if args.command == []:
|
||||||
|
print(tn.read_until(prompt).decode('utf-8'), end='')
|
||||||
|
tn.interact()
|
||||||
|
else:
|
||||||
|
tn.read_until(prompt)
|
||||||
|
print(write_and_read(tn, ' '.join(args.command) + '\n', prompt))
|
||||||
|
else:
|
||||||
|
tn.read_until(prompt)
|
||||||
|
print(write_and_read(tn, sys.stdin.read() + '\n', prompt))
|
||||||
|
|||||||
Reference in New Issue
Block a user