diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2015-12-24 12:06:04 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2015-12-24 12:06:04 +0100 |
| commit | 05b38edce28aea69ced072da7e45dd44383afbc3 (patch) | |
| tree | ba4f00ce0959260a199b13ff1d98c69db98947a5 | |
| parent | 58509c75a2a2d472855da0683c36d7ef2f1a6c97 (diff) | |
vm/qemu: fix output reading bug
If qemu boot retries several times due to busy tcp port,
it ends up with several output reading goroutines.
That completely messes output.
| -rw-r--r-- | vm/qemu/qemu.go | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/vm/qemu/qemu.go b/vm/qemu/qemu.go index 6116bcacc..a02a762dc 100644 --- a/vm/qemu/qemu.go +++ b/vm/qemu/qemu.go @@ -5,6 +5,7 @@ package qemu import ( "fmt" + "math/rand" "net" "os" "os/exec" @@ -38,6 +39,19 @@ type instance struct { } func ctor(cfg *vm.Config) (vm.Instance, error) { + for i := 0; ; i++ { + inst, err := ctorImpl(cfg) + if err == nil { + return inst, nil + } + if i < 1000 && strings.Contains(err.Error(), "could not set up host forwarding rule") { + continue + } + return nil, err + } +} + +func ctorImpl(cfg *vm.Config) (vm.Instance, error) { inst := &instance{ cfg: cfg, image: filepath.Join(cfg.Workdir, "image"), @@ -63,16 +77,10 @@ func ctor(cfg *vm.Config) (vm.Instance, error) { return nil, fmt.Errorf("failed to create pipe: %v", err) } - for i := 0; ; i++ { - err := inst.Boot() - if err == nil { - break - } - if i < 1000 && strings.Contains(err.Error(), "could not set up host forwarding rule") { - continue - } + if err := inst.Boot(); err != nil { return nil, err } + closeInst = nil return inst, nil } @@ -122,7 +130,7 @@ func (inst *instance) Close() { func (inst *instance) Boot() error { for { // Find an unused TCP port. - inst.port = int(time.Now().UnixNano()%(64<<10-1<<10) + 1<<10) + inst.port = rand.Intn(64<<10-1<<10) + 1<<10 ln, err := net.Listen("tcp", fmt.Sprintf("localhost:%v", inst.port)) if err == nil { ln.Close() |
