[CRIU] [PATCH 3/4] IPC: restore dump message queue
Kinsbursky Stanislav
skinsbursky at openvz.org
Thu Feb 9 10:58:03 EST 2012
Signed-off-by: Stanislav Kinsbursky <skinsbursky at parallels.com>
---
ipc_ns.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/ipc_ns.c b/ipc_ns.c
index 0e7e521..fa8d721 100644
--- a/ipc_ns.c
+++ b/ipc_ns.c
@@ -29,6 +29,10 @@
#define MSG_SET 13
#endif
+#ifndef SEM_SET
+#define SEM_SET 20
+#endif
+
static void print_ipc_seg(const struct ipc_seg *seg)
{
pr_info("id: %-10d key: 0x%08x ", seg->id, seg->key);
@@ -531,6 +535,105 @@ void show_ipc_var(int fd)
pr_img_tail(CR_FD_IPCNS);
}
+static int prepare_ipc_sem_set(int fd, const struct ipc_sem_entry *entry)
+{
+ int ret, size;
+ u16 *values;
+
+ size = sizeof(u16) * entry->nsems;
+ values = xmalloc(size);
+ if (values == NULL) {
+ pr_err("Failed to allocate memory for semaphores set values\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = read_img_buf(fd, values, round_up(size, sizeof(u64)));
+ if (ret < 0) {
+ pr_err("Failed to allocate memory for semaphores set values\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ print_ipc_sem(entry->nsems, values);
+
+ ret = semctl(entry->seg.id, 0, SETALL, values);
+ if (ret < 0) {
+ pr_perror("Failed to set semaphores set values");
+ ret = -errno;
+ }
+out:
+ xfree(values);
+ return ret;
+}
+
+static int prepare_ipc_sem_seg(int fd, const struct ipc_sem_entry *entry)
+{
+ int ret, id;
+ struct semid_ds ds;
+
+ id = semget(entry->seg.id, entry->nsems,
+ entry->seg.mode | IPC_CREAT | IPC_EXCL | IPC_PRESET);
+ if (id == -1) {
+ pr_perror("Failed to create sem segment");
+ return -errno;
+ }
+
+ if (id != entry->seg.id) {
+ pr_err("Failed to preset id (%d instead of %d)\n",
+ id, entry->seg.id);
+ return -EFAULT;
+ }
+
+ ret = semctl(id, 0, SEM_STAT, &ds);
+ if (ret < 0) {
+ pr_perror("Failed to stat msg segment");
+ return -errno;
+ }
+
+ ds.sem_perm.KEY = entry->seg.key;
+ ret = semctl(id, 0, SEM_SET, &ds);
+ if (ret < 0) {
+ pr_perror("Failed to update sem key");
+ return -errno;
+ }
+ ret = prepare_ipc_sem_set(fd, entry);
+ if (ret < 0) {
+ pr_err("Failed to update sem pages\n");
+ return ret;
+ }
+ return 0;
+}
+
+static int prepare_ipc_sem(int pid)
+{
+ int fd;
+
+ pr_info("Restoring IPC semaphores sets\n");
+ fd = open_image_ro(CR_FD_IPCNS_SEM, pid);
+ if (fd < 0)
+ return -1;
+
+ while (1) {
+ int ret, id;
+ struct ipc_sem_entry entry;
+ struct semid_ds ds;
+
+ ret = read_img_eof(fd, &entry);
+ if (ret < 0)
+ return -EIO;
+ if (ret == 0)
+ break;
+
+ print_ipc_sem_entry(&entry);
+
+ ret = prepare_ipc_sem_seg(fd, &entry);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
static int prepare_ipc_msg_queue(int fd, const struct ipc_msg_entry *entry)
{
int msg_nr = 0;
@@ -765,5 +868,8 @@ int prepare_ipc_ns(int pid)
ret = prepare_ipc_msg(pid);
if (ret < 0)
return ret;
+ ret = prepare_ipc_sem(pid);
+ if (ret < 0)
+ return ret;
return 0;
}
More information about the CRIU
mailing list