in core/agent_windows.go [166:263]
func (a *amazonSSMAgentService) Execute(args []string, r <-chan svc.ChangeRequest, s chan<- svc.Status) (bool, uint32) {
log := a.log
defer func() {
// recover in case the agent panics
// this should handle some kind of seg fault errors.
if msg := recover(); msg != nil {
log.Errorf("core Agent service crashed with message %v!", msg)
log.Errorf("Stacktrace:\n%s", debug.Stack())
}
}()
log.Info("Waiting for system state")
isSysPrepEC, erro := waitForSysPrep(log)
if !(isSysPrepEC && erro == appconfig.SuccessExitCode) { //returnCode true with success exit code means we can continue to start the agent
log.Warnf("System not ready, not starting agent: isSysPrepEC %v, erro %v", isSysPrepEC, erro)
// In this case, svcSpecificEC = sysPrepEC and so we will return it
return isSysPrepEC, erro
}
log.Info("System is ready")
// notify service controller status is now StartPending
s <- svc.Status{State: svc.StartPending}
// start service
log.Info("Starting up agent subsystem")
agent, contextLog, err := initializeBasicModules(a.log)
if err != nil {
contextLog.Errorf("Failed to start agent. %v", err)
return true, appconfig.ErrorExitCode
}
statusChannels := &contracts.StatusComm{
TerminationChan: make(chan struct{}, 1),
DoneChan: make(chan struct{}, 1),
}
startCoreAgent(contextLog, agent, statusChannels)
contextLog.Info("Notifying windows service manager for agent subsystem start")
// update service status to Running
const acceptCmds = svc.AcceptStop | svc.AcceptShutdown
s <- svc.Status{State: svc.Running, Accepts: acceptCmds}
contextLog.Info("Windows service manager notified that agent service has started")
var (
incomingServiceReq svc.ChangeRequest
incomingServiceReqChan = make(chan svc.ChangeRequest, 1)
terminateIncomingReqThread = make(chan bool, 1)
)
go func() {
incomingReqLoop:
for {
select {
case <-coreAgentStartupErrChan:
contextLog.Error("Failed to start core agent startup module")
statusChannels.DoneChan <- struct{}{}
incomingServiceReqChan <- svc.ChangeRequest{Cmd: svc.Stop}
case incomingServiceReq = <-r:
incomingServiceReqChan <- incomingServiceReq
case <-terminateIncomingReqThread:
contextLog.Info("Incoming service request go routine ended")
break incomingReqLoop
}
}
}()
loop:
// using an infinite loop to wait for ChangeRequests
for {
// block and wait for ChangeRequests
c := <-incomingServiceReqChan
// handle ChangeRequest, svc.Pause is not supported
switch c.Cmd {
case svc.Interrogate:
contextLog.Debug("Service received interrogate ChangeRequest")
s <- c.CurrentStatus
// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
time.Sleep(100 * time.Millisecond)
s <- c.CurrentStatus
case svc.Stop:
statusChannels.TerminationChan <- struct{}{}
contextLog.Info("Service received stop ChangeRequest")
break loop
case svc.Shutdown:
statusChannels.TerminationChan <- struct{}{}
contextLog.Info("Service received shutdown ChangeRequest")
break loop
default:
continue loop
}
}
s <- svc.Status{State: svc.StopPending}
terminateIncomingReqThread <- true
<-statusChannels.DoneChan
agent.Stop()
return false, appconfig.SuccessExitCode
}