From a39bbe377c59987dc97ec677b9a907276f38d281 Mon Sep 17 00:00:00 2001 From: anatasluo Date: Thu, 5 Aug 2021 16:10:48 +0800 Subject: [PATCH] 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 --- ...pport-for-nginx-service-dump-restore.patch | 33 +++++ ...-pid-file-after-restore-from-systemd.patch | 113 ++++++++++++++++++ nvwa.spec | 8 +- 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 0007-add-support-for-nginx-service-dump-restore.patch create mode 100644 0008-restore-pid-file-after-restore-from-systemd.patch diff --git a/0007-add-support-for-nginx-service-dump-restore.patch b/0007-add-support-for-nginx-service-dump-restore.patch new file mode 100644 index 0000000..e0e2e88 --- /dev/null +++ b/0007-add-support-for-nginx-service-dump-restore.patch @@ -0,0 +1,33 @@ +From a01224e1cd57813e29ceab256b8acaa906f4e387 Mon Sep 17 00:00:00 2001 +From: anatasluo +Date: Tue, 27 Jul 2021 08:03:19 +0000 +Subject: [PATCH] add support for nginx service dump/restore + +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. + +Signed-off-by: anatasluo +--- + src/server.go | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/server.go b/src/server.go +index 3de06a5..6b5d2c2 100644 +--- a/src/server.go ++++ b/src/server.go +@@ -212,7 +212,7 @@ func loadCmdline() (string, error) { + } + + func getCriuExtPara() []string { +- criuExtPara := []string{"--shell-job"} ++ criuExtPara := []string{"--shell-job", "--enable-external-masters", "--skip-in-flight"} + + enablePM := nvwaRestoreConfig.GetBool("enable_pin_memory") + if enablePM { +-- +2.31.1 + diff --git a/0008-restore-pid-file-after-restore-from-systemd.patch b/0008-restore-pid-file-after-restore-from-systemd.patch new file mode 100644 index 0000000..ead54e4 --- /dev/null +++ b/0008-restore-pid-file-after-restore-from-systemd.patch @@ -0,0 +1,113 @@ +From 710071a871bbaa9f1f514acf0710966e7ae5b53d Mon Sep 17 00:00:00 2001 +From: anatasluo +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 +--- + 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 + diff --git a/nvwa.spec b/nvwa.spec index 62dc427..f8d8a68 100644 --- a/nvwa.spec +++ b/nvwa.spec @@ -1,6 +1,6 @@ Name: nvwa Version: 0.1 -Release: 5 +Release: 6 Summary: a tool used for openEuler kernel update License: MulanPSL-2.0 and Apache-2.0 and MIT and MPL-2.0 @@ -13,6 +13,8 @@ Patch3: 0003-nvwa-move-socket-from-tmp-to-run.patch Patch4: 0004-kexec-add-x.patch Patch5: 0005-nvwa-move-unix-socket-from-run-to-run-nvwa.patch Patch6: 0006-pin-move-pin-from-tools-to-tools-pin.patch +Patch7: 0007-add-support-for-nginx-service-dump-restore.patch +Patch8: 0008-restore-pid-file-after-restore-from-systemd.patch BuildRequires: golang >= 1.13 Requires: kexec-tools criu @@ -80,6 +82,10 @@ install -m 0644 %{_builddir}/%{name}-v%{version}/misc/%{name}-pre.service %{buil %{_bindir}/%{name}-pre.sh %changelog +* Fri 06 Aug 2021 anatasluo - 0.1-6 +- Add "--skip-in-flight" for criu dump/restore +- restore pid file after restore from systemd + * Sat 31 Jul 2021 anatasluo - 0.1-5 - Add necessary patches from version 0.2 - Do kexec before criu dump