diff --git a/cmd/enit/main.go b/cmd/enit/main.go index e3d5196..fb1fc55 100644 --- a/cmd/enit/main.go +++ b/cmd/enit/main.go @@ -10,6 +10,7 @@ import ( "path" "strconv" "syscall" + "time" ) // Build-time variables @@ -94,6 +95,39 @@ func startServiceManager() { fmt.Println("Done") } +func stopServiceManager() { + fmt.Println("Stopping service manager... ") + + err := syscall.Kill(serviceManagerPid, syscall.SIGTERM) + if err != nil { + log.Println("Could not stop service manager!") + } + // Check if service manager has stopped gracefully, otherwise send sigkill on timeout + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() + timer := time.NewTimer(5 * time.Second) + defer timer.Stop() + select { + case <-timer.C: + log.Println("Could not stop service manager!") + err := syscall.Kill(serviceManagerPid, syscall.SIGKILL) + if err != nil { + log.Println("Could not stop service manager!") + } + case <-ticker.C: + p, err := os.FindProcess(serviceManagerPid) + if err != nil { + break + } + err = p.Signal(syscall.Signal(0)) + if err != nil { + break + } + } + + fmt.Print("Done.") +} + func waitZombieProcesses() { for { if wpid, _ := syscall.Wait4(-1, nil, syscall.WNOHANG, nil); wpid <= 0 { @@ -141,17 +175,13 @@ func catchSignals() { func shutdownSystem() { fmt.Println("Shutting down...") - fmt.Println("Stopping services... ") - err := syscall.Kill(serviceManagerPid, syscall.SIGTERM) - if err != nil { - log.Println("Could not stop service manager!") - panic(err) - } - fmt.Print("Done.") + stopServiceManager() + + fmt.Println("Syncing disks...") + syscall.Sync() fmt.Println("Sending shutdown syscall...") - syscall.Sync() - err = syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF) + err := syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF) if err != nil { panic(err) } @@ -160,17 +190,13 @@ func shutdownSystem() { func rebootSystem() { fmt.Println("Rebooting...") - fmt.Println("Stopping service manager... ") - err := syscall.Kill(serviceManagerPid, syscall.SIGTERM) - if err != nil { - log.Println("Could not stop service manager!") - panic(err) - } - fmt.Print("Done.") + stopServiceManager() + + fmt.Println("Syncing disks...") + syscall.Sync() fmt.Println("Sending reboot syscall...") - syscall.Sync() - err = syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART) + err := syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART) if err != nil { panic(err) } diff --git a/cmd/esvm/main.go b/cmd/esvm/main.go index 2aa5f3a..b2ab7cb 100644 --- a/cmd/esvm/main.go +++ b/cmd/esvm/main.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" "syscall" + "time" ) type EnitServiceState uint8 @@ -229,7 +230,7 @@ func (service *EnitService) StartService() error { return nil } - cmd := exec.Command("/bin/sh", "-c", service.StartCmd) + cmd := exec.Command("/bin/sh", "-c", "exec "+service.StartCmd) if err := cmd.Start(); err != nil { return err } @@ -271,10 +272,28 @@ func (service *EnitService) StopService() error { return nil } go func() { service.stopChannel <- true }() - err := service.GetProcess().Kill() + + err := service.GetProcess().Signal(syscall.SIGTERM) if err != nil { return err } + + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() + timer := time.NewTimer(5 * time.Second) + defer timer.Stop() + + select { + case <-timer.C: + err := service.GetProcess().Kill() + if err != nil { + return err + } + case <-ticker.C: + if service.GetProcess() == nil { + break + } + } } else { cmd := exec.Command("/bin/sh", "-c", service.StopCmd) if err := cmd.Run(); err != nil { @@ -307,39 +326,6 @@ func (service *EnitService) RestartService() error { return nil } -func checkForServiceCommand() { - for _, service := range Services { - if _, err := os.Stat(path.Join(service.ServiceRunPath, "start")); err == nil { - err := service.StartService() - if err != nil { - return - } - err = os.Remove(path.Join(service.ServiceRunPath, "start")) - if err != nil { - return - } - } else if _, err := os.Stat(path.Join(service.ServiceRunPath, "stop")); err == nil { - err := service.StopService() - if err != nil { - return - } - err = os.Remove(path.Join(service.ServiceRunPath, "stop")) - if err != nil { - return - } - } else if _, err := os.Stat(path.Join(service.ServiceRunPath, "restart")); err == nil { - err := service.RestartService() - if err != nil { - return - } - err = os.Remove(path.Join(service.ServiceRunPath, "restart")) - if err != nil { - return - } - } - } -} - func listenToSocket() { conn, err := socket.Accept() if err != nil {