linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] IPC: message queue stealing feature introduced
@ 2012-02-15  9:08 Stanislav Kinsbursky
  2012-02-15  9:40 ` Eric Dumazet
  0 siblings, 1 reply; 3+ messages in thread
From: Stanislav Kinsbursky @ 2012-02-15  9:08 UTC (permalink / raw)
  To: akpm; +Cc: criu, lucas.demarchi, dhowells, linux-kernel, serge.hallyn

This patch is required for checkpoint/restore in userspace project.
C/r requires some way to get all pending IPC messages without deleting them for
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_STEAL for sys_msgrcv() system call
introduced.
If this flag is set, then passed struct msgbuf pointer will be used for storing
array of structures:

struct msgbuf_a {
	long mtype;         /* type of message */
	size_t msize;       /* size of message */
	char mtext[0];      /* message text */
};

each of which will be followed by corresponding message data.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/msg.h |    8 ++++++++
 ipc/msg.c           |   43 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/include/linux/msg.h b/include/linux/msg.h
index 6689e73..2bace1a 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -11,6 +11,7 @@
 /* msgrcv options */
 #define MSG_NOERROR     010000  /* no error if message is too big */
 #define MSG_EXCEPT      020000  /* recv any msg except of specified type.*/
+#define MSG_STEAL       040000  /* copy (not remove) all queue messages */
 
 /* Obsolete, used only for backwards compatibility and libc5 compiles */
 struct msqid_ds {
@@ -38,6 +39,13 @@ struct msgbuf {
 	char mtext[1];      /* message text */
 };
 
+/* message buffer for msgrcv in case of array calls */
+struct msgbuf_a {
+	long mtype;         /* type of message */
+	size_t msize;       /* size of message */
+	char mtext[0];      /* message text */
+};
+
 /* buffer for msgctl calls IPC_INFO, MSG_INFO */
 struct msginfo {
 	int msgpool;
diff --git a/ipc/msg.c b/ipc/msg.c
index 303362b..d024cdc 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -762,6 +762,23 @@ static inline int convert_mode(long *msgtyp, int msgflg)
 	return SEARCH_EQUAL;
 }
 
+static int do_store_msg(void __user *mtext, size_t msgsz, struct msg_msg *msg)
+{
+	msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz;
+	if (store_msg(mtext, msg, msgsz))
+		return -EFAULT;
+	return msgsz;
+}
+
+static int do_steal_msg(struct msgbuf_a __user *msgp, size_t msgsz, struct msg_msg *msg)
+{
+	if (put_user(msg->m_type, &msgp->mtype))
+		return -EFAULT;
+	if (put_user(msg->m_ts, &msgp->msize))
+		return -EFAULT;
+	return do_store_msg(msgp->mtext, msgsz, msg);
+}
+
 long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
 		size_t msgsz, long msgtyp, int msgflg)
 {
@@ -769,6 +786,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
 	struct msg_msg *msg;
 	int mode;
 	struct ipc_namespace *ns;
+	size_t arrsz = msgsz;
 
 	if (msqid < 0 || (long) msgsz < 0)
 		return -EINVAL;
@@ -802,6 +820,16 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
 						walk_msg->m_type != 1) {
 					msg = walk_msg;
 					msgtyp = walk_msg->m_type - 1;
+				} else if (msgflg & MSG_STEAL) {
+					int ret;
+
+					ret = do_steal_msg(mtext, arrsz, msg);
+					if (ret < 0) {
+						msg = ERR_PTR(ret);
+						goto out_unlock;
+					}
+					mtext += ret + sizeof(struct msgbuf_a);
+					arrsz -= ret + sizeof(struct msgbuf_a);
 				} else {
 					msg = walk_msg;
 					break;
@@ -810,6 +838,8 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
 			tmp = tmp->next;
 		}
 		if (!IS_ERR(msg)) {
+			if (msgflg & MSG_STEAL)
+				goto out_unlock;
 			/*
 			 * Found a suitable message.
 			 * Unlink it from the queue.
@@ -904,10 +934,11 @@ out_unlock:
 	if (IS_ERR(msg))
 		return PTR_ERR(msg);
 
-	msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz;
+	if (msgflg & MSG_STEAL)
+		return msgsz;
+
 	*pmtype = msg->m_type;
-	if (store_msg(mtext, msg, msgsz))
-		msgsz = -EFAULT;
+	msgsz = do_store_msg(mtext, msgsz, msg);
 
 	free_msg(msg);
 
@@ -919,8 +950,10 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
 {
 	long err, mtype;
 
-	err =  do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
-	if (err < 0)
+	err =  do_msgrcv(msqid, &mtype,
+			 (msgflg & MSG_STEAL) ? (void *)msgp : msgp->mtext,
+			 msgsz, msgtyp, msgflg);
+	if (err < 0 || msgflg & MSG_STEAL)
 		goto out;
 
 	if (put_user(mtype, &msgp->mtype))


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] IPC: message queue stealing feature introduced
  2012-02-15  9:08 [PATCH] IPC: message queue stealing feature introduced Stanislav Kinsbursky
@ 2012-02-15  9:40 ` Eric Dumazet
  2012-02-15 15:02   ` Stanislav Kinsbursky
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Dumazet @ 2012-02-15  9:40 UTC (permalink / raw)
  To: Stanislav Kinsbursky
  Cc: akpm, criu, lucas.demarchi, dhowells, linux-kernel, serge.hallyn

Le mercredi 15 février 2012 à 13:08 +0400, Stanislav Kinsbursky a
écrit :
> This patch is required for checkpoint/restore in userspace project.
> C/r requires some way to get all pending IPC messages without deleting them for
> 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_STEAL for sys_msgrcv() system call
> introduced.
> If this flag is set, then passed struct msgbuf pointer will be used for storing
> array of structures:
> 
> struct msgbuf_a {
> 	long mtype;         /* type of message */
> 	size_t msize;       /* size of message */
> 	char mtext[0];      /* message text */
> };
> 

This structure is not 32/64 bit safe and will need compat tricks.

+                       ret = do_steal_msg(mtext, arrsz, msg);
+                       if (ret < 0) {
+                               msg = ERR_PTR(ret);
+                               goto out_unlock;
+                       }
+                       mtext += ret + sizeof(struct msgbuf_a);
+                       arrsz -= ret + sizeof(struct msgbuf_a);

I cant see where alignement requirements are met.

(ret should be rounded up to a multiple of alignof(struct msgbuf_a)




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] IPC: message queue stealing feature introduced
  2012-02-15  9:40 ` Eric Dumazet
@ 2012-02-15 15:02   ` Stanislav Kinsbursky
  0 siblings, 0 replies; 3+ messages in thread
From: Stanislav Kinsbursky @ 2012-02-15 15:02 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: akpm, criu, lucas.demarchi, dhowells, linux-kernel, serge.hallyn

15.02.2012 13:40, Eric Dumazet пишет:
> Le mercredi 15 février 2012 à 13:08 +0400, Stanislav Kinsbursky a
> écrit :
>> This patch is required for checkpoint/restore in userspace project.
>> C/r requires some way to get all pending IPC messages without deleting them for
>> 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_STEAL for sys_msgrcv() system call
>> introduced.
>> If this flag is set, then passed struct msgbuf pointer will be used for storing
>> array of structures:
>>
>> struct msgbuf_a {
>> 	long mtype;         /* type of message */
>> 	size_t msize;       /* size of message */
>> 	char mtext[0];      /* message text */
>> };
>>
>
> This structure is not 32/64 bit safe and will need compat tricks.
>
> +                       ret = do_steal_msg(mtext, arrsz, msg);
> +                       if (ret<  0) {
> +                               msg = ERR_PTR(ret);
> +                               goto out_unlock;
> +                       }
> +                       mtext += ret + sizeof(struct msgbuf_a);
> +                       arrsz -= ret + sizeof(struct msgbuf_a);
>
> I cant see where alignement requirements are met.
>
> (ret should be rounded up to a multiple of alignof(struct msgbuf_a)
>


Thanks for reply, Eric.
Will fix and resend soon.

-- 
Best regards,
Stanislav Kinsbursky

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-02-15 15:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-15  9:08 [PATCH] IPC: message queue stealing feature introduced Stanislav Kinsbursky
2012-02-15  9:40 ` Eric Dumazet
2012-02-15 15:02   ` Stanislav Kinsbursky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).