aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-11-25 17:11:56 +0100
committerDmitry Vyukov <dvyukov@google.com>2016-11-25 17:11:56 +0100
commit9d672cd451330195801dfd01395e9d4818037f5d (patch)
treebf600209c4ea86c7a330a884cf0774c179b87c8e
parent9604794dce636f25332e4efcdbd6ac9195d94f9b (diff)
config: use dense indices for VMs
CreateVMConfig uses fileutil.ProcessTempDir to assign indices to VMs. fileutil.ProcessTempDir generates unique indices globally across several processes. This was required for old vm/qemu code that used the index to choose unique ssh port for the VM. Now vm/qemu does not use index as port and this global index assignment started causing problems for adb and gce. Adb really needs indexes to be dense -- index is used to choose adb device id (if we have 2 devices, index 3 causes out of bounds panic). For gce it leads to creation of unnecessary VM instances (if I set count=4, I want at most 4 VMs created). Don't use fileutil.ProcessTempDir-generated index in CreateVMConfig and instead just use the dense indices passed by caller.
-rw-r--r--config/config.go2
-rw-r--r--fileutil/fileutil.go14
-rw-r--r--fileutil/fileutil_test.go27
3 files changed, 14 insertions, 29 deletions
diff --git a/config/config.go b/config/config.go
index 9a8562912..103238f0a 100644
--- a/config/config.go
+++ b/config/config.go
@@ -250,7 +250,7 @@ func CreateVMConfig(cfg *Config, index int) (*vm.Config, error) {
if index < 0 || index >= cfg.Count {
return nil, fmt.Errorf("invalid VM index %v (count %v)", index, cfg.Count)
}
- workdir, index, err := fileutil.ProcessTempDir(cfg.Workdir)
+ workdir, err := fileutil.ProcessTempDir(cfg.Workdir)
if err != nil {
return nil, fmt.Errorf("failed to create instance temp dir: %v", err)
}
diff --git a/fileutil/fileutil.go b/fileutil/fileutil.go
index b84088354..a522b0a8d 100644
--- a/fileutil/fileutil.go
+++ b/fileutil/fileutil.go
@@ -59,15 +59,15 @@ func WriteTempFile(data []byte) (string, error) {
// ProcessTempDir creates a new temp dir in where and returns its path and an unique index.
// It also cleans up old, unused temp dirs after dead processes.
-func ProcessTempDir(where string) (string, int, error) {
+func ProcessTempDir(where string) (string, error) {
lk := filepath.Join(where, "instance-lock")
lkf, err := syscall.Open(lk, syscall.O_RDWR|syscall.O_CREAT, 0600)
if err != nil {
- return "", 0, err
+ return "", err
}
defer syscall.Close(lkf)
if err := syscall.Flock(lkf, syscall.LOCK_EX); err != nil {
- return "", 0, err
+ return "", err
}
defer syscall.Flock(lkf, syscall.LOCK_UN)
@@ -95,14 +95,14 @@ func ProcessTempDir(where string) (string, int, error) {
continue
}
if err != nil {
- return "", 0, err
+ return "", err
}
if err := ioutil.WriteFile(pidfile, []byte(strconv.Itoa(syscall.Getpid())), 0600); err != nil {
- return "", 0, err
+ return "", err
}
- return path, i, nil
+ return path, nil
}
- return "", 0, fmt.Errorf("too many live instances")
+ return "", fmt.Errorf("too many live instances")
}
// UmountAll recurusively unmounts all mounts in dir.
diff --git a/fileutil/fileutil_test.go b/fileutil/fileutil_test.go
index 4e4b61e11..d432ef5e7 100644
--- a/fileutil/fileutil_test.go
+++ b/fileutil/fileutil_test.go
@@ -4,7 +4,6 @@
package fileutil
import (
- "bytes"
"io/ioutil"
"os"
"path/filepath"
@@ -25,13 +24,10 @@ func TestProcessTempDir(t *testing.T) {
// Pre-create half of the instances with stale pid.
var dirs []string
for i := 0; i < P/2; i++ {
- dir, idx, err := ProcessTempDir(tmp)
+ dir, err := ProcessTempDir(tmp)
if err != nil {
t.Fatalf("failed to create process temp dir")
}
- if idx != i {
- t.Fatalf("unexpected index: want %v, got %v", i, idx)
- }
dirs = append(dirs, dir)
}
for _, dir := range dirs {
@@ -41,34 +37,23 @@ func TestProcessTempDir(t *testing.T) {
}
// Now request a bunch of instances concurrently.
done := make(chan bool)
- indices := make(map[int]bool)
+ allDirs := make(map[string]bool)
var mu sync.Mutex
for p := 0; p < P; p++ {
go func() {
defer func() {
done <- true
}()
- dir, idx, err := ProcessTempDir(tmp)
+ dir, err := ProcessTempDir(tmp)
if err != nil {
t.Fatalf("failed to create process temp dir")
}
mu.Lock()
- present := indices[idx]
- indices[idx] = true
+ present := allDirs[dir]
+ allDirs[dir] = true
mu.Unlock()
if present {
- t.Fatalf("duplicate index %v", idx)
- }
- data := []byte(strconv.Itoa(idx))
- if err := ioutil.WriteFile(filepath.Join(dir, "data"), data, 0600); err != nil {
- t.Fatalf("failed to write data file: %v", err)
- }
- data1, err := ioutil.ReadFile(filepath.Join(dir, "data"))
- if err != nil {
- t.Fatalf("failed to read data file: %v", err)
- }
- if bytes.Compare(data, data1) != 0 {
- t.Fatalf("corrupted data file")
+ t.Fatalf("duplicate dir %v", dir)
}
}()
}