[CRIU] [PATCH v2 05/11] uffdd: Implement --daemon mode
Mike Rapoport
rppt at linux.vnet.ibm.com
Sun Nov 13 01:52:38 PST 2016
From: Pavel Emelyanov <xemul at virtuozzo.com>
Right now the zdtm.py hacks around core code and waits for
a second for the socket to appear. Let's better make proper
--daemon mode for lazy-pages daemon and pidfile generation.
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
Acked-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/crtools.c | 2 +-
criu/include/crtools.h | 2 +-
criu/uffd.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
test/zdtm.py | 12 +++---------
4 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/criu/crtools.c b/criu/crtools.c
index 72718cb..710059f 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -751,7 +751,7 @@ int main(int argc, char *argv[], char *envp[])
}
if (!strcmp(argv[optind], "lazy-pages"))
- return cr_lazy_pages() != 0;
+ return cr_lazy_pages(opts.daemon_mode) != 0;
if (!strcmp(argv[optind], "check"))
return cr_check() != 0;
diff --git a/criu/include/crtools.h b/criu/include/crtools.h
index 0e26716..efd84ae 100644
--- a/criu/include/crtools.h
+++ b/criu/include/crtools.h
@@ -22,7 +22,7 @@ extern int convert_to_elf(char *elf_path, int fd_core);
extern int cr_check(void);
extern int cr_exec(int pid, char **opts);
extern int cr_dedup(void);
-extern int cr_lazy_pages(void);
+extern int cr_lazy_pages(bool daemon);
extern int check_add_feature(char *arg);
extern void pr_check_features(const char *offset, const char *sep, int width);
diff --git a/criu/uffd.c b/criu/uffd.c
index 1d629a3..85d9025 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -15,12 +15,13 @@
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/epoll.h>
+#include <sys/wait.h>
#include "linux/userfaultfd.h"
#include "int.h"
#include "page.h"
-#include "log.h"
+#include "criu-log.h"
#include "criu-plugin.h"
#include "pagemap.h"
#include "files-reg.h"
@@ -840,12 +841,9 @@ static int epoll_add_fd(int epollfd, int fd)
return 0;
}
-static int prepare_uffds(int epollfd)
+static int prepare_lazy_socket(void)
{
- int i;
int listen;
- int client;
- socklen_t len;
struct sockaddr_un saddr;
if (prepare_sock_addr(&saddr))
@@ -857,6 +855,16 @@ static int prepare_uffds(int epollfd)
return -1;
}
+ return listen;
+}
+
+static int prepare_uffds(int listen, int epollfd)
+{
+ int i;
+ int client;
+ socklen_t len;
+ struct sockaddr_un saddr;
+
/* accept new client request */
len = sizeof(struct sockaddr_un);
if ((client = accept(listen, (struct sockaddr *) &saddr, &len)) < 0) {
@@ -887,10 +895,11 @@ close_uffd:
return -1;
}
-int cr_lazy_pages()
+int cr_lazy_pages(bool daemon)
{
struct epoll_event *events;
int epollfd;
+ int lazy_sk;
int ret;
if (check_for_uffd())
@@ -901,11 +910,35 @@ int cr_lazy_pages()
if (lazy_pages_prepare_pstree())
return -1;
+ lazy_sk = prepare_lazy_socket();
+ if (lazy_sk < 0)
+ return -1;
+
+ if (daemon) {
+ ret = cr_daemon(1, 0, &lazy_sk, -1);
+ if (ret == -1) {
+ pr_err("Can't run in the background\n");
+ return -1;
+ }
+ if (ret > 0) { /* parent task, daemon started */
+ if (opts.pidfile) {
+ if (write_pidfile(ret) == -1) {
+ pr_perror("Can't write pidfile");
+ kill(ret, SIGKILL);
+ waitpid(ret, NULL, 0);
+ return -1;
+ }
+ }
+
+ return 0;
+ }
+ }
+
epollfd = prepare_epoll(task_entries->nr_tasks, &events);
if (epollfd < 0)
return -1;
- if (prepare_uffds(epollfd))
+ if (prepare_uffds(lazy_sk, epollfd))
return -1;
if (connect_to_page_server())
diff --git a/test/zdtm.py b/test/zdtm.py
index 0d8503f..3bd9010 100755
--- a/test/zdtm.py
+++ b/test/zdtm.py
@@ -679,8 +679,6 @@ class criu_cli:
print "Forcing %s fault" % fault
env = dict(os.environ, CRIU_FAULT = fault)
cr = subprocess.Popen(strace + [criu_bin, action] + args, env = env, preexec_fn = preexec)
- if action == "lazy-pages":
- return cr
return cr.wait()
@@ -839,8 +837,6 @@ class criu:
__ddir = self.__ddir()
ret = self.__criu.run(action, s_args, self.__fault, strace, preexec)
- if action == "lazy-pages":
- return ret
grep_errors(os.path.join(__ddir, log))
if ret != 0:
@@ -927,11 +923,9 @@ class criu:
r_opts.append('--external')
r_opts.append('mnt[zdtm]:%s' % criu_dir)
- lazy_pages_p = None
if self.__lazy_pages:
- lazy_pages_p = self.__criu_act("lazy-pages", opts = [])
+ self.__criu_act("lazy-pages", opts = ["--daemon", "--pidfile", "lp.pid"])
r_opts += ["--lazy-pages"]
- time.sleep(1) # FIXME wait user fault fd socket
if self.__leave_stopped:
r_opts += ['--leave-stopped']
@@ -942,8 +936,8 @@ class criu:
pstree_check_stopped(self.__test.getpid())
pstree_signal(self.__test.getpid(), signal.SIGCONT)
- if lazy_pages_p and lazy_pages_p.wait():
- raise test_fail_exc("CRIU lazy-pages")
+ if self.__lazy_pages:
+ wait_pid_die(int(rpidfile(self.__ddir() + "/lp.pid")), "lazy pages daemon")
@staticmethod
def check(feature):
--
1.9.1
More information about the CRIU
mailing list