mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 18:07:57 +00:00
IPC: restore namespace itself
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Acked-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
parent
5d40ea2ff1
commit
c75c33cb86
@ -49,7 +49,7 @@ OPTIONS
|
|||||||
|
|
||||||
-n <ns>::
|
-n <ns>::
|
||||||
Checkpoint namespaces. Namespaces must be separated by comma.
|
Checkpoint namespaces. Namespaces must be separated by comma.
|
||||||
Currently supported namespaces: uts.
|
Currently supported namespaces: uts, ipc.
|
||||||
|
|
||||||
-o <file>::
|
-o <file>::
|
||||||
Write logging messages to 'file'.
|
Write logging messages to 'file'.
|
||||||
|
@ -402,7 +402,7 @@ usage:
|
|||||||
" show contents of pages dumped in hexdump format\n");
|
" show contents of pages dumped in hexdump format\n");
|
||||||
printk(" -d detach after restore\n");
|
printk(" -d detach after restore\n");
|
||||||
printk(" -n checkpoint/restore namespaces - values must be separated by comma\n");
|
printk(" -n checkpoint/restore namespaces - values must be separated by comma\n");
|
||||||
printk(" supported: uts\n");
|
printk(" supported: uts, ipc\n");
|
||||||
|
|
||||||
printk("\nAdditional common parameters:\n");
|
printk("\nAdditional common parameters:\n");
|
||||||
printk(" -D dir save checkpoint files in specified directory\n");
|
printk(" -D dir save checkpoint files in specified directory\n");
|
||||||
|
151
ipc_ns.c
151
ipc_ns.c
@ -310,3 +310,154 @@ void show_ipc_ns(int fd)
|
|||||||
show_ipc_data(fd);
|
show_ipc_data(fd);
|
||||||
pr_img_tail(CR_FD_IPCNS);
|
pr_img_tail(CR_FD_IPCNS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
static int write_ipc_sysctl_long(char *name, u64 *data)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int ret;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
fd = open(name, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
pr_err("Can't open %s\n", name);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
sprintf(buf, "%ld\n", *(long *)data);
|
||||||
|
ret = write(fd, buf, 32);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("Can't write %s\n", name);
|
||||||
|
ret = -errno;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int write_ipc_sysctl(char *name, u32 *data)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int ret;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
fd = open(name, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
pr_err("Can't open %s\n", name);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
sprintf(buf, "%d\n", *(int *)data);
|
||||||
|
ret = write(fd, buf, 32);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("Can't write %s\n", name);
|
||||||
|
ret = -errno;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_ipc_sem(u32 sem[])
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int ret;
|
||||||
|
char buf[128];
|
||||||
|
char *name = "/proc/sys/kernel/sem";
|
||||||
|
|
||||||
|
fd = open(name, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
pr_err("Can't open %s\n", name);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
sprintf(buf, "%d %d %d %d\n", sem[0], sem[1], sem[2], sem[3]);
|
||||||
|
ret = write(fd, buf, 128);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("Can't write %s: %d\n", name, errno);
|
||||||
|
ret = -errno;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prepare_ipc_tun(struct ipc_ns_entry *entry)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = write_ipc_sem(entry->sem_ctls);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/msgmax", &entry->msg_ctlmax);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/msgmnb", &entry->msg_ctlmnb);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/msgmni", &entry->msg_ctlmni);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/auto_msgmni", &entry->auto_msgmni);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
ret = write_ipc_sysctl_long("/proc/sys/kernel/shmmax", (u64 *)entry->shm_ctlmax);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl_long("/proc/sys/kernel/shmall", (u64 *)entry->shm_ctlall);
|
||||||
|
#else
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/shmmax", entry->shm_ctlmax);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/shmall", entry->shm_ctlall);
|
||||||
|
#endif
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/shmmni", &entry->shm_ctlmni);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/kernel/shm_rmid_forced", &entry->shm_rmid_forced);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/fs/mqueue/queues_max", &entry->mq_queues_max);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/fs/mqueue/msg_max", &entry->mq_msg_max);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
ret = write_ipc_sysctl("/proc/sys/fs/mqueue/msgsize_max", &entry->mq_msgsize_max);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
pr_err("Failed to restore ipc namespace tunables\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prepare_ipc_data(int fd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct ipc_ns_data ipc;
|
||||||
|
|
||||||
|
ret = read_img(fd, &ipc);
|
||||||
|
if (ret <= 0)
|
||||||
|
return -EFAULT;
|
||||||
|
ret = prepare_ipc_tun(&ipc.entry);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prepare_ipc_ns(int pid)
|
||||||
|
{
|
||||||
|
int fd, ret;
|
||||||
|
|
||||||
|
fd = open_image_ro(CR_FD_IPCNS, pid);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = prepare_ipc_data(fd);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -104,6 +104,8 @@ int prepare_namespace(int pid, unsigned long clone_flags)
|
|||||||
|
|
||||||
if (clone_flags & CLONE_NEWUTS)
|
if (clone_flags & CLONE_NEWUTS)
|
||||||
ret = prepare_utsns(pid);
|
ret = prepare_utsns(pid);
|
||||||
|
if (clone_flags & CLONE_NEWIPC)
|
||||||
|
ret = prepare_ipc_ns(pid);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user