nvwa/0008-restore-pid-file-after-restore-from-systemd.patch
anatasluo a39bbe377c add support for nginx service dump/restore
1. add --skip-in-flight and --enable-external-masters options

For nginx service, it has a mount point in /run/user
which was used by pam_systemd to store non-essential
runtime files or objects(check more info in pam_systemd manpage).

To support dumpping such a mount point, criu needs enable
--enable-external-masters.

For in flight connections, we simply drop it.

2. restore pid file after restore from systemd

When I use systemd to restore nginx service,
I find that systemd will check pid file and it will
timeout since no value can be found in pid file.

To slove this problem, nvwa will supply this value
for systemd.

Signed-off-by: anatasluo <luolongjuna@gmail.com>
2021-08-06 21:37:54 +08:00

114 lines
3.6 KiB
Diff

From 710071a871bbaa9f1f514acf0710966e7ae5b53d Mon Sep 17 00:00:00 2001
From: anatasluo <luolongjuna@gmail.com>
Date: Fri, 6 Aug 2021 11:39:15 +0800
Subject: [PATCH] restore pid file after restore from systemd
When I use systemd to restore nginx service,
I find that systemd will check pid file and it will
timeout since no value can be found in pid file.
To slove this problem, I add a ExecStartPost action to
write back necessary pid file.
Signed-off-by: anatasluo <luolongjuna@gmail.com>
---
src/server.go | 50 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 6 deletions(-)
diff --git a/src/server.go b/src/server.go
index 6b5d2c2..38a0bdb 100644
--- a/src/server.go
+++ b/src/server.go
@@ -50,6 +50,25 @@ func overrideConf(path string, content string) error {
return nil
}
+func getSystemdOptions(service string, option string) (error, string) {
+ return runCmd("systemctl", []string{"show", "--property",
+ option, "--value", service}, nil, nil, nil)
+}
+
+func getPIDFile(service string) (error, string) {
+ err, ret := getSystemdOptions(service, "PIDFile")
+ if err != nil {
+ log.Errorf("Unable to get pid file for service %s\n", service)
+ log.Errorf("Error is %s \n", err)
+ return err, ""
+ }
+
+ log.Debugf("Get pid file for %s - %s \n", service, ret)
+
+ i := strings.Index(ret, "=")
+ return nil, ret[i+1:]
+}
+
func overrideSystemctl(service string, pid int) error {
systemdEtc := nvwaSeverConfig.GetString("systemd_etc")
@@ -57,8 +76,9 @@ func overrideSystemctl(service string, pid int) error {
_ = os.Mkdir(systemdDir, 0700)
content := "[Service]\nExecStart=\nExecStart="
- content += "nvwa restore " + service + " " + strconv.Itoa(pid) + "\n"
+ content += "nvwa restore " + service + "@" + strconv.Itoa(pid) + "\n"
content += "User=root\nGroup=root\n"
+
err := overrideConf(path.Join(systemdDir, "nvwa_override_exec.conf"), content)
if err != nil {
return err
@@ -118,8 +138,7 @@ func findPids(criuPids map[string]int) error {
services := nvwaRestoreConfig.GetStringSlice("services")
for _, val := range services {
- err, tmpRet := runCmd("systemctl", []string{"show", "--property",
- "MainPID", "--value", val}, nil, nil, nil)
+ err, tmpRet := getSystemdOptions(val, "MainPID")
if err != nil {
log.Errorf("Unable to get pid for service %s\n", val)
log.Errorf("Error is %s \n", err)
@@ -356,11 +375,27 @@ func loadConfig() {
readConfig(nvwaRestoreConfig, "nvwa-restore")
}
-func RestoreService(service string) int {
+func RestoreService(cmd string) int {
+ i := strings.Index(cmd, "@")
+ service := cmd[:i]
+ pid := cmd[i+1:]
+
+ log.Debugf("nvwa restore %s %s \n", service, pid)
+
criuExe := nvwaSeverConfig.GetString("criu_exe")
criuDir := nvwaSeverConfig.GetString("criu_dir")
- err, _ := runCmd(criuExe, getCriuPara("restore", path.Join(criuDir, service), ""),
+ err, pidfile := getPIDFile(service)
+ if err != nil {
+ return -1
+ }
+ pidfile = strings.TrimSpace(pidfile)
+ if pidfile != "" {
+ pidData := []byte(pid)
+ _ = ioutil.WriteFile(pidfile, pidData, 0644)
+ }
+
+ err, _ = runCmd(criuExe, getCriuPara("restore", path.Join(criuDir, service), ""),
os.Stdin, os.Stdout, os.Stderr)
if err != nil {
log.Errorf("Restore %s failed, error is %s \n", service, err)
@@ -435,7 +470,10 @@ func ExitServer(msg string) int {
func may_init_socket(path string) error {
socketDir := filepath.Dir(path)
log.Debugf("Socket directory %s \n", socketDir)
- return os.Mkdir(socketDir, 0700)
+ if _, err := os.Stat(socketDir); os.IsNotExist(err) {
+ return os.Mkdir(socketDir, 0700)
+ }
+ return nil
}
func runServer(path string) {
--
2.31.1