[CRIU] Another attempt at migration processes
Adrian Reber
adrian at lisas.de
Mon Jul 2 08:03:19 EDT 2012
I have taken the code and changed it to allow migration. For this try I
only changed the restore part to listen on a socket where it receives
all the files needed for the restore process.
On the first host I am dumping the process and on the second host I am
running crtools (with the attached patch applied) like this:
./crtools restore -l 0.0.0.0:10000 -vvv -t 2920
-l|--listen <ip:port> listen on ip:port for incoming restore objects
On the first host I am still transferring the process image manually
like this:
for i in pstree.img reg-files.img remap-fpath.img pipes.img inetsk.img
unixsk.img sk-queues.img eventfd.img eventpoll-tfd.img eventpoll.img
inotify.img inotify-wd.img vmas-2920.img fdinfo-2920.img pipes-data.img
core-2920.img fs-2920.img sigacts-2920.img vmas-2920.img core-2920.img
pages-2920.img itimers-2920.img creds-2920.img mm-2920.img eof ; do
cat dump/$i | nc dest-host 10000 ; done
Using the attached patch I can "migrate" a process without copying all
the files.
The patch is still very rough and meant as an RFC to see if this is
something criu is interested in and if the implementation in way like I
did could be accepted by upstream?
This only works for very simple test program and my biggest problem is
that I have to write the pages*.img file to a temporary file (in
/dev/shm) right now, because I was not able to open a network socket
from restorer.c.
Adrian
-------------- next part --------------
diff --git a/cr-restore.c b/cr-restore.c
index 62e84e8..640732c 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -6,6 +6,7 @@
#include <errno.h>
#include <dirent.h>
#include <string.h>
+#include <netdb.h>
#include <fcntl.h>
@@ -35,6 +36,7 @@
#include "files.h"
#include "pipes.h"
#include "sk-inet.h"
+#include "sk-queue.h"
#include "eventfd.h"
#include "eventpoll.h"
#include "proc_parse.h"
@@ -51,7 +53,35 @@ static struct pstree_item *me;
static LIST_HEAD(tasks);
static int restore_task_with_children(void *);
-static int sigreturn_restore(pid_t pid, struct list_head *vmas, int nr_vmas);
+static int sigreturn_restore(pid_t pid, struct list_head *vmas, int nr_vmas, int socket);
+
+static int open_listen_socket(char *hostname, int portno)
+{
+ int sockfd = -1;
+ struct hostent *server;
+ struct sockaddr_in serveraddr;
+
+ printf("%s\n", __FUNCTION__);
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0)
+ pr_perror("ERROR opening socket");
+
+ server = gethostbyname(hostname);
+ if (server == NULL)
+ pr_perror("ERROR, no such host as %s\n", hostname);
+
+ memset((char *) &serveraddr, 0, sizeof(serveraddr));
+ serveraddr.sin_family = AF_INET;
+ memcpy((char *)&serveraddr.sin_addr.s_addr,(char *)server->h_addr, server->h_length);
+ serveraddr.sin_port = htons(portno);
+
+ if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
+ pr_perror("ERROR connecting\n");
+ printf("listen %d\n", listen(sockfd, 5));
+
+ return sockfd;
+}
static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
{
@@ -67,9 +97,9 @@ static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
return 0;
}
-static int prepare_pstree(void)
+static int _prepare_pstree(int ps_fd)
{
- int ret = 0, ps_fd;
+ int ret = 0;
pr_info("Reading image tree\n");
@@ -82,10 +112,6 @@ static int prepare_pstree(void)
task_entries->nr_tasks = 0;
futex_set(&task_entries->start, CR_STATE_FORKING);
- ps_fd = open_image_ro(CR_FD_PSTREE);
- if (ps_fd < 0)
- return ps_fd;
-
while (1) {
struct pstree_entry e;
struct pstree_item *pi;
@@ -137,6 +163,19 @@ static int prepare_pstree(void)
if (!ret)
futex_set(&task_entries->nr_in_progress, task_entries->nr_tasks);
+ return ret;
+}
+
+static int prepare_pstree(void)
+{
+ int ps_fd, ret;
+
+ ps_fd = open_image_ro(CR_FD_PSTREE);
+ if (ps_fd < 0)
+ return ps_fd;
+
+ ret = _prepare_pstree(ps_fd);
+
close(ps_fd);
return ret;
}
@@ -199,13 +238,27 @@ static int prepare_shared(void)
return ret;
}
-static int read_and_open_vmas(int pid, struct list_head *vmas, int *nr_vmas)
+static int read_and_open_vmas(int pid, struct list_head *vmas, int *nr_vmas, int socket)
{
int fd, ret = -1;
+ int n;
+ u32 magic;
- fd = open_image_ro(CR_FD_VMAS, pid);
- if (fd < 0)
- return fd;
+ if (socket == -1) {
+ fd = open_image_ro(CR_FD_VMAS, pid);
+ if (fd < 0)
+ return fd;
+ } else {
+ printf("%s2\n", __FUNCTION__);
+ fd = accept(socket, NULL, NULL);
+ printf("fd %d\n", fd);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ }
*nr_vmas = 0;
while (1) {
@@ -250,30 +303,45 @@ static int read_and_open_vmas(int pid, struct list_head *vmas, int *nr_vmas)
return ret;
}
-static int prepare_and_sigreturn(int pid)
+static int prepare_and_sigreturn(int pid, int socket)
{
int err, nr_vmas;
LIST_HEAD(vma_list);
- err = read_and_open_vmas(pid, &vma_list, &nr_vmas);
+ err = read_and_open_vmas(pid, &vma_list, &nr_vmas, socket);
if (err)
return err;
- return sigreturn_restore(pid, &vma_list, nr_vmas);
+ return sigreturn_restore(pid, &vma_list, nr_vmas, socket);
}
static rt_sigaction_t sigchld_act;
-static int prepare_sigactions(int pid)
+static int prepare_sigactions(int pid, int socket)
{
rt_sigaction_t act, oact;
int fd_sigact;
struct sa_entry e;
int sig;
+ int n;
int ret = -1;
+ u32 magic;
+
+ if (socket == -1) {
+ fd_sigact = open_image_ro(CR_FD_SIGACT, pid);
+ if (fd_sigact < 0)
+ return -1;
+ } else {
+ printf("%s2\n", __FUNCTION__);
+ fd_sigact = accept(socket, NULL, NULL);
+ printf("fd %d\n", fd_sigact);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd_sigact, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ }
- fd_sigact = open_image_ro(CR_FD_SIGACT, pid);
- if (fd_sigact < 0)
- return -1;
for (sig = 1; sig < SIGMAX; sig++) {
if (sig == SIGKILL || sig == SIGSTOP)
@@ -308,20 +376,25 @@ err:
return ret;
}
-static int restore_one_alive_task(int pid)
+static int restore_one_alive_task(int pid, char *host, int port)
{
+ int socket = -1;
+
pr_info("Restoring resources\n");
if (prepare_fds(me))
return -1;
- if (prepare_fs(pid))
+ if (host && port != -1)
+ socket = open_listen_socket(host, port);
+
+ if (prepare_fs(pid, socket))
return -1;
- if (prepare_sigactions(pid))
+ if (prepare_sigactions(pid, socket))
return -1;
- return prepare_and_sigreturn(pid);
+ return prepare_and_sigreturn(pid, socket);
}
static void zombie_prepare_signals(void)
@@ -410,15 +483,35 @@ static int restore_one_zombie(int pid, int exit_code)
return -1;
}
-static int check_core_header(int pid, struct task_core_entry *tc)
+static int check_core_header(int pid, struct task_core_entry *tc, char *host, int port)
{
int fd = -1, ret = -1;
struct image_header hdr;
-
- fd = open_image_ro(CR_FD_CORE, pid);
- if (fd < 0)
- return -1;
-
+ u32 magic;
+ int n;
+ int socket = -1;
+
+ printf("%s\n", __FUNCTION__);
+ if (host && port != -1) {
+ socket = open_listen_socket(host, port);
+ printf("%s2\n", __FUNCTION__);
+ fd = accept(socket, NULL, NULL);
+ perror("blub fd:");
+ printf("fd %d\n", fd);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ } else {
+ fd = open_image_ro(CR_FD_CORE, pid);
+ if (fd < 0)
+ return -1;
+ }
+
+ printf("fd %d\n", fd);
+ printf("%s: before read_img()\n", __FUNCTION__);
if (read_img(fd, &hdr) < 0)
goto out;
@@ -435,19 +528,21 @@ static int check_core_header(int pid, struct task_core_entry *tc)
ret = read_img(fd, tc);
out:
close_safe(&fd);
+ if (socket != -1)
+ close(socket);
return ret < 0 ? ret : 0;
}
-static int restore_one_task(int pid)
+static int restore_one_task(int pid, char *host, int port)
{
struct task_core_entry tc;
- if (check_core_header(pid, &tc))
+ if (check_core_header(pid, &tc, host, port))
return -1;
switch ((int)tc.task_state) {
case TASK_ALIVE:
- return restore_one_alive_task(pid);
+ return restore_one_alive_task(pid, host, port);
case TASK_DEAD:
return restore_one_zombie(pid, tc.exit_code);
default:
@@ -466,9 +561,11 @@ static int restore_one_task(int pid)
struct cr_clone_arg {
int pid, fd;
unsigned long clone_flags;
+ char *host;
+ int port;
};
-static inline int fork_with_pid(int pid, unsigned long ns_clone_flags)
+static inline int fork_with_pid(int pid, unsigned long ns_clone_flags, char *host, int port)
{
int ret = -1;
char buf[32];
@@ -488,6 +585,9 @@ static inline int fork_with_pid(int pid, unsigned long ns_clone_flags)
ca.pid = pid;
ca.clone_flags = ns_clone_flags;
ca.fd = open(LAST_PID_PATH, O_RDWR);
+ ca.port = port;
+ if (host)
+ ca.host = strdup(host);
if (ca.fd < 0) {
pr_perror("%d: Can't open %s", pid, LAST_PID_PATH);
goto err;
@@ -639,7 +739,7 @@ static int restore_task_with_children(void *_arg)
pr_info("Restoring %d children:\n", me->nr_children);
for (i = 0; i < me->nr_children; i++) {
- ret = fork_with_pid(me->children[i], 0);
+ ret = fork_with_pid(me->children[i], 0, NULL, -1);
if (ret < 0)
exit(1);
}
@@ -649,7 +749,7 @@ static int restore_task_with_children(void *_arg)
restore_pgid();
- return restore_one_task(me->pid);
+ return restore_one_task(me->pid, ca->host, ca->port);
}
static int restore_root_task(pid_t pid, struct cr_options *opts)
@@ -686,7 +786,7 @@ static int restore_root_task(pid_t pid, struct cr_options *opts)
* this later.
*/
- ret = fork_with_pid(init->pid, opts->namespaces_flags);
+ ret = fork_with_pid(init->pid, opts->namespaces_flags, opts->host, opts->port);
if (ret < 0)
return -1;
@@ -853,10 +953,24 @@ static int prepare_itimers(int pid, struct task_restore_core_args *args)
{
int fd, ret = -1;
struct itimer_entry ie[3];
+ int n;
+ u32 magic;
- fd = open_image_ro(CR_FD_ITIMERS, pid);
- if (fd < 0)
- return fd;
+ if (args->socket == -1) {
+ fd = open_image_ro(CR_FD_ITIMERS, pid);
+ if (fd < 0)
+ return fd;
+ } else {
+ printf("%s2\n", __FUNCTION__);
+ fd = accept(args->socket, NULL, NULL);
+ printf("fd %d\n", fd);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ }
if (read_img_buf(fd, ie, sizeof(ie)) > 0) {
ret = itimer_restore_and_fix("real",
@@ -876,10 +990,24 @@ static int prepare_itimers(int pid, struct task_restore_core_args *args)
static int prepare_creds(int pid, struct task_restore_core_args *args)
{
int fd, ret;
+ int n;
+ u32 magic;
- fd = open_image_ro(CR_FD_CREDS, pid);
- if (fd < 0)
- return fd;
+ if (args->socket == -1) {
+ fd = open_image_ro(CR_FD_CREDS, pid);
+ if (fd < 0)
+ return fd;
+ } else {
+ printf("%s2\n", __FUNCTION__);
+ fd = accept(args->socket, NULL, NULL);
+ printf("fd %d\n", fd);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ }
ret = read_img(fd, &args->creds);
@@ -916,10 +1044,25 @@ static struct vma_entry *vma_list_remap(void *addr, unsigned long len, struct li
static int prepare_mm(pid_t pid, struct task_restore_core_args *args)
{
int fd, exe_fd;
+ int n;
+ u32 magic;
+
+ if (args->socket == -1) {
+ fd = open_image_ro(CR_FD_MM, pid);
+ if (fd < 0)
+ return -1;
+ } else {
+ printf("%s2\n", __FUNCTION__);
+ fd = accept(args->socket, NULL, NULL);
+ printf("fd %d\n", fd);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ }
- fd = open_image_ro(CR_FD_MM, pid);
- if (fd < 0)
- return -1;
if (read_img(fd, &args->mm) < 0)
return -1;
@@ -934,7 +1077,7 @@ static int prepare_mm(pid_t pid, struct task_restore_core_args *args)
return 0;
}
-static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
+static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas, int socket)
{
long restore_code_len, restore_task_vma_len;
long restore_thread_vma_len, self_vmas_len, vmas_len;
@@ -954,6 +1097,12 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
int fd_core = -1;
int fd_pages = -1;
int i;
+ int n;
+ u32 magic;
+ u8 *tmp;
+ int tmp_fd;
+ char buffer[PATH_MAX];
+ char proc_path[PATH_MAX];
pr_info("Restore via sigreturn\n");
@@ -976,16 +1125,18 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE);
BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE);
- fd_core = open_image_ro(CR_FD_CORE, pid);
- if (fd_core < 0) {
- pr_perror("Can't open core-out-%d", pid);
- goto err;
- }
+ if (socket == -1) {
+ fd_core = open_image_ro(CR_FD_CORE, pid);
+ if (fd_core < 0) {
+ pr_perror("Can't open core-out-%d", pid);
+ goto err;
+ }
- fd_pages = open_image_ro(CR_FD_PAGES, pid);
- if (fd_pages < 0) {
- pr_perror("Can't open pages-%d", pid);
- goto err;
+ fd_pages = open_image_ro(CR_FD_PAGES, pid);
+ if (fd_pages < 0) {
+ pr_perror("Can't open pages-%d", pid);
+ goto err;
+ }
}
restore_code_len = sizeof(restorer_blob);
@@ -1093,6 +1244,85 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
if (!task_args->tgt_vmas)
goto err;
+ if (socket != -1) {
+ printf("%s2\n", __FUNCTION__);
+ fd_core = accept(socket, NULL, NULL);
+ printf("fd %d\n", fd_core);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd_core, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ task_args->core = (u8 *)malloc(1024);
+ tmp = task_args->core;
+ i = 0;
+ while (1) {
+ n = read(fd_core, tmp, 1024);
+
+ if (n == 0)
+ break;
+
+ if (n == -1) {
+ pr_perror("Core read failed");
+ goto err;
+ }
+
+ i += n;
+ printf("realloc now: %p\n", task_args->core);
+ task_args->core = (u8 *)realloc(task_args->core, i+1024);
+ printf("realloc done: %p\n", task_args->core);
+ tmp = task_args->core + i;
+ }
+ task_args->core_size = i;
+ close(fd_core);
+ task_args->pages = (u8 *)malloc(PAGE_SIZE);
+ printf("%p\n", task_args->pages);
+ memset(task_args->pages, 0, PAGE_SIZE);
+
+ printf("%s3\n", __FUNCTION__);
+ fd_pages = accept(socket, NULL, NULL);
+ printf("fd %d\n", fd_pages);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(fd_pages, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ i = 0;
+ printf("mkstemp\n");
+ strcpy(buffer, "/dev/shm/pages-XXXXXX");
+ tmp_fd = mkstemp(buffer);
+ printf("mkstemp done\n");
+ while (1) {
+ printf("about to read\n");
+ n = read(fd_pages, tmp, PAGE_SIZE);
+
+ if (n == 0)
+ break;
+
+ if (n == -1) {
+ pr_perror("Pages read failed");
+ goto err;
+ }
+
+ printf("about to write\n");
+ i = write(tmp_fd, tmp, n);
+ if (i!=n) {
+ pr_perror("Oops, writing failed");
+ goto err;
+ }
+
+ }
+ close(fd_pages);
+ memset(buffer, 0, PATH_MAX);
+ memset(proc_path, 0, PATH_MAX);
+ sprintf(proc_path, "/proc/self/fd/%d", tmp_fd);
+ readlink(proc_path, buffer, PATH_MAX);
+ close(tmp_fd);
+ fd_pages = open(buffer, O_RDONLY);
+ }
+
/*
* Arguments for task restoration.
*/
@@ -1101,6 +1331,7 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
task_args->logfd = log_get_fd();
task_args->sigchld_act = sigchld_act;
task_args->fd_pages = fd_pages;
+ task_args->socket = socket;
ret = prepare_itimers(pid, task_args);
if (ret < 0)
@@ -1116,6 +1347,7 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
mutex_init(&task_args->rst_lock);
+
/*
* Now prepare run-time data for threads restore.
*/
@@ -1189,6 +1421,147 @@ err:
int cr_restore_tasks(pid_t pid, struct cr_options *opts)
{
if (opts->leader_only)
- return restore_one_task(pid);
+ return restore_one_task(pid, NULL, -1);
return restore_all_tasks(pid, opts);
}
+
+int cr_restore_from_socket(pid_t pid, struct cr_options *opts)
+{
+ int sock;
+ u32 magic;
+ int n;
+ int ret = 0;
+ int loop = 1;
+ struct pstree_item *pi;
+ struct inotify_file_info info;
+ struct inotify_wd_info mark;
+
+ pr_info("PID: %d\n", pid);
+
+ opts->socket = open_listen_socket(opts->host, opts->port);
+
+ while(loop) {
+ sock = accept(opts->socket, NULL, NULL);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(sock, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+
+ switch (magic) {
+ case END_MIGRATION_MAGIC:
+ return 0;
+ case PSTREE_MAGIC:
+ pr_info("PSTREE_MAGIC\n");
+ if (_prepare_pstree(sock) < 0) {
+ printf("ups\n");
+ perror("uh oh:");
+ return -1;
+ }
+ pr_info("PSTREE success\n");
+ break;
+
+ case REG_FILES_MAGIC:
+ pr_info("REG_FILES_MAGIC\n");
+ if (prepare_shmem_restore())
+ return -1;
+
+ if (prepare_shared_fdinfo())
+ return -1;
+
+ _collect_reg_files(sock);
+ n = read(sock, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+
+ break;
+ case REMAP_FPATH_MAGIC:
+ pr_info("REMAP_FPATH_MAGIC\n");
+ if (_collect_remaps(sock))
+ return -1;
+ break;
+ case PIPES_MAGIC:
+ pr_info("PIPES_MAGIC\n");
+ if (_collect_pipes(sock))
+ return -1;
+ break;
+ case INETSK_MAGIC:
+ pr_info("INETSK_MAGIC\n");
+ if (_collect_inet_sockets(sock))
+ return -1;
+ break;
+ case UNIXSK_MAGIC:
+ pr_info("UNIXSK_MAGIC\n");
+ _collect_unix_sockets(sock);
+ break;
+ case SK_QUEUES_MAGIC:
+ pr_info("SK_QUEUES_MAGIC\n");
+ if (_read_sk_queues(sock))
+ return -1;
+ break;
+ case EVENTFD_MAGIC:
+ pr_info("EVENTFD_MAGIC\n");
+ if (_collect_eventfd(sock))
+ return -1;
+ break;
+ case EVENTPOLL_TFD_MAGIC:
+ pr_info("EVENTPOLL_TFD_MAGIC\n");
+ if (_collect_eventpoll_tfd(sock))
+ return -1;
+ break;
+ case EVENTPOLL_MAGIC:
+ pr_info("EVENTPOLL_MAGIC\n");
+ if (_collect_eventpoll(sock))
+ return -1;
+ if (collect_mount_info())
+ return -1;
+ break;
+ case INOTIFY_MAGIC:
+ pr_info("INOTIFY_MAGIC\n");
+ if (_collect_inotify(sock, &info))
+ return -1;
+ break;
+ case INOTIFY_WD_MAGIC:
+ pr_info("INOTIFY_WD_MAGIC\n");
+ if (_collect_inotify_wd(sock, &info, &mark))
+ return -1;
+ break;
+ case VMAS_MAGIC:
+ pr_info("VMAS_MAGIC\n");
+
+ list_for_each_entry(pi, &tasks, list) {
+ ret = _prepare_shmem_pid(pi->pid, sock);
+ if (ret < 0)
+ break;
+ }
+ break;
+ case FDINFO_MAGIC:
+ pr_info("FDINFO_MAGIC\n");
+
+ list_for_each_entry(pi, &tasks, list) {
+ ret = _prepare_fd_pid(pi->pid, pi->rst, sock);
+ if (ret < 0)
+ break;
+ }
+ break;
+ case PIPES_DATA_MAGIC:
+ pr_info("PIPES_DATA_MAGIC\n");
+ _mark_pipe_master();
+ _handle_pipes_data(sock);
+
+ ret = resolve_unix_peers();
+
+ if (!ret) {
+ show_saved_shmems();
+ show_saved_files();
+ }
+ loop = 0;
+ break;
+ }
+ close(sock);
+
+ }
+ close(opts->socket);
+
+ return restore_root_task(pid, opts);
+}
diff --git a/crtools.c b/crtools.c
index fc0e010..6d7f844 100644
--- a/crtools.c
+++ b/crtools.c
@@ -207,7 +207,7 @@ int main(int argc, char *argv[])
int log_inited = 0;
int log_level = 0;
- static const char short_opts[] = "dsf:p:t:hcD:o:n:vx";
+ static const char short_opts[] = "dsf:p:t:hcD:o:l:n:vx";
BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
@@ -218,6 +218,9 @@ int main(int argc, char *argv[])
/* Default options */
opts.final_state = TASK_DEAD;
+ opts.host = NULL;
+ opts.port = -1;
+ opts.socket = -1;
while (1) {
static struct option long_opts[] = {
@@ -229,6 +232,7 @@ int main(int argc, char *argv[])
{ "file", required_argument, 0, 'f' },
{ "images-dir", required_argument, 0, 'D' },
{ "log-file", required_argument, 0, 'o' },
+ { "listen", required_argument, 0, 'l' },
{ "namespaces", required_argument, 0, 'n' },
{ "ext-unix-sk", no_argument, 0, 'x' },
{ "help", no_argument, 0, 'h' },
@@ -279,6 +283,17 @@ int main(int argc, char *argv[])
return -1;
log_inited = 1;
break;
+ case 'l':
+ opts.host = strchr(optarg, ':');
+ if (!opts.host)
+ goto usage;
+ /* port needs to be at least one digit long after ':' */
+ if (strlen(optarg) < strchr(optarg, ':') - optarg + 2)
+ goto usage;
+ opts.port = atoi(strchr(optarg, ':') + 1);
+ optarg[strchr(optarg, ':') - optarg] = 0;
+ opts.host = strdup(optarg);
+ break;
case 'n':
if (parse_ns_string(optarg))
return -1;
@@ -351,6 +366,10 @@ int main(int argc, char *argv[])
ret = cr_dump_tasks(pid, &opts);
break;
case 'r':
+ if (opts.host && (opts.port > 0)) {
+ ret = cr_restore_from_socket(pid, &opts);
+ break;
+ }
if (!pid)
goto opt_pid_missing;
ret = cr_restore_tasks(pid, &opts);
@@ -412,6 +431,9 @@ usage:
pr_msg(" -D|--images-dir directory where to get images from\n");
pr_msg(" -c|--contents show contents of pages dumped in hexdump format\n");
+ pr_msg("\nRestore options:\n");
+ pr_msg(" -l|--listen <ip:port> listen on ip:port for incoming restore objects\n");
+
return -1;
opt_pid_missing:
diff --git a/eventfd.c b/eventfd.c
index c6fdf67..cb4fdac 100644
--- a/eventfd.c
+++ b/eventfd.c
@@ -145,13 +145,23 @@ static struct file_desc_ops eventfd_desc_ops = {
int collect_eventfd(void)
{
- struct eventfd_file_info *info = NULL;
int ret, image_fd;
image_fd = open_image_ro(CR_FD_EVENTFD);
if (image_fd < 0)
return -1;
+ ret = _collect_eventfd(image_fd);
+
+ close(image_fd);
+ return ret;
+}
+
+int _collect_eventfd(int image_fd)
+{
+ struct eventfd_file_info *info = NULL;
+ int ret;
+
while (1) {
ret = -1;
@@ -170,6 +180,5 @@ int collect_eventfd(void)
err:
xfree(info);
- close(image_fd);
return ret;
}
diff --git a/eventpoll.c b/eventpoll.c
index 2d380a2..a30652b 100644
--- a/eventpoll.c
+++ b/eventpoll.c
@@ -215,16 +215,36 @@ int collect_eventpoll(void)
if (image_fd < 0)
return -1;
+ ret = _collect_eventpoll_tfd(image_fd);
+ if (ret < 0)
+ goto err;
+
+ close_safe(&image_fd);
+ image_fd = open_image_ro(CR_FD_EVENTPOLL);
+ if (image_fd < 1)
+ return -1;
+
+ ret = _collect_eventpoll(image_fd);
+err:
+ close_safe(&image_fd);
+ return ret;
+}
+
+
+int _collect_eventpoll_tfd(int image_fd)
+{
+ int ret = -1;
+
while (1) {
struct eventpoll_tfd_file_info *info;
info = xmalloc(sizeof(*info));
if (!info)
- goto err;
+ return ret;
ret = read_img_eof(image_fd, &info->tdefe);
if (ret < 0)
- goto err;
+ return ret;
else if (!ret)
break;
@@ -234,22 +254,24 @@ int collect_eventpoll(void)
pr_info_eventpoll_tfd("Collected ", &info->tdefe);
}
- close_safe(&image_fd);
+ return ret;
+}
- image_fd = open_image_ro(CR_FD_EVENTPOLL);
- if (image_fd < 0)
- return -1;
+
+int _collect_eventpoll(int image_fd)
+{
+ int ret = -1;
while (1) {
struct eventpoll_file_info *info;
info = xmalloc(sizeof(*info));
if (!info)
- goto err;
+ return ret;
ret = read_img_eof(image_fd, &info->efe);
if (ret < 0)
- goto err;
+ return ret;
else if (!ret)
break;
@@ -257,7 +279,5 @@ int collect_eventpoll(void)
file_desc_add(&info->d, info->efe.id, &desc_ops);
}
-err:
- close_safe(&image_fd);
return ret;
}
diff --git a/files.c b/files.c
index 1aecd6f..8ea84be 100644
--- a/files.c
+++ b/files.c
@@ -242,13 +242,9 @@ gf_found:
return 0;
}
-static int collect_remaps(void)
+int _collect_remaps(int fd)
{
- int fd, ret = 0;
-
- fd = open_image_ro(CR_FD_REMAP_FPATH);
- if (fd < 0)
- return -1;
+ int ret = 0;
while (1) {
struct remap_file_path_entry rfe;
@@ -282,19 +278,28 @@ static int collect_remaps(void)
break;
}
- close(fd);
return ret;
}
-int collect_reg_files(void)
+int collect_remaps(void)
{
- struct reg_file_info *rfi = NULL;
- int fd, ret = -1;
+ int fd, ret;
- fd = open_image_ro(CR_FD_REG_FILES);
+ fd = open_image_ro(CR_FD_REMAP_FPATH);
if (fd < 0)
return -1;
+ ret = _collect_remaps(fd);
+
+ close(fd);
+ return ret;
+}
+
+void _collect_reg_files(int fd)
+{
+ struct reg_file_info *rfi = NULL;
+ int ret = -1;
+
while (1) {
int len;
@@ -329,6 +334,17 @@ int collect_reg_files(void)
xfree(rfi->path);
xfree(rfi);
}
+}
+
+int collect_reg_files(void)
+{
+ int fd;
+
+ fd = open_image_ro(CR_FD_REG_FILES);
+ if (fd < 0)
+ return -1;
+
+ _collect_reg_files(fd);
close(fd);
@@ -374,10 +390,7 @@ static int collect_fd(int pid, struct fdinfo_entry *e, struct rst_info *rst_info
int prepare_fd_pid(int pid, struct rst_info *rst_info)
{
- int fdinfo_fd, ret = 0;
-
- INIT_LIST_HEAD(&rst_info->fds);
- INIT_LIST_HEAD(&rst_info->eventpoll);
+ int fdinfo_fd, ret;
fdinfo_fd = open_image_ro(CR_FD_FDINFO, pid);
if (fdinfo_fd < 0) {
@@ -387,6 +400,22 @@ int prepare_fd_pid(int pid, struct rst_info *rst_info)
return -1;
}
+ ret = _prepare_fd_pid(pid, rst_info, fdinfo_fd);
+
+ close(fdinfo_fd);
+
+ return ret;
+}
+
+int _prepare_fd_pid(int pid, struct rst_info *rst_info, int fdinfo_fd)
+{
+ int ret = 0;
+
+ printf("_prepare_fd_pid\n");
+
+ INIT_LIST_HEAD(&rst_info->fds);
+ INIT_LIST_HEAD(&rst_info->eventpoll);
+
while (1) {
struct fdinfo_entry e;
@@ -399,7 +428,6 @@ int prepare_fd_pid(int pid, struct rst_info *rst_info)
break;
}
- close(fdinfo_fd);
return ret;
}
@@ -684,14 +712,28 @@ done:
return ret;
}
-int prepare_fs(int pid)
+int prepare_fs(int pid, int socket)
{
int ifd, cwd;
struct fs_entry fe;
-
- ifd = open_image_ro(CR_FD_FS, pid);
- if (ifd < 0)
- return -1;
+ u32 magic;
+ int n;
+
+ if (socket == -1) {
+ ifd = open_image_ro(CR_FD_FS, pid);
+ if (ifd < 0)
+ return -1;
+ } else {
+ printf("%s2\n", __FUNCTION__);
+ ifd = accept(socket, NULL, NULL);
+ printf("fd %d\n", ifd);
+ /* read the first 4 bytes - should be the magic string */
+ n = read(ifd, &magic, sizeof(u32));
+ pr_info("read %d bytes\n", n);
+ if (n != 4)
+ return -1;
+ pr_info("magic: 0x%x\n", magic);
+ }
if (read_img(ifd, &fe) < 0)
return -1;
diff --git a/include/crtools.h b/include/crtools.h
index fdfb59b..ddbf4a0 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -77,6 +77,9 @@ struct cr_options {
unsigned int namespaces_flags;
bool log_file_per_pid;
char *output;
+ char *host;
+ int port;
+ int socket;
};
extern struct cr_options opts;
@@ -147,6 +150,7 @@ extern struct cr_options opts;
int cr_dump_tasks(pid_t pid, const struct cr_options *opts);
int cr_restore_tasks(pid_t pid, struct cr_options *opts);
+int cr_restore_from_socket(pid_t pid, struct cr_options *opts);
int cr_show(struct cr_options *opts);
int convert_to_elf(char *elf_path, int fd_core);
int cr_check(void);
diff --git a/include/eventfd.h b/include/eventfd.h
index 5b10447..0bd044a 100644
--- a/include/eventfd.h
+++ b/include/eventfd.h
@@ -10,6 +10,7 @@
#include "crtools.h"
extern int is_eventfd_link(int lfd);
+extern int _collect_eventfd(int image_fd);
extern int dump_eventfd(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern int collect_eventfd(void);
extern void show_eventfds(int fd, struct cr_options *o);
diff --git a/include/eventpoll.h b/include/eventpoll.h
index 6a619ee..2111820 100644
--- a/include/eventpoll.h
+++ b/include/eventpoll.h
@@ -12,6 +12,8 @@
extern int is_eventpoll_link(int lfd);
extern int dump_eventpoll(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern int collect_eventpoll(void);
+extern int _collect_eventpoll(int fd);
+extern int _collect_eventpoll_tfd(int fd);
extern void show_eventpoll(int fd, struct cr_options *o);
extern void show_eventpoll_tfd(int fd, struct cr_options *o);
diff --git a/include/files.h b/include/files.h
index 2e97c76..0dcfb82 100644
--- a/include/files.h
+++ b/include/files.h
@@ -68,14 +68,18 @@ extern int restore_fown(int fd, fown_t *fown);
int rst_file_params(int fd, fown_t *fown, int flags);
void show_saved_files(void);
+extern int _collect_remaps(int fd);
+extern int collect_remaps(void);
extern int collect_reg_files(void);
+extern void _collect_reg_files(int fd);
struct pstree_item;
extern int prepare_fds(struct pstree_item *);
struct rst_info;
extern int prepare_fd_pid(int pid, struct rst_info *);
+extern int _prepare_fd_pid(int pid, struct rst_info *rst_info, int fdinfo_fd);
extern int prepare_shared_fdinfo(void);
extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
-extern int prepare_fs(int pid);
+extern int prepare_fs(int pid, int socket);
extern int open_reg_by_id(u32 id);
int set_fd_flags(int fd, int flags);
diff --git a/include/image.h b/include/image.h
index 3e5f36d..e183f2c 100644
--- a/include/image.h
+++ b/include/image.h
@@ -40,6 +40,7 @@
#define INOTIFY_MAGIC 0x48424431 /* Volgograd */
#define INOTIFY_WD_MAGIC 0x54562009 /* Svetlogorsk (Rauschen) */
#define MOUNTPOINTS_MAGIC 0x55563928 /* Petushki */
+#define END_MIGRATION_MAGIC 0x44444443
enum fd_types {
FDINFO_UND,
diff --git a/include/inotify.h b/include/inotify.h
index d6665c6..7cc72ec 100644
--- a/include/inotify.h
+++ b/include/inotify.h
@@ -9,9 +9,23 @@
#include "files.h"
#include "crtools.h"
+struct inotify_wd_info {
+ struct list_head list;
+ struct inotify_wd_entry iwe;
+};
+
+struct inotify_file_info {
+ struct list_head list;
+ struct inotify_file_entry ife;
+ struct list_head marks;
+ struct file_desc d;
+};
+
extern int is_inotify_link(int lfd);
extern int dump_inotify(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern int collect_inotify(void);
+extern int _collect_inotify(int fd, struct inotify_file_info *info);
+extern int _collect_inotify_wd(int fd, struct inotify_file_info *info, struct inotify_wd_info *mark);
extern void show_inotify_wd(int fd_inotify_wd, struct cr_options *o);
extern void show_inotify(int fd_inotify, struct cr_options *o);
diff --git a/include/pipes.h b/include/pipes.h
index e3bc2fb..51e535d 100644
--- a/include/pipes.h
+++ b/include/pipes.h
@@ -1,7 +1,10 @@
#ifndef __CR_PIPES_H__
#define __CR_PIPES_H__
extern int collect_pipes(void);
+extern int _collect_pipes(int fd);
extern void mark_pipe_master(void);
+extern void _mark_pipe_master(void);
+extern int _handle_pipes_data(int fd);
int init_pipes_dump(void);
void fini_pipes_dump(void);
int dump_pipe(struct fd_parms *p, int lfd,
diff --git a/include/restorer.h b/include/restorer.h
index 4a75763..4a687f4 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -85,6 +85,11 @@ struct task_restore_core_args {
struct creds_entry creds;
struct mm_entry mm;
+ int socket;
+ u8 *core;
+ int core_size;
+ u8 *pages;
+ int pages_size;
} __aligned(sizeof(long));
struct pt_regs {
diff --git a/include/shmem.h b/include/shmem.h
index f8907c8..2bd9d30 100644
--- a/include/shmem.h
+++ b/include/shmem.h
@@ -1,6 +1,7 @@
#ifndef __CR_SHMEM_H__
#define __CR_SHMEM_H__
int prepare_shmem_pid(int pid);
+int _prepare_shmem_pid(int pid, int fd);
int prepare_shmem_restore(void);
void show_saved_shmems(void);
struct vma_entry;
diff --git a/include/sk-queue.h b/include/sk-queue.h
index 2f38759..6b2da09 100644
--- a/include/sk-queue.h
+++ b/include/sk-queue.h
@@ -13,6 +13,7 @@ struct sk_packet {
};
extern int read_sk_queues(void);
+extern int _read_sk_queues(int fd);
extern int dump_sk_queue(int sock_fd, int sock_id);
extern void show_sk_queues(int fd, struct cr_options *o);
extern int restore_sk_queue(int fd, unsigned int peer_id);
diff --git a/include/sockets.h b/include/sockets.h
index b94fab4..0ecf9f8 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -31,7 +31,9 @@ extern void show_socket_opts(struct sk_opts_entry *soe);
extern int sk_collect_one(int ino, int family, struct socket_desc *d);
extern int collect_sockets(void);
extern int collect_inet_sockets(void);
+extern int _collect_inet_sockets(int fd);
extern int collect_unix_sockets(void);
+extern void _collect_unix_sockets(int fd);
extern int fix_external_unix_sockets(void);
extern int resolve_unix_peers(void);
extern int run_unix_connections(void);
diff --git a/include/util.h b/include/util.h
index 714bfdd..5879eb5 100644
--- a/include/util.h
+++ b/include/util.h
@@ -94,6 +94,7 @@ static inline int read_img_buf_eof(int fd, void *ptr, int size)
{
int ret;
ret = read(fd, ptr, size);
+ printf("read %d\n", ret);
if (ret == size)
return 1;
if (ret == 0)
diff --git a/inotify.c b/inotify.c
index 724d49d..0744300 100644
--- a/inotify.c
+++ b/inotify.c
@@ -34,18 +34,6 @@
#include "list.h"
#include "lock.h"
-struct inotify_wd_info {
- struct list_head list;
- struct inotify_wd_entry iwe;
-};
-
-struct inotify_file_info {
- struct list_head list;
- struct inotify_file_entry ife;
- struct list_head marks;
- struct file_desc d;
-};
-
static LIST_HEAD(info_head);
static char fdinfo_buf[PAGE_SIZE];
@@ -322,20 +310,41 @@ static int collect_mark(struct inotify_wd_info *mark)
int collect_inotify(void)
{
- struct inotify_file_info *info;
- struct inotify_wd_info *mark;
+ struct inotify_file_info info;
+ struct inotify_wd_info mark;
int image_fd = -1, image_wd = -1, ret = -1;
image_fd = open_image_ro(CR_FD_INOTIFY);
if (image_fd < 0)
return -1;
+ ret = _collect_inotify(image_fd, &info);
+ if (ret < 0)
+ goto err;
+
+ image_wd = open_image_ro(CR_FD_INOTIFY_WD);
+ if (image_wd < 0)
+ goto err;
+
+ ret = _collect_inotify_wd(image_wd, &info, &mark);
+
+err:
+ close_safe(&image_wd);
+ close_safe(&image_fd);
+
+ return ret;
+}
+
+int _collect_inotify(int image_fd, struct inotify_file_info *info)
+{
+ int ret = -1;
+
while (1) {
struct inotify_file_entry ife;
ret = read_img_eof(image_fd, &ife);
if (ret < 0)
- goto err;
+ return ret;
else if (!ret)
break;
@@ -350,24 +359,27 @@ int collect_inotify(void)
list_add(&info->list, &info_head);
}
- image_wd = open_image_ro(CR_FD_INOTIFY_WD);
- if (image_wd < 0)
- goto err;
+ return ret;
+}
+
+int _collect_inotify_wd(int image_wd, struct inotify_file_info *info, struct inotify_wd_info *mark)
+{
+ int ret = -1;
while (1) {
mark = xmalloc(sizeof(*mark));
if (!mark)
- goto err;
+ return ret;
ret = read_img_eof(image_wd, &mark->iwe);
if (ret < 0)
- goto err;
+ return ret;
else if (!ret)
break;
if (collect_mark(mark)) {
ret = -1;
pr_err("Can't find inotify with id 0x%08x\n", mark->iwe.id);
- goto err;
+ return ret;
}
}
@@ -376,9 +388,6 @@ int collect_inotify(void)
file_desc_add(&info->d, info->ife.id, &desc_ops);
}
ret = 0;
-err:
- close_safe(&image_wd);
- close_safe(&image_fd);
return ret;
}
diff --git a/pipes.c b/pipes.c
index 80684f5..eef6285 100644
--- a/pipes.c
+++ b/pipes.c
@@ -40,13 +40,23 @@ static struct file_desc_ops pipe_desc_ops = {
int collect_pipes(void)
{
- struct pipe_info *pi = NULL, *tmp;
- int fd, ret = -1;
+ int fd, ret;
fd = open_image_ro(CR_FD_PIPES);
if (fd < 0)
return -1;
+ ret = _collect_pipes(fd);
+
+ close(fd);
+ return ret;
+}
+
+int _collect_pipes(int fd)
+{
+ struct pipe_info *pi = NULL, *tmp;
+ int ret = -1;
+
while (1) {
pi = xmalloc(sizeof(*pi));
ret = -1;
@@ -76,7 +86,6 @@ int collect_pipes(void)
xfree(pi);
- close(fd);
return ret;
}
@@ -96,6 +105,16 @@ static int handle_pipes_data()
fd = open_image_ro(CR_FD_PIPES_DATA);
if (fd < 0)
return -1;
+
+ ret = _handle_pipes_data(fd);
+
+ close(fd);
+ return ret;
+}
+
+int _handle_pipes_data(int fd)
+{
+ int ret;
while (1) {
struct pipe_info *pi;
@@ -127,7 +146,7 @@ err:
}
/* Choose who will restore a pipe. */
-void mark_pipe_master()
+void _mark_pipe_master()
{
LIST_HEAD(head);
@@ -170,6 +189,11 @@ void mark_pipe_master()
}
list_splice(&head, &pipes);
+}
+
+void mark_pipe_master()
+{
+ _mark_pipe_master();
handle_pipes_data();
}
diff --git a/restorer.c b/restorer.c
index 2fa049a..1405c4e 100644
--- a/restorer.c
+++ b/restorer.c
@@ -317,10 +317,14 @@ long __export_restore_task(struct task_restore_core_args *args)
write_hex_n((long)vma_entry);
#endif
- ret = sys_read(args->fd_core, core_entry, sizeof(*core_entry));
- if (ret != sizeof(*core_entry)) {
- write_num_n(__LINE__);
- goto core_restore_end;
+ if (args->socket == -1) {
+ ret = sys_read(args->fd_core, core_entry, sizeof(*core_entry));
+ if (ret != sizeof(*core_entry)) {
+ write_num_n(__LINE__);
+ goto core_restore_end;
+ }
+ } else {
+ memcpy(core_entry, args->core, sizeof(*core_entry));
}
for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) {
@@ -362,22 +366,40 @@ long __export_restore_task(struct task_restore_core_args *args)
* Read page contents.
*/
while (1) {
- ret = sys_read(args->fd_pages, &va, sizeof(va));
- if (!ret)
- break;
+ //if (args->socket == -1) {
+ ret = sys_read(args->fd_pages, &va, sizeof(va));
+ if (!ret)
+ break;
- if (ret != sizeof(va)) {
- write_num_n(__LINE__);
- write_num_n(ret);
- goto core_restore_end;
- }
+ if (ret != sizeof(va)) {
+ write_num_n(__LINE__);
+ write_num_n(ret);
+ goto core_restore_end;
+ }
- ret = sys_read(args->fd_pages, (void *)va, PAGE_SIZE);
- if (ret != PAGE_SIZE) {
- write_num_n(__LINE__);
- write_num_n(ret);
- goto core_restore_end;
+ ret = sys_read(args->fd_pages, (void *)va, PAGE_SIZE);
+ if (ret != PAGE_SIZE) {
+ write_num_n(__LINE__);
+ write_num_n(ret);
+ goto core_restore_end;
+ }
+#if 0
+ } else {
+ if ((args->pages_size - sizeof(va)) <= 0)
+ break;
+
+ write_string_n("memcpy start va");
+ memcpy(&va, args->pages, sizeof(va));
+ write_string_n("memcpy start va done");
+ args->pages += sizeof(va);
+ args->pages_size -= sizeof(va);
+
+
+ memcpy((void *)va, args->pages, PAGE_SIZE);
+ args->pages += PAGE_SIZE;
+ args->pages_size -= PAGE_SIZE;
}
+#endif
}
sys_close(args->fd_pages);
diff --git a/shmem.c b/shmem.c
index fea697f..7c9eebc 100644
--- a/shmem.c
+++ b/shmem.c
@@ -75,8 +75,7 @@ static int collect_shmem(int pid, struct vma_entry *vi)
int prepare_shmem_pid(int pid)
{
- int fd, ret = -1;
- struct vma_entry vi;
+ int fd, ret;
fd = open_image_ro(CR_FD_VMAS, pid);
if (fd < 0) {
@@ -86,6 +85,18 @@ int prepare_shmem_pid(int pid)
return -1;
}
+ ret = _prepare_shmem_pid(pid, fd);
+
+ close(fd);
+
+ return ret;
+}
+
+int _prepare_shmem_pid(int pid, int fd)
+{
+ int ret = -1;
+ struct vma_entry vi;
+
while (1) {
ret = read_img_eof(fd, &vi);
if (ret <= 0)
@@ -104,7 +115,6 @@ int prepare_shmem_pid(int pid)
break;
}
- close(fd);
return ret;
}
diff --git a/sk-inet.c b/sk-inet.c
index a193fed..dcbabe6 100644
--- a/sk-inet.c
+++ b/sk-inet.c
@@ -186,13 +186,23 @@ static struct file_desc_ops inet_desc_ops = {
int collect_inet_sockets(void)
{
- struct inet_sk_info *ii = NULL;
int fd, ret = -1;
fd = open_image_ro(CR_FD_INETSK);
if (fd < 0)
return -1;
+ ret = _collect_inet_sockets(fd);
+
+ close(fd);
+ return ret;
+}
+
+int _collect_inet_sockets(int fd)
+{
+ struct inet_sk_info *ii = NULL;
+ int ret = -1;
+
while (1) {
ii = xmalloc(sizeof(*ii));
ret = -1;
@@ -212,7 +222,6 @@ int collect_inet_sockets(void)
if (ii)
xfree(ii);
- close(fd);
return 0;
}
diff --git a/sk-queue.c b/sk-queue.c
index 7c29037..bbf381f 100644
--- a/sk-queue.c
+++ b/sk-queue.c
@@ -23,7 +23,6 @@ static LIST_HEAD(packets_list);
int read_sk_queues(void)
{
- struct sk_packet *pkt;
int ret, fd;
pr_info("Trying to read socket queues image\n");
@@ -32,6 +31,17 @@ int read_sk_queues(void)
if (fd < 0)
return -1;
+ ret = _read_sk_queues(fd);
+
+ close(fd);
+ return ret;
+}
+
+int _read_sk_queues(int fd)
+{
+ struct sk_packet *pkt;
+ int ret;
+
while (1) {
pkt = xmalloc(sizeof(*pkt));
if (!pkt) {
@@ -50,7 +60,6 @@ int read_sk_queues(void)
list_add_tail(&pkt->list, &packets_list);
lseek(fd, pkt->entry.length, SEEK_CUR);
}
- close(fd);
xfree(pkt);
return ret;
diff --git a/sk-unix.c b/sk-unix.c
index a6d109e..09d916a 100644
--- a/sk-unix.c
+++ b/sk-unix.c
@@ -703,7 +703,7 @@ static struct file_desc_ops unix_desc_ops = {
int collect_unix_sockets(void)
{
- int fd, ret;
+ int fd;
pr_info("Reading unix sockets in\n");
@@ -715,6 +715,17 @@ int collect_unix_sockets(void)
return -1;
}
+ _collect_unix_sockets(fd);
+
+ close(fd);
+
+ return read_sk_queues();
+}
+
+void _collect_unix_sockets(int fd)
+{
+ int ret;
+
while (1) {
struct unix_sk_info *ui;
@@ -762,9 +773,6 @@ int collect_unix_sockets(void)
list_add_tail(&ui->list, &unix_sockets);
}
- close(fd);
-
- return read_sk_queues();
}
int resolve_unix_peers(void)
diff --git a/util.c b/util.c
index ee35f70..56c7d99 100644
--- a/util.c
+++ b/util.c
@@ -136,6 +136,8 @@ static int image_dir_fd = -1;
int open_image(int type, unsigned long flags, ...)
{
char path[PATH_MAX];
+ char buffer[PATH_MAX];
+ char proc_path[PATH_MAX];
va_list args;
int ret;
@@ -157,6 +159,12 @@ int open_image(int type, unsigned long flags, ...)
goto err;
}
+ memset(buffer, 0, PATH_MAX);
+ memset(proc_path, 0, PATH_MAX);
+ sprintf(proc_path, "/proc/self/fd/%d", ret);
+ readlink(proc_path, buffer, PATH_MAX);
+ printf("Opening filedescriptor %d:%s\n", ret,buffer);
+
if (flags == O_RDONLY) {
u32 magic;
More information about the CRIU
mailing list