diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index 99054da..45292b4 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -449,6 +449,23 @@ func initCLI() { if doTasks([]task{{s.Stop, true}}) { p.router.Cleanup() p.resetDNS() + if router.WaitProcessExited() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + for { + select { + case <-ctx.Done(): + mainLog.Load().Error().Msg("timeout while waiting for service to stop") + return + default: + } + time.Sleep(time.Second) + if status, _ := s.Status(); status == service.StatusStopped { + break + } + } + } mainLog.Load().Notice().Msg("Service stopped") } }, diff --git a/internal/router/openwrt/procd.go b/internal/router/openwrt/procd.go index 8e74461..bf7253e 100644 --- a/internal/router/openwrt/procd.go +++ b/internal/router/openwrt/procd.go @@ -18,6 +18,7 @@ start_service() { procd_set_param stdout 1 # forward stdout of the command to logd procd_set_param stderr 1 # same for stderr procd_set_param pidfile ${pid_file} # write a pid file on instance start and remove it on stop + procd_set_param term_timeout 10 procd_close_instance echo "${name} has been started" } diff --git a/internal/router/router.go b/internal/router/router.go index 18b7a90..bf65e6e 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -98,6 +98,11 @@ func IsOldOpenwrt() bool { return cmd == "" } +// WaitProcessExited reports whether the "ctrld stop" command have to wait until ctrld process exited. +func WaitProcessExited() bool { + return Name() == openwrt.Name +} + var routerPlatform atomic.Pointer[router] type router struct {