[CRIU] [crtools-bot] IPC: restore namespace itself
Cyrill Gorcunov
gorcunov at openvz.org
Tue Jan 31 13:32:22 EST 2012
The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit c75c33cb8699176e65dddaa05bb565ede6c55f38
Author: Stanislav Kinsbursky <skinsbursky at parallels.com>
Date: Tue Jan 31 22:29:22 2012 +0400
IPC: restore namespace itself
Signed-off-by: Stanislav Kinsbursky <skinsbursky at parallels.com>
Acked-by: Pavel Emelyanov <xemul at parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
Documentation/crtools.txt | 2 +-
crtools.c | 2 +-
ipc_ns.c | 151 +++++++++++++++++++++++++++++++++++++++++++++
namespaces.c | 2 +
4 files changed, 155 insertions(+), 2 deletions(-)
diff --git a/Documentation/crtools.txt b/Documentation/crtools.txt
index c7b028d..c1f6bcc 100644
--- a/Documentation/crtools.txt
+++ b/Documentation/crtools.txt
@@ -49,7 +49,7 @@ OPTIONS
-n <ns>::
Checkpoint namespaces. Namespaces must be separated by comma.
- Currently supported namespaces: uts.
+ Currently supported namespaces: uts, ipc.
-o <file>::
Write logging messages to 'file'.
diff --git a/crtools.c b/crtools.c
index dd67a42..4529a10 100644
--- a/crtools.c
+++ b/crtools.c
@@ -402,7 +402,7 @@ usage:
" show contents of pages dumped in hexdump format\n");
printk(" -d detach after restore\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(" -D dir save checkpoint files in specified directory\n");
diff --git a/ipc_ns.c b/ipc_ns.c
index 11e96e6..b5c2c82 100644
--- a/ipc_ns.c
+++ b/ipc_ns.c
@@ -310,3 +310,154 @@ void show_ipc_ns(int fd)
show_ipc_data(fd);
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;
+}
+
diff --git a/namespaces.c b/namespaces.c
index 04d476f..67051b1 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -104,6 +104,8 @@ int prepare_namespace(int pid, unsigned long clone_flags)
if (clone_flags & CLONE_NEWUTS)
ret = prepare_utsns(pid);
+ if (clone_flags & CLONE_NEWIPC)
+ ret = prepare_ipc_ns(pid);
return ret;
}
More information about the CRIU
mailing list