mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 09:02:06 +00:00
ipc: introduce message queue copy feature
This patch is required for checkpoint/restore in userspace. c/r requires some way to get all pending IPC messages without deleting them from the queue (checkpoint can fail and in this case tasks will be resumed, so queue have to be valid). To achive this, new operation flag MSG_COPY for sys_msgrcv() system call was introduced. If this flag was specified, then mtype is interpreted as number of the message to copy. If MSG_COPY is set, then kernel will allocate dummy message with passed size, and then use new copy_msg() helper function to copy desired message (instead of unlinking it from the queue). Notes: 1) Return -ENOSYS if MSG_COPY is specified, but CONFIG_CHECKPOINT_RESTORE is not set. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
f9dd87f473
commit
4a674f34ba
4 changed files with 102 additions and 2 deletions
|
@ -102,7 +102,45 @@ out_err:
|
|||
free_msg(msg);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
#ifdef CONFIG_CHECKPOINT_RESTORE
|
||||
struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
|
||||
{
|
||||
struct msg_msgseg *dst_pseg, *src_pseg;
|
||||
int len = src->m_ts;
|
||||
int alen;
|
||||
|
||||
BUG_ON(dst == NULL);
|
||||
if (src->m_ts > dst->m_ts)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
alen = len;
|
||||
if (alen > DATALEN_MSG)
|
||||
alen = DATALEN_MSG;
|
||||
|
||||
dst->next = NULL;
|
||||
dst->security = NULL;
|
||||
|
||||
memcpy(dst + 1, src + 1, alen);
|
||||
|
||||
len -= alen;
|
||||
dst_pseg = dst->next;
|
||||
src_pseg = src->next;
|
||||
while (len > 0) {
|
||||
alen = len;
|
||||
if (alen > DATALEN_SEG)
|
||||
alen = DATALEN_SEG;
|
||||
memcpy(dst_pseg + 1, src_pseg + 1, alen);
|
||||
dst_pseg = dst_pseg->next;
|
||||
len -= alen;
|
||||
src_pseg = src_pseg->next;
|
||||
}
|
||||
|
||||
dst->m_type = src->m_type;
|
||||
dst->m_ts = src->m_ts;
|
||||
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
int store_msg(void __user *dest, struct msg_msg *msg, int len)
|
||||
{
|
||||
int alen;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue