Example #1
0
File: ipc_ns.c Project: 8472/criu
static int ipc_sysctl_req(IpcVarEntry *e, int op)
{
	struct sysctl_req req[] = {
		{ "kernel/sem",			e->sem_ctls,		CTL_U32A(e->n_sem_ctls) },
		{ "kernel/msgmax",		&e->msg_ctlmax,		CTL_U32 },
		{ "kernel/msgmnb",		&e->msg_ctlmnb,		CTL_U32 },
		{ "kernel/auto_msgmni",		&e->auto_msgmni,	CTL_U32 },
		{ "kernel/msgmni",		&e->msg_ctlmni,		CTL_U32 },
		{ "kernel/shmmax",		&e->shm_ctlmax,		CTL_U64 },
		{ "kernel/shmall",		&e->shm_ctlall,		CTL_U64 },
		{ "kernel/shmmni",		&e->shm_ctlmni,		CTL_U32 },
		{ "kernel/shm_rmid_forced",	&e->shm_rmid_forced,	CTL_U32 },
	};

	struct sysctl_req req_mq[] = {
		{ "fs/mqueue/queues_max",	&e->mq_queues_max,	CTL_U32 },
		{ "fs/mqueue/msg_max",		&e->mq_msg_max,		CTL_U32 },
		{ "fs/mqueue/msgsize_max",	&e->mq_msgsize_max,	CTL_U32 },
	};

	int ret;

	ret = sysctl_op(req, ARRAY_SIZE(req), op, CLONE_NEWIPC);
	if (ret)
		return ret;

	if (access("/proc/sys/fs/mqueue", X_OK)) {
		pr_info("Mqueue sysctls are missing\n");
		return 0;
	}

	return sysctl_op(req_mq, ARRAY_SIZE(req_mq), op, CLONE_NEWIPC);
}
Example #2
0
File: uts_ns.c Project: OSLL/pmover
int prepare_utsns(int pid)
{
	int fd, ret;
	UtsnsEntry *ue;
	struct sysctl_req req[3] = {
		{ "kernel/hostname" },
		{ "kernel/domainname" },
		{ },
	};

	fd = open_image_ro(CR_FD_UTSNS, pid);
	if (fd < 0)
		return -1;

	ret = pb_read_one(fd, &ue, PB_UTSNS);
	if (ret < 0)
		goto out;

	req[0].arg = ue->nodename;
	req[0].type = CTL_STR(strlen(ue->nodename));
	req[1].arg = ue->domainname;
	req[1].type = CTL_STR(strlen(ue->domainname));

	ret = sysctl_op(req, CTL_WRITE);
	utsns_entry__free_unpacked(ue, NULL);
out:
	close(fd);
	return ret;
}
Example #3
0
int prepare_utsns(int pid)
{
	int ret;
	struct cr_img *img;
	UtsnsEntry *ue;
	struct sysctl_req req[] = {
		{ "kernel/hostname" },
		{ "kernel/domainname" },
	};

	img = open_image(CR_FD_UTSNS, O_RSTR, pid);
	if (!img)
		return -1;

	ret = pb_read_one(img, &ue, PB_UTSNS);
	if (ret < 0)
		goto out;

	req[0].arg = ue->nodename;
	req[0].type = CTL_STR(strlen(ue->nodename));
	req[1].arg = ue->domainname;
	req[1].type = CTL_STR(strlen(ue->domainname));

	ret = sysctl_op(req, ARRAY_SIZE(req), CTL_WRITE, CLONE_NEWUTS);
	utsns_entry__free_unpacked(ue, NULL);
out:
	close_image(img);
	return ret;
}
Example #4
0
static int dump_ipc_msg_queue_messages(int fd, const IpcMsgEntry *msq,
				       unsigned int msg_nr)
{
	struct msgbuf *message = NULL;
	unsigned int msgmax;
	int ret, msg_cnt = 0;
	struct sysctl_req req[] = {
		{ "kernel/msgmax", &msgmax, CTL_U32 },
		{ },
	};

	ret = sysctl_op(req, CTL_READ);
	if (ret < 0) {
		pr_err("Failed to read max IPC message size\n");
		goto err;
	}

	msgmax += sizeof(struct msgbuf);
	message = xmalloc(round_up(msgmax, sizeof(u64)));
	if (message == NULL) {
		pr_err("Failed to allocate memory for IPC message\n");
		return -ENOMEM;
	}

	for (msg_cnt = 0; msg_cnt < msg_nr; msg_cnt++) {
		IpcMsg msg = IPC_MSG__INIT;
		size_t rounded;

		ret = msgrcv(msq->desc->id, message, msgmax, msg_cnt, IPC_NOWAIT | MSG_COPY);
		if (ret < 0) {
			pr_perror("Failed to copy IPC message");
			goto err;
		}

		msg.msize = ret;
		msg.mtype = message->mtype;

		pr_info_ipc_msg(msg_cnt, &msg);

		ret = pb_write_one(fd, &msg, PB_IPCNS_MSG);
		if (ret < 0) {
			pr_err("Failed to write IPC message header\n");
			break;
		}

		rounded = round_up(msg.msize, sizeof(u64));
		memzero(((void *)message->mtext + msg.msize), rounded - msg.msize);
		ret = write_img_buf(fd, message->mtext, rounded);
		if (ret < 0) {
			pr_err("Failed to write IPC message data\n");
			break;
		}
	}
	ret = 0;
err:
	xfree(message);
	return ret;
}
Example #5
0
static int prepare_ipc_shm_seg(int fd, const IpcShmEntry *shm)
{
	int ret, id;
	struct sysctl_req req[] = {
		{ "kernel/shm_next_id", &shm->desc->id, CTL_U32 },
		{ },
	};
	struct shmid_ds shmid;

	ret = sysctl_op(req, CTL_WRITE);
	if (ret < 0) {
		pr_err("Failed to set desired IPC shm ID\n");
		return ret;
	}

	id = shmget(shm->desc->key, shm->size,
		    shm->desc->mode | IPC_CREAT | IPC_EXCL);
	if (id == -1) {
		pr_perror("Failed to create shm set");
		return -errno;
	}

	if (id != shm->desc->id) {
		pr_err("Failed to restore shm id (%d instead of %d)\n",
							id, shm->desc->id);
		return -EFAULT;
	}

	ret = shmctl(id, IPC_STAT, &shmid);
	if (ret == -1) {
		pr_err("Failed to get shm stat structure\n");
		return -EFAULT;
	}

	shmid.shm_perm.uid = shm->desc->uid;
	shmid.shm_perm.gid = shm->desc->gid;

	ret = shmctl(id, IPC_SET, &shmid);
	if (ret == -1) {
		pr_err("Failed to set shm uid and gid\n");
		return -EFAULT;
	}

	ret = prepare_ipc_shm_pages(fd, shm);
	if (ret < 0) {
		pr_err("Failed to update shm pages\n");
		return ret;
	}
	return 0;
}
Example #6
0
File: ipc_ns.c Project: 8472/criu
static int prepare_ipc_sem_desc(struct cr_img *img, const IpcSemEntry *sem)
{
	int ret, id;
	struct sysctl_req req[] = {
		{ "kernel/sem_next_id", &sem->desc->id, CTL_U32 },
	};
	struct semid_ds semid;

	ret = sysctl_op(req, ARRAY_SIZE(req), CTL_WRITE, CLONE_NEWIPC);
	if (ret < 0) {
		pr_err("Failed to set desired IPC sem ID\n");
		return ret;
	}

	id = semget(sem->desc->key, sem->nsems,
		     sem->desc->mode | IPC_CREAT | IPC_EXCL);
	if (id == -1) {
		pr_perror("Failed to create sem set");
		return -errno;
	}

	if (id != sem->desc->id) {
		pr_err("Failed to restore sem id (%d instead of %d)\n",
							id, sem->desc->id);
		return -EFAULT;
	}

	ret = semctl(id, sem->nsems, IPC_STAT, &semid);
	if (ret == -1) {
		pr_err("Failed to get sem stat structure\n");
		return -EFAULT;
	}

	semid.sem_perm.uid = sem->desc->uid;
	semid.sem_perm.gid = sem->desc->gid;

	ret = semctl(id, sem->nsems, IPC_SET, &semid);
	if (ret == -1) {
		pr_err("Failed to set sem uid and gid\n");
		return -EFAULT;
	}

	ret = prepare_ipc_sem_values(img, sem);
	if (ret < 0) {
		pr_err("Failed to update sem pages\n");
		return ret;
	}
	return 0;
}
Example #7
0
static int prepare_ipc_msg_queue(int fd, const IpcMsgEntry *msq)
{
	int ret, id;
	struct sysctl_req req[] = {
		{ "kernel/msg_next_id", &msq->desc->id, CTL_U32 },
		{ },
	};
	struct msqid_ds msqid;

	ret = sysctl_op(req, CTL_WRITE);
	if (ret < 0) {
		pr_err("Failed to set desired IPC msg ID\n");
		return ret;
	}

	id = msgget(msq->desc->key, msq->desc->mode | IPC_CREAT | IPC_EXCL);
	if (id == -1) {
		pr_perror("Failed to create msg set");
		return -errno;
	}

	if (id != msq->desc->id) {
		pr_err("Failed to restore msg id (%d instead of %d)\n",
							id, msq->desc->id);
		return -EFAULT;
	}

	ret = msgctl(id, IPC_STAT, &msqid);
	if (ret == -1) {
		pr_err("Failed to get msq stat structure\n");
		return -EFAULT;
	}

	msqid.msg_perm.uid = msq->desc->uid;
	msqid.msg_perm.gid = msq->desc->gid;

	ret = msgctl(id, IPC_SET, &msqid);
	if (ret == -1) {
		pr_err("Failed to set msq queue uid and gid\n");
		return -EFAULT;
	}

	ret = prepare_ipc_msg_queue_messages(fd, msq);
	if (ret < 0) {
		pr_err("Failed to update message queue messages\n");
		return ret;
	}
	return 0;
}