func readLibvirtPysicalMachine(hosts []*PhysicalMachine) { /* get libvirt connections */ numLiveHost := 0 var conn libvirt.VirConnection /* use this type in chanStruct */ type connResult struct { host *PhysicalMachine conn libvirt.VirConnection existing bool } connChan := make(chan connResult) var numGoroutines = 0 for _, host := range hosts { ok := ipaddressConnectionCache.Check(host.IpAddress) if ok == false { numGoroutines++ go func(host *PhysicalMachine) { conn, err := libvirt.NewVirConnection("qemu+ssh://root@" + host.IpAddress + "/system") if err != nil { checkErr(err, fmt.Sprintf("failed to connect to %s", host.IpAddress)) host.Existing = false connChan <- connResult{host: host, existing: false} return } connChan <- connResult{host: host, conn: conn, existing: true} }(host) } else { /* existing a conn which is alive */ conn = ipaddressConnectionCache.Get(host.IpAddress).(libvirt.VirConnection) if ok, _ := conn.IsAlive(); ok { host.VirConn = conn host.Existing = true numLiveHost++ /* existing a conn which is dead */ } else { log.Printf("remove %s is not alive", host.IpAddress) host.Existing = false ipaddressConnectionCache.Delete(host.IpAddress) /* TODO ?if close the connectin */ conn.CloseConnection() } } } for i := 0; i < numGoroutines; i++ { r := <-connChan if r.existing { r.host.VirConn = r.conn r.host.Existing = true /*Write Lock*/ ipaddressConnectionCache.Set(r.host.IpAddress, r.conn) numLiveHost++ } } /* all the PhysicalMachines are ready, VirConnection was connected now */ /* receive data from VirConnections */ done := make(chan bool) for _, host := range hosts { if host.Existing == false { continue } go func(host *PhysicalMachine) { domains, _ := host.VirConn.ListAllDomains() for _, virdomain := range domains { vm := fillVmData(virdomain, conn) vm.HostIpAddress = host.IpAddress if vm.Active == true { vm.VNCAddress = host.IpAddress } //will not have any operations on vm, virdomain could be freeed virdomain.Free() host.VirtualMachines = append(host.VirtualMachines, &vm) } done <- true }(host) } /* wait for all ListAllDomains finish */ for i := 0; i < numLiveHost; i++ { <-done } }