diff --git a/pkg/pillar/cmd/domainmgr/domainmgr.go b/pkg/pillar/cmd/domainmgr/domainmgr.go index 269c36b428..026a4f5fca 100644 --- a/pkg/pillar/cmd/domainmgr/domainmgr.go +++ b/pkg/pillar/cmd/domainmgr/domainmgr.go @@ -136,9 +136,20 @@ func (ctx *domainContext) publishAssignableAdapters() { ctx.pubAssignableAdapters.Publish("global", *ctx.assignableAdapters) } +var currentHypervisor hypervisor.Hypervisor +var currentHypervisorMutex sync.Mutex var logger *logrus.Logger var log *base.LogObject +// CurrentHypervisor returns the current hypervisor +func CurrentHypervisor() hypervisor.Hypervisor { + currentHypervisorMutex.Lock() + hv := currentHypervisor + currentHypervisorMutex.Unlock() + + return hv +} + func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, arguments []string) int { logger = loggerArg log = logArg @@ -168,6 +179,9 @@ func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, ar fmt.Printf("%s: %s\n", agentName, Version) return 0 } + currentHypervisorMutex.Lock() + currentHypervisor, err = hypervisor.GetHypervisor(*domainCtx.hypervisorPtr) + currentHypervisorMutex.Unlock() if err != nil { log.Fatal(err) } @@ -175,7 +189,7 @@ func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, ar if err := pidfile.CheckAndCreatePidfile(log, agentName); err != nil { log.Fatal(err) } - log.Functionf("Starting %s with %s hypervisor backend", agentName, hypervisor.CurrentHypervisor().Name()) + log.Functionf("Starting %s with %s hypervisor backend", agentName, CurrentHypervisor().Name()) // Run a periodic timer so we always update StillRunning stillRunning := time.NewTicker(25 * time.Second) @@ -472,7 +486,7 @@ func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, ar capabilitiesSent := false capabilitiesTicker := time.NewTicker(5 * time.Second) - if err := getAndPublishCapabilities(&domainCtx, hypervisor.CurrentHypervisor()); err != nil { + if err := getAndPublishCapabilities(&domainCtx, CurrentHypervisor()); err != nil { log.Warnf("getAndPublishCapabilities: %v", err) } else { capabilitiesSent = true @@ -480,7 +494,7 @@ func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, ar } log.Functionf("Creating %s at %s", "metricsTimerTask", agentlog.GetMyStack()) - go metricsTimerTask(&domainCtx, hypervisor.CurrentHypervisor()) + go metricsTimerTask(&domainCtx, CurrentHypervisor()) // Before starting to process DomainConfig, domainmgr should (in this order): // 1. wait for NIM to publish DNS to learn which ports are used for management @@ -516,7 +530,7 @@ func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, ar publishProcessesHandler(&domainCtx) case <-capabilitiesTicker.C: - if err := getAndPublishCapabilities(&domainCtx, hypervisor.CurrentHypervisor()); err != nil { + if err := getAndPublishCapabilities(&domainCtx, CurrentHypervisor()); err != nil { log.Warnf("getAndPublishCapabilities: %v", err) } else { capabilitiesSent = true @@ -542,7 +556,7 @@ func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, ar var resources types.HostMemory for i := 0; true; i++ { delay := 10 - resources, err = hypervisor.CurrentHypervisor().GetHostCPUMem() + resources, err = CurrentHypervisor().GetHostCPUMem() if err == nil { break } @@ -930,7 +944,7 @@ func verifyStatus(ctx *domainContext, status *types.DomainStatus) { configActivate = true } - domainID, domainStatus, err := hypervisor.CurrentHypervisor().Task(status).Info(status.DomainName) + domainID, domainStatus, err := CurrentHypervisor().Task(status).Info(status.DomainName) if err != nil || domainStatus == types.HALTED { if status.Activated && configActivate { if err == nil { @@ -963,10 +977,10 @@ func verifyStatus(ctx *domainContext, status *types.DomainStatus) { } //cleanup app instance tasks - if err := hypervisor.CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { log.Errorf("failed to delete domain: %s (%v)", status.DomainName, err) } - if err := hypervisor.CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { log.Errorf("failed to cleanup domain: %s (%v)", status.DomainName, err) } } @@ -1104,7 +1118,7 @@ func maybeRetryBoot(ctx *domainContext, status *types.DomainStatus) { } defer file.Close() - if err := hypervisor.CurrentHypervisor().Task(status).Setup(*status, *config, ctx.assignableAdapters, nil, file); err != nil { + if err := CurrentHypervisor().Task(status).Setup(*status, *config, ctx.assignableAdapters, nil, file); err != nil { //it is retry, so omit error log.Errorf("Failed to create DomainStatus from %v: %s", config, err) @@ -1383,14 +1397,14 @@ func doAssignIoAdaptersToDomain(ctx *domainContext, config types.DomainConfig, } for i, long := range assignmentsPci { - err := hypervisor.CurrentHypervisor().PCIReserve(long) + err := CurrentHypervisor().PCIReserve(long) if err != nil { // Undo what we assigned for j, long := range assignmentsPci { if j >= i { break } - hypervisor.CurrentHypervisor().PCIRelease(long) + CurrentHypervisor().PCIRelease(long) } if publishAssignableAdapters { ctx.publishAssignableAdapters() @@ -1567,7 +1581,7 @@ func doActivate(ctx *domainContext, config types.DomainConfig, defer file.Close() globalConfig := agentlog.GetGlobalConfig(log, ctx.subGlobalConfig) - if err := hypervisor.CurrentHypervisor().Task(status).Setup(*status, config, ctx.assignableAdapters, globalConfig, file); err != nil { + if err := CurrentHypervisor().Task(status).Setup(*status, config, ctx.assignableAdapters, globalConfig, file); err != nil { log.Errorf("Failed to create DomainStatus from %v: %s", config, err) status.SetErrorNow(err.Error()) @@ -1626,17 +1640,17 @@ func doActivateTail(ctx *domainContext, status *types.DomainStatus, status.State = types.BOOTING publishDomainStatus(ctx, status) - err := hypervisor.CurrentHypervisor().Task(status).Start(status.DomainName) + err := CurrentHypervisor().Task(status).Start(status.DomainName) if err != nil { log.Errorf("domain start for %s: %s", status.DomainName, err) status.SetErrorNow(err.Error()) // Delete - if err := hypervisor.CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { log.Errorf("failed to delete domain: %s (%v)", status.DomainName, err) } // Cleanup - if err := hypervisor.CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { log.Errorf("failed to cleanup domain: %s (%v)", status.DomainName, err) } @@ -1650,7 +1664,7 @@ func doActivateTail(ctx *domainContext, status *types.DomainStatus, status.VifList = checkIfEmu(status.VifList) status.State = types.RUNNING - domainID, state, err := hypervisor.CurrentHypervisor().Task(status).Info(status.DomainName) + domainID, state, err := CurrentHypervisor().Task(status).Info(status.DomainName) if err != nil { // Immediate failure treat as above @@ -1661,11 +1675,11 @@ func doActivateTail(ctx *domainContext, status *types.DomainStatus, log.Errorf("doActivateTail(%v) failed for %s: %s", status.UUIDandVersion, status.DisplayName, err) // Delete - if err := hypervisor.CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { log.Errorf("failed to delete domain: %s (%v)", status.DomainName, err) } // Cleanup - if err := hypervisor.CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { log.Errorf("failed to cleanup domain: %s (%v)", status.DomainName, err) } return @@ -1710,7 +1724,7 @@ func doInactivate(ctx *domainContext, status *types.DomainStatus, impatient bool log.Functionf("doInactivate(%v) for %s domainId %d", status.UUIDandVersion, status.DisplayName, status.DomainId) - domainID, _, err := hypervisor.CurrentHypervisor().Task(status).Info(status.DomainName) + domainID, _, err := CurrentHypervisor().Task(status).Info(status.DomainName) if err == nil && domainID != status.DomainId { status.DomainId = domainID status.BootTime = time.Now() @@ -1784,7 +1798,7 @@ func doInactivate(ctx *domainContext, status *types.DomainStatus, impatient bool } if status.DomainId != 0 { - if err := hypervisor.CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Delete(status.DomainName); err != nil { log.Errorf("Failed to delete domain %s (%v)", status.DomainName, err) } else { log.Functionf("doInactivate(%v) for %s: Delete succeeded", @@ -1802,7 +1816,7 @@ func doInactivate(ctx *domainContext, status *types.DomainStatus, impatient bool } func doCleanup(ctx *domainContext, status *types.DomainStatus) { - if err := hypervisor.CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { + if err := CurrentHypervisor().Task(status).Cleanup(status.DomainName); err != nil { log.Errorf("failed to cleanup domain: %s (%v)", status.DomainName, err) } @@ -1906,7 +1920,7 @@ func releaseAdapters(ctx *domainContext, ioAdapterList []types.IoAdapter, checkIoBundleAll(ctx) } for _, long := range assignments { - err := hypervisor.CurrentHypervisor().PCIRelease(long) + err := CurrentHypervisor().PCIRelease(long) if err != nil && !ignoreErrors { status.SetErrorNow(err.Error()) } @@ -2275,7 +2289,7 @@ func waitForDomainGone(status types.DomainStatus, maxDelay time.Duration) bool { time.Sleep(delay) waited += delay } - _, state, err := hypervisor.CurrentHypervisor().Task(&status).Info(status.DomainName) + _, state, err := CurrentHypervisor().Task(&status).Info(status.DomainName) if err != nil { log.Errorf("waitForDomainGone(%v) for %s error %s state %s", status.UUIDandVersion, status.DisplayName, @@ -2363,7 +2377,7 @@ func DomainCreate(ctx *domainContext, status types.DomainStatus) (int, error) { log.Errorf("DomainCreate(%s) no DomainConfig", status.Key()) return 0, fmt.Errorf("DomainCreate(%s) no DomainConfig", status.Key()) } - domainID, err = hypervisor.CurrentHypervisor().Task(&status).Create(status.DomainName, filename, config) + domainID, err = CurrentHypervisor().Task(&status).Create(status.DomainName, filename, config) return domainID, err } @@ -2376,7 +2390,7 @@ func DomainShutdown(status types.DomainStatus, force bool) error { // Stop the domain log.Functionf("Stopping domain - %s", status.DomainName) - err = hypervisor.CurrentHypervisor().Task(&status).Stop(status.DomainName, force) + err = CurrentHypervisor().Task(&status).Stop(status.DomainName, force) return err } @@ -2833,7 +2847,7 @@ func handlePhysicalIOAdapterListImpl(ctxArg interface{}, key string, len(aa.IoBundleList)) // check for mismatched PCI-ids and assignment groups and mark as errors - aa.CheckBadAssignmentGroups(log, hypervisor.CurrentHypervisor().PCISameController) + aa.CheckBadAssignmentGroups(log, CurrentHypervisor().PCISameController) for i := range aa.IoBundleList { ib := &aa.IoBundleList[i] log.Functionf("handlePhysicalIOAdapterListImpl: new Adapter: %+v", @@ -2878,7 +2892,7 @@ func handlePhysicalIOAdapterListImpl(ctxArg interface{}, key string, aa.AddOrUpdateIoBundle(log, *ib) // check for mismatched PCI-ids and assignment groups and mark as errors - aa.CheckBadAssignmentGroups(log, hypervisor.CurrentHypervisor().PCISameController) + aa.CheckBadAssignmentGroups(log, CurrentHypervisor().PCISameController) // Lookup since it could have changed ib = aa.LookupIoBundlePhylabel(ib.Phylabel) updatePortAndPciBackIoBundle(ctx, ib) @@ -2979,7 +2993,7 @@ func updatePortAndPciBackIoBundle(ctx *domainContext, ib *types.IoBundle) (chang // expand list to include other PCI functions on the same PCI controller // since they need to be treated as part of the same bundle even if the // EVE controller doesn't know it - list = aa.ExpandControllers(log, list, hypervisor.CurrentHypervisor().PCISameController) + list = aa.ExpandControllers(log, list, CurrentHypervisor().PCISameController) for _, ib := range list { if types.IsPort(ctx.deviceNetworkStatus, ib.Ifname) { isPort = true @@ -3065,7 +3079,7 @@ func updatePortAndPciBackIoMember(ctx *domainContext, ib *types.IoBundle, isPort if ib.PciLong != "" { log.Functionf("updatePortAndPciBackIoMember: Removing %s (%s) from pciback", ib.Phylabel, ib.PciLong) - err = hypervisor.CurrentHypervisor().PCIRelease(ib.PciLong) + err = CurrentHypervisor().PCIRelease(ib.PciLong) if err != nil { err = fmt.Errorf("adapter %s (group %s, type %d) PCI ID %s; not released by hypervisor: %v", ib.Phylabel, ib.AssignmentGroup, ib.Type, @@ -3112,7 +3126,7 @@ func updatePortAndPciBackIoMember(ctx *domainContext, ib *types.IoBundle, isPort } else if ib.PciLong != "" && ib.UsbAddr == "" { log.Noticef("Assigning %s (%s) to pciback", ib.Phylabel, ib.PciLong) - err := hypervisor.CurrentHypervisor().PCIReserve(ib.PciLong) + err := CurrentHypervisor().PCIReserve(ib.PciLong) if err != nil { return changed, err } @@ -3353,7 +3367,7 @@ func handleIBDelete(ctx *domainContext, phylabel string) { log.Functionf("handleIBDelete: Assigning %s (%s) back", ib.Phylabel, ib.PciLong) if ib.PciLong != "" { - err := hypervisor.CurrentHypervisor().PCIRelease(ib.PciLong) + err := CurrentHypervisor().PCIRelease(ib.PciLong) if err != nil { log.Errorf("handleIBDelete(%d %s %s) PCIRelease %s failed %v", ib.Type, ib.Phylabel, ib.AssignmentGroup, ib.PciLong, err) diff --git a/pkg/pillar/cmd/usbmanager/usbmanager.go b/pkg/pillar/cmd/usbmanager/usbmanager.go index 62b546db4a..4b0ae87420 100644 --- a/pkg/pillar/cmd/usbmanager/usbmanager.go +++ b/pkg/pillar/cmd/usbmanager/usbmanager.go @@ -10,6 +10,7 @@ import ( "github.com/lf-edge/eve/pkg/pillar/agentbase" "github.com/lf-edge/eve/pkg/pillar/base" + "github.com/lf-edge/eve/pkg/pillar/cmd/domainmgr" "github.com/lf-edge/eve/pkg/pillar/hypervisor" "github.com/lf-edge/eve/pkg/pillar/pubsub" "github.com/lf-edge/eve/pkg/pillar/utils" @@ -81,7 +82,7 @@ func Run(ps *pubsub.PubSub, loggerArg *logrus.Logger, logArg *base.LogObject, ar } log.Functionf("processed Vault Status") - currentHypervisor := hypervisor.CurrentHypervisor() + currentHypervisor := domainmgr.CurrentHypervisor() _, ok := currentHypervisor.(hypervisor.KvmContext) if ok { usbCtx.subscribe(ps) diff --git a/pkg/pillar/hypervisor/hypervisor.go b/pkg/pillar/hypervisor/hypervisor.go index 23def56485..d874dd0e05 100644 --- a/pkg/pillar/hypervisor/hypervisor.go +++ b/pkg/pillar/hypervisor/hypervisor.go @@ -4,37 +4,14 @@ package hypervisor import ( - "flag" "fmt" - "log" - "os" - "github.com/lf-edge/eve/pkg/pillar/types" "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/mem" "github.com/sirupsen/logrus" + "os" ) -var currentHypervisor Hypervisor - -func init() { - var err error - - flagSet := flag.NewFlagSet("", flag.ExitOnError) - allHypervisors, enabledHypervisors := GetAvailableHypervisors() - hypervisorPtr := flagSet.String("h", enabledHypervisors[0], fmt.Sprintf("Current hypervisor %+q", allHypervisors)) - - currentHypervisor, err = GetHypervisor(*hypervisorPtr) - if err != nil { - log.Fatal(err) - } -} - -// CurrentHypervisor returns the current hypervisor -func CurrentHypervisor() Hypervisor { - return currentHypervisor -} - // Hypervisor provides methods for manipulating domains on the host type Hypervisor interface { Name() string