blob: 1cd7531893303a0992d1cf536e21b1d333dc32d3 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package main
// Program to map Fuchsia devices to their associated serial connection on a
// controller machine. Connects to all available serial connections on the
// controller machine, invokes `dlog` (kernel debug log) and attempts to
// extract nodename=(.*?) from netsvc start up.
import (
"bufio"
"context"
"fmt"
"io"
"io/ioutil"
"path"
"regexp"
"time"
"fuchsia.googlesource.com/tools/logger"
"fuchsia.googlesource.com/tools/serial"
)
const (
// The default path under which /lib/udev/rules.d/60-serial.rules
// will create serial device files with full identifiers.
serialDir = "/dev/serial/by-id"
)
func main() {
ctx := context.Background()
files, err := ioutil.ReadDir(serialDir)
if err != nil {
logger.Fatalf(ctx, "failed to readdir() %s: %s", serialDir, err)
}
mapping := make(map[string]string)
re := regexp.MustCompile("nodename='(.*?)'")
for _, f := range files {
fPath := path.Join(serialDir, f.Name())
device, err := serial.Open(fPath)
if err != nil {
logger.Errorf(ctx, "unable to open() %s: %s", fPath, err)
}
_, err = io.WriteString(device, "\ndlog\n")
if err != nil {
logger.Errorf(ctx, "failed to writestring() to %s: %s", fPath, err)
}
errs := make(chan error)
c := make(chan string)
go func() {
defer close(c)
defer close(errs)
scanner := bufio.NewScanner(device)
for scanner.Scan() {
line := scanner.Text()
match := re.FindStringSubmatch(line)
if match != nil {
c <- match[1]
break
}
}
if err := scanner.Err(); err != nil {
errs <- fmt.Errorf("scan() error: %s", err)
}
}()
select {
case err := <-errs:
logger.Errorf(ctx, "%s", err)
// Timeout after 10 seconds.
case <-time.After(10 * time.Second):
logger.Errorf(ctx, "timed out %s", fPath)
case nodename := <-c:
mapping[nodename] = fPath
}
device.Close()
}
if len(mapping) > 0 {
fmt.Println("device:serial mapping:")
for k, v := range mapping {
fmt.Printf("%s\t%s\n", k, v)
}
} else {
fmt.Println("found nothing!")
}
}