Skip to content

Commit

Permalink
vm: support console_cmd to run cmd to collect console log
Browse files Browse the repository at this point in the history
- Sometimes we need customized cmd to get serial log, ex FTDI4232H
chip gets serial log through usb directly, thus we need to call
cmd like `pyterm.py ftdi://ftdi:4232:FT7JLD0U/1`.
- There are seveval places in console implementation to call
osutil.Command, move the command code into one function.
  • Loading branch information
jiangenj committed Jan 24, 2025
1 parent 7315a7c commit 19cf8f5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 50 deletions.
46 changes: 27 additions & 19 deletions vm/adb/adb.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ func init() {
}

type Device struct {
Serial string `json:"serial"` // device serial to connect
Console string `json:"console"` // console device name (e.g. "/dev/pts/0")
Serial string `json:"serial"` // device serial to connect
Console string `json:"console"` // console device name (e.g. "/dev/pts/0")
ConsoleCmd []string `json:"console_cmd"` // command to obtain device console log
}

type Config struct {
Expand All @@ -60,13 +61,14 @@ type Pool struct {
}

type instance struct {
cfg *Config
adbBin string
device string
console string
closed chan bool
debug bool
timeouts targets.Timeouts
cfg *Config
adbBin string
device string
console string
consoleCmd []string
closed chan bool
debug bool
timeouts targets.Timeouts
}

var (
Expand Down Expand Up @@ -132,13 +134,14 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
return nil, err
}
inst := &instance{
cfg: pool.cfg,
adbBin: pool.cfg.Adb,
device: device.Serial,
console: device.Console,
closed: make(chan bool),
debug: pool.env.Debug,
timeouts: pool.env.Timeouts,
cfg: pool.cfg,
adbBin: pool.cfg.Adb,
device: device.Serial,
console: device.Console,
consoleCmd: device.ConsoleCmd,
closed: make(chan bool),
debug: pool.env.Debug,
timeouts: pool.env.Timeouts,
}
closeInst := inst
defer func() {
Expand All @@ -149,10 +152,13 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
if err := inst.repair(); err != nil {
return nil, err
}
if inst.console == "" {
if inst.console != "" {
log.Logf(0, "associating adb device %v with console %v", inst.device, inst.console)
} else if inst.consoleCmd != nil {
log.Logf(0, "associating adb device %v with console cmd `%v`", inst.device, inst.consoleCmd)
} else {
inst.console = findConsole(inst.adbBin, inst.device)
}
log.Logf(0, "associating adb device %v with console %v", inst.device, inst.console)
if pool.cfg.BatteryCheck {
if err := inst.checkBatteryLevel(); err != nil {
return nil, err
Expand Down Expand Up @@ -517,7 +523,9 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
var tty io.ReadCloser
var err error

if ok, ip := isRemoteCuttlefish(inst.device); ok {
if inst.consoleCmd != nil {
tty, err = vmimpl.OpenConsoleByCmd(inst.consoleCmd)
} else if ok, ip := isRemoteCuttlefish(inst.device); ok {
tty, err = vmimpl.OpenRemoteKernelLog(ip, inst.console)
} else if inst.console == "adb" {
tty, err = vmimpl.OpenAdbConsole(inst.adbBin, inst.device)
Expand Down
53 changes: 22 additions & 31 deletions vm/vmimpl/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,58 +80,49 @@ func (t *tty) Close() error {
// OpenRemoteKernelLog accesses to the host where Android VM runs on, not Android VM itself.
// The host stores all kernel outputs of Android VM so in case of crashes nothing will be lost.
func OpenRemoteKernelLog(ip, console string) (rc io.ReadCloser, err error) {
rpipe, wpipe, err := osutil.LongPipe()
if err != nil {
return nil, err
}
conAddr := "vsoc-01@" + ip
cmd := osutil.Command("ssh", conAddr, "tail", "-f", console)
cmd.Stdout = wpipe
cmd.Stderr = wpipe
if _, err := cmd.StdinPipe(); err != nil {
rpipe.Close()
wpipe.Close()
return nil, err
}
if err := cmd.Start(); err != nil {
rpipe.Close()
wpipe.Close()
return nil, fmt.Errorf("failed to connect to console server: %w", err)
}
wpipe.Close()
con := &remoteCon{
cmd: cmd,
rpipe: rpipe,
args := []string{
"ssh",
conAddr,
"tail",
"-f",
console,
}
return con, nil
return OpenConsoleByCmd(args)
}

// Open dmesg remotely.
func OpenRemoteConsole(bin string, args ...string) (rc io.ReadCloser, err error) {
args = append([]string{bin}, args...)
args = append(args, "dmesg -w")
return OpenConsoleByCmd(args)
}

// OpenAdbConsole provides fallback console output using 'adb shell dmesg -w'.
func OpenAdbConsole(bin, dev string) (rc io.ReadCloser, err error) {
return OpenRemoteConsole(bin, "-s", dev, "shell")
}

// Open console log by cmd.
func OpenConsoleByCmd(args []string) (rc io.ReadCloser, err error) {
rpipe, wpipe, err := osutil.LongPipe()
if err != nil {
return nil, err
}
args = append(args, "dmesg -w")
cmd := osutil.Command(bin, args...)
cmd := osutil.Command(args[0], args[1:]...)
cmd.Stdout = wpipe
cmd.Stderr = wpipe
if err := cmd.Start(); err != nil {
rpipe.Close()
wpipe.Close()
return nil, fmt.Errorf("failed to start adb: %w", err)
return nil, fmt.Errorf("failed to open console: %w", err)
}
wpipe.Close()
con := &remoteCon{
cmd: cmd,
rpipe: rpipe,
}
return con, err
}

// OpenAdbConsole provides fallback console output using 'adb shell dmesg -w'.
func OpenAdbConsole(bin, dev string) (rc io.ReadCloser, err error) {
return OpenRemoteConsole(bin, "-s", dev, "shell")
return con, nil
}

type remoteCon struct {
Expand Down

0 comments on commit 19cf8f5

Please sign in to comment.