+ service: support "-s reload" command

This commit is contained in:
Simon Zolin 2020-02-18 16:01:32 +03:00
parent fa2f793ac7
commit c77907694d
5 changed files with 70 additions and 2 deletions

View File

@ -528,7 +528,7 @@ func loadOptions() options {
}
o.bindPort = v
}, nil},
{"service", "s", "Service control action: status, install, uninstall, start, stop, restart", func(value string) {
{"service", "s", "Service control action: status, install, uninstall, start, stop, restart, reload (configuration)", func(value string) {
o.serviceControlAction = value
}, nil},
{"logfile", "l", "Path to log file. If empty: write to stdout; if 'syslog': write to system log", func(value string) {

View File

@ -1,9 +1,11 @@
package home
import (
"fmt"
"io/ioutil"
"os"
"runtime"
"strconv"
"strings"
"syscall"
@ -71,6 +73,48 @@ func svcAction(s service.Service, action string) error {
return err
}
// Send SIGHUP to a process with ID taken from our pid-file
// If pid-file doesn't exist, find our PID using 'ps' command
func sendSigReload() {
if runtime.GOOS == "windows" {
log.Error("Not implemented on Windows")
return
}
pidfile := fmt.Sprintf("/var/run/%s.pid", serviceName)
data, err := ioutil.ReadFile(pidfile)
if os.IsNotExist(err) {
code, psdata, err := util.RunCommand("ps", "-C", serviceName, "-o", "pid=")
if err != nil || code != 0 {
log.Error("Can't find AdGuardHome process: %s code:%d", err, code)
return
}
data = []byte(psdata)
} else if err != nil {
log.Error("Can't read PID file %s: %s", pidfile, err)
return
}
parts := strings.SplitN(string(data), "\n", 2)
if len(parts) == 0 {
log.Error("Can't read PID file %s: bad value", pidfile)
return
}
pid, err := strconv.Atoi(parts[0])
if err != nil {
log.Error("Can't read PID file %s: %s", pidfile, err)
return
}
err = util.SendProcessSignal(pid, syscall.SIGHUP)
if err != nil {
log.Error("Can't send signal to PID %d: %s", pid, err)
return
}
log.Debug("Sent signal to PID %d", pid)
}
// handleServiceControlAction one of the possible control actions:
// install -- installs a service/daemon
// uninstall -- uninstalls it
@ -84,6 +128,11 @@ func svcAction(s service.Service, action string) error {
func handleServiceControlAction(action string) {
log.Printf("Service control action: %s", action)
if action == "reload" {
sendSigReload()
return
}
pwd, err := os.Getwd()
if err != nil {
log.Fatal("Unable to find the path to the current directory")

View File

@ -25,3 +25,8 @@ func SetRlimit(val uint) {
func HaveAdminRights() (bool, error) {
return os.Getuid() == 0, nil
}
// SendProcessSignal - send signal to a process
func SendProcessSignal(pid int, sig syscall.Signal) error {
return syscall.Kill(pid, sig)
}

View File

@ -25,3 +25,8 @@ func SetRlimit(val uint) {
func HaveAdminRights() (bool, error) {
return os.Getuid() == 0, nil
}
// SendProcessSignal - send signal to a process
func SendProcessSignal(pid int, sig syscall.Signal) error {
return syscall.Kill(pid, sig)
}

View File

@ -1,6 +1,11 @@
package util
import "golang.org/x/sys/windows"
import (
"fmt"
"syscall"
"golang.org/x/sys/windows"
)
// Set user-specified limit of how many fd's we can use
func SetRlimit(val uint) {
@ -26,3 +31,7 @@ func HaveAdminRights() (bool, error) {
}
return true, nil
}
func SendProcessSignal(pid int, sig syscall.Signal) error {
return fmt.Errorf("not supported on Windows")
}