[CRIU] [PATCH 3/4] IPC: restore namespace itself
Kinsbursky Stanislav
skinsbursky at openvz.org
Mon Jan 30 12:19:13 EST 2012
From: Stanislav Kinsbursky <skinsbursky at parallels.com>
Signed-off-by: Stanislav Kinsbursky <skinsbursky at parallels.com>
---
Documentation/crtools.txt | 2 -
crtools.c | 2 -
ipc_ns.c | 136 +++++++++++++++++++++++++++++++++++++++++++++
namespaces.c | 2 +
4 files changed, 140 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 baeabed..c1d0d19 100644
--- a/crtools.c
+++ b/crtools.c
@@ -385,7 +385,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 434501c..37db899 100644
--- a/ipc_ns.c
+++ b/ipc_ns.c
@@ -310,3 +310,139 @@ void show_ipc_ns(int fd)
show_ipc_data(fd);
pr_img_tail(CR_FD_IPCNS);
}
+
+static int write_ipc_sysctl(char *name, void *data, size_t size)
+{
+ int fd;
+ int ret;
+ char buf[32];
+
+ fd = open(name, O_WRONLY);
+ if (fd < 0) {
+ pr_err("Can't open %d\n", name);
+ return fd;
+ }
+ if (size > sizeof(int))
+ sprintf(buf, "%ld\n", *(long *)data);
+ else
+ 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 %d\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, sizeof(entry->msg_ctlmax));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/kernel/msgmnb",
+ &entry->msg_ctlmnb, sizeof(entry->msg_ctlmnb));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/kernel/msgmni",
+ &entry->msg_ctlmni, sizeof(entry->msg_ctlmni));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/kernel/auto_msgmni",
+ &entry->auto_msgmni, sizeof(entry->auto_msgmni));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/kernel/shmmax",
+ &entry->shm_ctlmax, sizeof(entry->shm_ctlmax));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/kernel/shmall",
+ &entry->shm_ctlall, sizeof(entry->shm_ctlall));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/kernel/shmmni",
+ &entry->shm_ctlmni, sizeof(entry->shm_ctlmni));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/kernel/shm_rmid_forced",
+ &entry->shm_rmid_forced, sizeof(entry->shm_rmid_forced));
+ if (ret < 0)
+ goto err;
+
+
+ ret = write_ipc_sysctl("/proc/sys/fs/mqueue/queues_max",
+ &entry->mq_queues_max, sizeof(entry->mq_queues_max));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/fs/mqueue/msg_max",
+ &entry->mq_msg_max, sizeof(entry->mq_msg_max));
+ if (ret < 0)
+ goto err;
+ ret = write_ipc_sysctl("/proc/sys/fs/mqueue/msgsize_max",
+ &entry->mq_msgsize_max, sizeof(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 ea0f6d1..4b65b3d 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