diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2016-11-25 17:11:56 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2016-11-25 17:11:56 +0100 |
| commit | 9d672cd451330195801dfd01395e9d4818037f5d (patch) | |
| tree | bf600209c4ea86c7a330a884cf0774c179b87c8e | |
| parent | 9604794dce636f25332e4efcdbd6ac9195d94f9b (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.go | 2 | ||||
| -rw-r--r-- | fileutil/fileutil.go | 14 | ||||
| -rw-r--r-- | fileutil/fileutil_test.go | 27 |
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) } }() } |
