From f3dd344026e433ad3a8c515572b0d5ffd8c0c1e1 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Wed, 15 May 2024 22:45:35 +0700 Subject: [PATCH] all: make procd "ctrld stop" blocks until process exited Since procd does not block when init scripts execute stop operation, it causes ctrld command callers (the installer, users ...) thought that ctrld process was exited, while it does not. See: https://forum.openwrt.org/t/procd-shutdown-issues-questions/33759 --- cmd/cli/cli.go | 17 +++++++++++++++++ internal/router/openwrt/procd.go | 1 + internal/router/router.go | 5 +++++ 3 files changed, 23 insertions(+) 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 {