OpenVZ Forum - RDF feed
type: channel
items: [PATCH v3 00/10] IPC: checkpoint/restore in userspace enhancements
items: [PATCH v3 01/10] ipc: remove forced assignment of selected message
items: [PATCH v3 02/10] ipc: &quot;use key as id&quot; functionality for resource get system call i
items: [PATCH v3 03/10] ipc: segment key change helper introduced
items: [PATCH v3 04/10] ipc: add new SHM_SET command for sys_shmctl() call
items: [PATCH v3 05/10] ipc: add new MSG_SET command for sys_msgctl() call
items: [PATCH v3 06/10] ipc: add new SEM_SET command for sys_semctl() call
items: [PATCH v3 07/10] IPC: message queue receive cleanup
items: [PATCH v3 08/10] IPC: message queue copy feature introduced
items: [PATCH v3 09/10] ipc: add new MSG_SET_COPY command for sys_msgctl() call
items: [PATCH v3 10/10] test: IPC message queue migration test
items: Re: [PATCH v3 08/10] IPC: message queue copy feature introduced

[PATCH v3 00/10] IPC: checkpoint/restore in userspace enhancements
type: item
description: v3: 1) Copy messages to user-space under spinlock was replaced by allocation of dummy message before queue lock and then copy of desired message to the dummy one instead of unlinking it from queue list. I.e. the message queue copy logic was changed: messages can be retrived one by one (instead of receiving of the whole list at once). This patch set is aimed to provide additional functionality for all IPC objects, which is required for migration of these objects by user-space checkpoint/restore utils (CRIU). The main problem here was impossibility to set up object id. This patch set solves the problem in two steps: 1) Makes it possible to create new object (shared memory, semaphores set or messages queue) with ID, equal to passed key. 2) Makes it possible to change existent object key. Another problem was to peek messages from queues without deleting them. This was achived by introducing of new MSG_COPY flag for sys_msgrcv() and MSG_SET_COPY command for sys_msgctl() (which can be used to select message number to copy). The following series implements... --- Stanislav Kinsbursky (10): ipc: remove forced assignment of selected message ipc: "use key as id" functionality for resource get system call introduced ipc: segment key change helper introduced ipc: add new SHM_SET command for sys_shmctl() call ipc: add new MSG_SET command for sys_msgctl() call ipc: add new SEM_SET command for sys_semctl() call IPC: message queue receive cleanup IPC: message queue copy feature introduced ipc: add new MSG_SET_COPY command for sys_msgctl() call test: IPC message queue migration test arch/tile/kernel/compat.c | 29 +++++++ include/linux/compat.h | 2 include/linux/ipc.h | 1 include/linux/msg.h | 11 ++ include/linux/sem.h | 1 include/linux/shm.h | 1 ipc/compat.c | 45 +++++++--- ipc/msg.c | 129 +++++++++++++++++++++++------ ipc/msgutil.c | 38 +++++++++ ipc/sem.c | 11 ++ ipc/shm.c | 14 +++ ipc/util.c | 59 ++++++++++++- ipc/util.h | 4 + security/selinux/hooks.c | 3 + security/smack/smack_l…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:15-00:00

[PATCH v3 01/10] ipc: remove forced assignment of selected message
type: item
description: This is a cleanup patch. The assignment is redundant. --- ipc/msg.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/ipc/msg.c b/ipc/msg.c index 7385de2..f3bfbb8 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -787,7 +787,6 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, !security_msg_queue_msgrcv(msq, walk_msg, current, msgtyp, mode)) { - msg = walk_msg; if (mode == SEARCH_LESSEQUAL && walk_msg->m_type != 1) { msg = walk_msg;
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:25-00:00

[PATCH v3 02/10] ipc: &quot;use key as id&quot; functionality for resource get system call i
type: item
description: This patch introduces new IPC resource get request flag IPC_PRESET, which should be interpreted as a request to try to allocate IPC slot with number, starting from value resented by key. IOW, kernel will try allocate new segment in specified slot. If slot is not emply, them -EEXIST returned. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> --- include/linux/ipc.h | 1 + ipc/msg.c | 1 + ipc/sem.c | 1 + ipc/shm.c | 1 + ipc/util.c | 8 +++++++- ipc/util.h | 1 + 6 files changed, 12 insertions(+), 1 deletions(-) diff --git a/include/linux/ipc.h b/include/linux/ipc.h index 30e8161..d7e5632 100644 --- a/include/linux/ipc.h +++ b/include/linux/ipc.h @@ -24,6 +24,7 @@ struct ipc_perm #define IPC_CREAT 00001000 /* create if key is nonexistent */ #define IPC_EXCL 00002000 /* fail if key exists */ #define IPC_NOWAIT 00004000 /* return error on wait */ +#define IPC_PRESET 00040000 /* use key as id */ /* these fields are used by the DIPC package so the kernel as standard should avoid using them if possible */ diff --git a/ipc/msg.c b/ipc/msg.c index f3bfbb8..70939a0 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -190,6 +190,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) msq->q_perm.mode = msgflg & S_IRWXUGO; msq->q_perm.key = key; + msq->q_perm.id = (msgflg & IPC_PRESET) ? key : 0; msq->q_perm.security = NULL; retval = security_msg_queue_alloc(msq); diff --git a/ipc/sem.c b/ipc/sem.c index 5215a81..845c912 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -306,6 +306,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) sma->sem_perm.mode = (semflg & S_IRWXUGO); sma->sem_perm.key = key; + sma->sem_perm.id = (semflg & IPC_PRESET) ? key : 0; sma->sem_perm.security = NULL; retval = security_sem_alloc(sma); diff --git a/ipc/shm.c b/ipc/shm.c index 41c1285..d4c0a9e 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -480,6 +480,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_param…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:30-00:00

[PATCH v3 03/10] ipc: segment key change helper introduced
type: item
description: This patch introduces existent segment key changing infrastructure. New function ipc_update_key() can be used change segment key, cuid, cgid values. It checks for that new key is not used (except IPC_PRIVATE) prior to set it on existent. To make this possible, added copying of this fields from user-space in __get_compat_ipc_perm() and __get_compat_ipc64_perm() functions. Also segment search by key and lock were splitted into different functions, because ipc_update_key() doesn't need to lock the segment during check that new key is not used. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> --- ipc/compat.c | 6 ++++++ ipc/util.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- ipc/util.h | 2 ++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/ipc/compat.c b/ipc/compat.c index a6df704..aa88515 100644 --- a/ipc/compat.c +++ b/ipc/compat.c @@ -144,6 +144,9 @@ static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64, err = __get_user(p64->uid, &up64->uid); err |= __get_user(p64->gid, &up64->gid); err |= __get_user(p64->mode, &up64->mode); + err |= __get_user(p64->cuid, &up64->cuid); + err |= __get_user(p64->cgid, &up64->cgid); + err |= __get_user(p64->key, &up64->key); return err; } @@ -155,6 +158,9 @@ static inline int __get_compat_ipc_perm(struct ipc64_perm *p, err = __get_user(p->uid, &up->uid); err |= __get_user(p->gid, &up->gid); err |= __get_user(p->mode, &up->mode); + err |= __get_user(p->cuid, &up->cuid); + err |= __get_user(p->cgid, &up->cgid); + err |= __get_user(p->key, &up->key); return err; } diff --git a/ipc/util.c b/ipc/util.c index ac9c6a9..d1e2f25 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -173,7 +173,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header, * @key: The key to find * * Requires ipc_ids.rw_mutex locked. - * Returns the LOCKED pointer to the ipc structure if found or NULL + * Returns the UNLOCKED pointer to the ipc structu…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:35-00:00

[PATCH v3 04/10] ipc: add new SHM_SET command for sys_shmctl() call
type: item
description: New SHM_SET command will be interpreted exactly as IPC_SET, but also will update key, cuid and cgid values. IOW, it allows to change existent key value. The fact, that key is not used is checked before update. Otherwise -EEXIST is returned. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> --- include/linux/shm.h | 1 + ipc/compat.c | 1 + ipc/shm.c | 13 +++++++++++-- security/selinux/hooks.c | 1 + security/smack/smack_lsm.c | 1 + 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/linux/shm.h b/include/linux/shm.h index 92808b8..6fc5447 100644 --- a/include/linux/shm.h +++ b/include/linux/shm.h @@ -63,6 +63,7 @@ struct shmid_ds { /* ipcs ctl commands */ #define SHM_STAT 13 #define SHM_INFO 14 +#define SHM_SET 15 /* Obsolete, used only for backwards compatibility */ struct shminfo { diff --git a/ipc/compat.c b/ipc/compat.c index aa88515..e7d4af7 100644 --- a/ipc/compat.c +++ b/ipc/compat.c @@ -688,6 +688,7 @@ long compat_sys_shmctl(int first, int second, void __user *uptr) case IPC_SET: + case SHM_SET: if (version == IPC_64) { err = get_compat_shmid64_ds(&s64, uptr); } else { diff --git a/ipc/shm.c b/ipc/shm.c index d4c0a9e..677b9f6 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -635,6 +635,9 @@ copy_shmid_from_user(struct shmid64_ds *out, void __user *buf, int version) out->shm_perm.uid = tbuf_old.shm_perm.uid; out->shm_perm.gid = tbuf_old.shm_perm.gid; out->shm_perm.mode = tbuf_old.shm_perm.mode; + out->shm_perm.cuid = tbuf_old.shm_perm.cuid; + out->shm_perm.cgid = tbuf_old.shm_perm.cgid; + out->shm_perm.key = tbuf_old.shm_perm.key; return 0; } @@ -739,12 +742,13 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, struct shmid_kernel *shp; int err; - if (cmd == IPC_SET) { + if (cmd == IPC_SET || cmd == SHM_SET) { if (copy_shmid_from_user(&shmid64, buf, version)) return -EFAULT; } - ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd, + ipcp = ipcctl_pre_down(ns, &shm…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:41-00:00

[PATCH v3 05/10] ipc: add new MSG_SET command for sys_msgctl() call
type: item
description: New MSG_SET command will be interpreted exactly as IPC_SET, but also will update key, cuid and cgid values. IOW, it allows to change existent key value. The fact, that key is not used is checked before update. Otherwise -EEXIST is returned. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> --- include/linux/msg.h | 1 + ipc/compat.c | 1 + ipc/msg.c | 13 +++++++++++-- security/selinux/hooks.c | 1 + security/smack/smack_lsm.c | 1 + 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/linux/msg.h b/include/linux/msg.h index 56abf15..6689e73 100644 --- a/include/linux/msg.h +++ b/include/linux/msg.h @@ -6,6 +6,7 @@ /* ipcs ctl commands */ #define MSG_STAT 11 #define MSG_INFO 12 +#define MSG_SET 13 /* msgrcv options */ #define MSG_NOERROR 010000 /* no error if message is too big */ diff --git a/ipc/compat.c b/ipc/compat.c index e7d4af7..da4f5c6 100644 --- a/ipc/compat.c +++ b/ipc/compat.c @@ -483,6 +483,7 @@ long compat_sys_msgctl(int first, int second, void __user *uptr) break; case IPC_SET: + case MSG_SET: if (version == IPC_64) { err = get_compat_msqid64(&m64, uptr); } else { diff --git a/ipc/msg.c b/ipc/msg.c index 70939a0..6bd66d3 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -391,6 +391,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version) out->msg_perm.uid = tbuf_old.msg_perm.uid; out->msg_perm.gid = tbuf_old.msg_perm.gid; out->msg_perm.mode = tbuf_old.msg_perm.mode; + out->msg_perm.cuid = tbuf_old.msg_perm.cuid; + out->msg_perm.cgid = tbuf_old.msg_perm.cgid; + out->msg_perm.key = tbuf_old.msg_perm.key; if (tbuf_old.msg_qbytes == 0) out->msg_qbytes = tbuf_old.msg_lqbytes; @@ -417,12 +420,13 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, struct msg_queue *msq; int err; - if (cmd == IPC_SET) { + if (cmd == IPC_SET || cmd == MSG_SET) { if (copy_msqid_from_user(&msqid64, buf, version)) return -EFAULT; } - ipcp = ipcctl_pre_down(ns, &msg_i…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:46-00:00

[PATCH v3 06/10] ipc: add new SEM_SET command for sys_semctl() call
type: item
description: New SEM_SET command will be interpreted exactly as IPC_SET, but also will update key, cuid and cgid values. IOW, it allows to change existent key value. The fact, that key is not used is checked before update. Otherwise -EEXIST is returned. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> --- include/linux/sem.h | 1 + ipc/compat.c | 1 + ipc/sem.c | 10 ++++++++-- security/selinux/hooks.c | 1 + security/smack/smack_lsm.c | 1 + 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/linux/sem.h b/include/linux/sem.h index 10d6b22..c74b9b5 100644 --- a/include/linux/sem.h +++ b/include/linux/sem.h @@ -18,6 +18,7 @@ /* ipcs ctl cmds */ #define SEM_STAT 18 #define SEM_INFO 19 +#define SEM_SET 20 /* Obsolete, used only for backwards compatibility and libc5 compiles */ struct semid_ds { diff --git a/ipc/compat.c b/ipc/compat.c index da4f5c6..7cfdb5b 100644 --- a/ipc/compat.c +++ b/ipc/compat.c @@ -290,6 +290,7 @@ static long do_compat_semctl(int first, int second, int third, u32 pad) break; case IPC_SET: + case SEM_SET: if (version == IPC_64) { err = get_compat_semid64_ds(&s64, compat_ptr(pad)); } else { diff --git a/ipc/sem.c b/ipc/sem.c index 845c912..d9024d5 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -1084,12 +1084,13 @@ static int semctl_down(struct ipc_namespace *ns, int semid, struct semid64_ds semid64; struct kern_ipc_perm *ipcp; - if(cmd == IPC_SET) { + if (cmd == IPC_SET || cmd == SEM_SET) { if (copy_semid_from_user(&semid64, arg.buf, version)) return -EFAULT; } - ipcp = ipcctl_pre_down(ns, &sem_ids(ns), semid, cmd, + ipcp = ipcctl_pre_down(ns, &sem_ids(ns), semid, + (cmd != SEM_SET) ? : IPC_SET, &semid64.sem_perm, 0); if (IS_ERR(ipcp)) return PTR_ERR(ipcp); @@ -1104,6 +1105,10 @@ static int semctl_down(struct ipc_namespace *ns, int semid, case IPC_RMID: freeary(ns, ipcp); goto out_up; + case SEM_SET: + err = ipc_update_key(&sem_ids(ns), &semid64.sem_perm, ipcp); + if (err) + break; c…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:51-00:00

[PATCH v3 07/10] IPC: message queue receive cleanup
type: item
description: This patch moves all message related manipulation into one function msg_fill(). Actually, two functions because of the compat one. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Conflicts: arch/tile/kernel/compat.c include/linux/compat.h --- arch/tile/kernel/compat.c | 29 +++++++++++++++++++++++++++++ include/linux/compat.h | 2 ++ include/linux/msg.h | 5 +++-- ipc/compat.c | 33 +++++++++++++++++---------------- ipc/msg.c | 44 +++++++++++++++++++++++--------------------- 5 files changed, 74 insertions(+), 39 deletions(-) diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c index d67459b..e74d61b 100644 --- a/arch/tile/kernel/compat.c +++ b/arch/tile/kernel/compat.c @@ -94,6 +94,35 @@ long compat_sys_sched_rr_get_interval(compat_pid_t pid, return ret; } +/* + * The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming + * some different calling convention than our normal 32-bit tile code. + */ + +/* Already defined in ipc/compat.c, but we need it here. */ +struct compat_msgbuf { + compat_long_t mtype; + char mtext[1]; +}; + +long tile_compat_sys_msgsnd(int msqid, + struct compat_msgbuf __user *msgp, + size_t msgsz, int msgflg) +{ + compat_long_t mtype; + + if (get_user(mtype, &msgp->mtype)) + return -EFAULT; + return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); +} + +long tile_compat_sys_msgrcv(int msqid, + struct compat_msgbuf __user *msgp, + size_t msgsz, long msgtyp, int msgflg) +{ + return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, compat_do_msg_fill); +} + /* Provide the compat syscall number to call mapping. */ #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), diff --git a/include/linux/compat.h b/include/linux/compat.h index 4e89039..6e035dc 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -245,6 +245,7 @@ struct compat_sysctl_args; struct compat_kexec_segment; struct compat_mq_attr; struct compat_msgbuf; +struct msg_msg; extern void…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:25:56-00:00

[PATCH v3 08/10] IPC: message queue copy feature introduced
type: item
description: This patch is required for checkpoint/restore in userspace. IOW, 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. Also, copy counter was added to msg_queue structure. It's set to zero by default and increases by one on each copy operation and decreased by one on each receive operation until reaches zero. 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) syscall type-based logic remains the same. It means, that passed type is not zero and MSG_COPY is specified, then n-th message of that type will be copied. 2) Return -ENOSYS if MSG_COPY is specified, but CONFIG_CHECKPOINT_RESTORE is not set. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> --- include/linux/msg.h | 4 ++++ ipc/msg.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++-- ipc/msgutil.c | 38 +++++++++++++++++++++++++++++++++++++ ipc/util.h | 1 + 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/include/linux/msg.h b/include/linux/msg.h index 9411b76..07a5e1e 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_COPY 040000 /* copy (not remove) all queue messages */ /* Obsolete, used only for backwards compatibility and libc5 compiles */ struct msqid_ds { @@ -96,6 +97,9 @@ struct msg_queue { unsigned long q_qbytes; /* max number of bytes on queue */ pid_t q_lspid; /* pid of last msgsnd */ pid_t q_lrpid; /* last receive pid */ +#ifdef CONFIG_CHECKPOINT_RESTORE + unsigned int q_copy_cnt; /* message number for copy operations */ +…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:26:02-00:00

[PATCH v3 09/10] ipc: add new MSG_SET_COPY command for sys_msgctl() call
type: item
description: New MSG_SET_COPY allows to set specified queue copy counter to passed value. Passed "struct msqid_ds *buf" interpreted as pointer to unsigned int in this case. --- include/linux/msg.h | 1 + ipc/compat.c | 3 +++ ipc/msg.c | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 0 deletions(-) diff --git a/include/linux/msg.h b/include/linux/msg.h index 07a5e1e..4e9ddf4 100644 --- a/include/linux/msg.h +++ b/include/linux/msg.h @@ -7,6 +7,7 @@ #define MSG_STAT 11 #define MSG_INFO 12 #define MSG_SET 13 +#define MSG_SET_COPY 14 /* msgrcv options */ #define MSG_NOERROR 010000 /* no error if message is too big */ diff --git a/ipc/compat.c b/ipc/compat.c index 6b07f5c..9e5acc7 100644 --- a/ipc/compat.c +++ b/ipc/compat.c @@ -481,6 +481,9 @@ long compat_sys_msgctl(int first, int second, void __user *uptr) case IPC_INFO: case IPC_RMID: case MSG_INFO: +#ifdef CONFIG_CHECKPOINT_RESTORE + case MSG_SET_COPY: +#endif err = sys_msgctl(first, second, uptr); break; diff --git a/ipc/msg.c b/ipc/msg.c index 44ba0ce..c63b22e 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -579,6 +579,24 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) case MSG_SET: err = msgctl_down(ns, msqid, cmd, buf, version); return err; +#ifdef CONFIG_CHECKPOINT_RESTORE + case MSG_SET_COPY: + { + int copy_cnt; + + if (!buf) + return -EFAULT; + if (get_user(copy_cnt, (unsigned int *)buf)) + return -EFAULT; + + msq = msg_lock(ns, msqid); + if (IS_ERR(msq)) + return PTR_ERR(msq); + msq->q_copy_cnt = copy_cnt; + err = 0; + break; + } +#endif default: return -EINVAL; }
creator: Stanislav Kinsbursky
date: 2012-08-10T14:26:07-00:00

[PATCH v3 10/10] test: IPC message queue migration test
type: item
description: This test is a part of CRIU development test suit. --- tools/testing/selftests/ipc/msgque.c | 151 ++++++++++++++++++++++++++++++++++ 1 files changed, 151 insertions(+), 0 deletions(-) create mode 100644 tools/testing/selftests/ipc/msgque.c diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c new file mode 100644 index 0000000..c101e25 --- /dev/null +++ b/tools/testing/selftests/ipc/msgque.c @@ -0,0 +1,151 @@ +#define _GNU_SOURCE +#include <sched.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/sem.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <signal.h> +#include <errno.h> + +#include "zdtmtst.h" + +const char *test_doc="Tests sysv5 msg queues support by user space checkpointing"; +const char *test_author="Stanislav Kinsbursky <skinsbursky@openvz.org>"; + +struct msg1 { + long mtype; + char mtext[20]; +}; +#define TEST_STRING "Test sysv5 msg" +#define MSG_TYPE 1 + +#define ANOTHER_TEST_STRING "Yet another test sysv5 msg" +#define ANOTHER_MSG_TYPE 26538 + +static int test_fn(int argc, char **argv) +{ + key_t key; + int msg, pid; + struct msg1 msgbuf; + int chret; + + key = ftok(argv[0], 822155650); + if (key == -1) { + err("Can't make key"); + exit(1); + } + + pid = test_fork(); + if (pid < 0) { + err("Can't fork"); + exit(1); + } + + msg = msgget(key, IPC_CREAT | IPC_EXCL | 0666); + if (msg == -1) { + msg = msgget(key, 0666); + if (msg == -1) { + err("Can't get queue"); + goto err_kill; + } + } + + if (pid == 0) { + /* + * Here is the place where test sleeps and waits for signal. + * This place is used for suspend/restore test. + */ + test_waitsig(); + + if (msgrcv(msg, &msgbuf, sizeof(TEST_STRING), MSG_TYPE, IPC_NOWAIT) == -1) { + fail("Child: msgrcv failed (%m)"); + return -errno; + } + + if (strncmp(TEST_STRING, msgbuf.mtext, sizeof(TEST_STRING))) { + fail("Child: the source and received strings aren't equal"); + retu…
creator: Stanislav Kinsbursky
date: 2012-08-10T14:26:12-00:00

Re: [PATCH v3 08/10] IPC: message queue copy feature introduced
type: item
description: Hi Stanislav, 2012/8/10 Stanislav Kinsbursky <skinsbursky@parallels.com>: > This patch is required for checkpoint/restore in userspace. > IOW, 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. Also, copy counter was added to msg_queue structure. It's set to > zero by default and increases by one on each copy operation and decreased by > one on each receive operation until reaches zero. Is msq->q_copy_cnt really necessary? As far as I can see user space needs the ability to read the n-th message. The implementation adds a state variable to the kernel, adds two automatic updates of the state into msgrcv() (an increase during MSG_COPY, a decrease during normal receives) and adds a msgctl() to set the state to a certain value. a) What about the simpler approach: - if MSG_COPY is set, then @mtype is interpreted as the number of the message that should be copied. If there are less than @mtype messages, then -ENOMSG is returned. b) I do not understand the purpose of the decrease of msq->q_copy_cnt: Do you want to handle normal msgrcv() calls in parallel with msgrcv(|MSG_COPY) calls? I don't think that this will work: What if msq->q_copy_cnt is 1 and and msgrcv() call receives the 20th message in the queue? -- Manfred
creator: Manfred Spraul
date: 2012-08-11T11:20:58-00:00

Re: [PATCH v3 08/10] IPC: message queue copy feature introduced
type: item
description: 11.08.2012 15:20, Manfred Spraul пишет: > Hi Stanislav, > > 2012/8/10 Stanislav Kinsbursky <skinsbursky@parallels.com>: >> This patch is required for checkpoint/restore in userspace. >> IOW, 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. Also, copy counter was added to msg_queue structure. It's set to >> zero by default and increases by one on each copy operation and decreased by >> one on each receive operation until reaches zero. > Is msq->q_copy_cnt really necessary? > As far as I can see user space needs the ability to read the n-th message. > > The implementation adds a state variable to the kernel, adds two > automatic updates of the state into msgrcv() (an increase during > MSG_COPY, a decrease during normal receives) and adds a msgctl() to > set the state to a certain value. > > a) What about the simpler approach: > - if MSG_COPY is set, then @mtype is interpreted as the number of the > message that should be copied. > If there are less than @mtype messages, then -ENOMSG is returned. Hi, Manfred. Your approach is simplier, but makes the call less generic and adds limitations. I.e. sys_msgrcv() allows you to receive message by type. And from my pow this logic have to be preserved - you can specify type and then copy all the messages of specified type. > b) I do not understand the purpose of the decrease of msq->q_copy_cnt: > Do you want to handle normal msgrcv() calls in parallel with > msgrcv(|MSG_COPY) calls? Actually, I'm not going to copy a message from a queue, when somebody is reading from it. But better to handle this case by decreasing msq->q_copy_cnt, because otherwise this counter becomes invalid in case of somebody is reading from queue. And this logic is similar to new "peek" logic for sockets (introduced in 3.4 or 3.…
creator: Stanislav Kinsbursky
date: 2012-08-11T13:31:53-00:00

Re: [PATCH v3 08/10] IPC: message queue copy feature introduced
type: item
description: Hi Stanislav, 2012/8/11 Stanislav Kinsbursky <skinsbursky@parallels.com>: > 11.08.2012 15:20, Manfred Spraul пишет: >> a) What about the simpler approach: >> - if MSG_COPY is set, then @mtype is interpreted as the number of the >> message that should be copied. >> If there are less than @mtype messages, then -ENOMSG is returned. > > > Hi, Manfred. > Your approach is simplier, but makes the call less generic and adds > limitations. > I.e. sys_msgrcv() allows you to receive message by type. And from my pow > this logic have to be preserved - you can specify type and then copy all the > messages of specified type. > Your implementation adds the ability to select a message for MSG_COPY by id. But I think the price is way too high: a) added complexity b) I didn't notice it immediately: The implementation means that MSG_COPY cannot be used at all by multiple processes: task 1: msgrcv(id,buf,len,0,MSG_COPY). task 2: msgrcv(id,buf,len,0,MSG_COPY). It is unpredictable if a task receives the first or the 2nd message from the queue. task 1: int msgnr=0; msgctl(id,MSG_SET_COPY,&msgnr) msgrcv(id,buf,len,0,MSG_COPY). task 2: int msgnr=0; msgctl(id,MSG_SET_COPY,&msgnr) msgrcv(id,buf,len,0,MSG_COPY). Doesn't work either, it's a race condition. > >> b) I do not understand the purpose of the decrease of msq->q_copy_cnt: >> Do you want to handle normal msgrcv() calls in parallel with >> msgrcv(|MSG_COPY) calls? > > > Actually, I'm not going to copy a message from a queue, when somebody is > reading from it. But better to handle this case by decreasing > msq->q_copy_cnt, because otherwise this counter becomes invalid in case of > somebody is reading from queue. And this logic is similar to new "peek" > logic for sockets (introduced in 3.4 or 3.5). > But I understand, that in case of queue with messages with different types > this approach works only if mtype is not specified for copy operation. > Otherwise result is unpredictable. > a) If the result is unpredictable when mtype is used,…
creator: Manfred Spraul
date: 2012-08-12T09:48:18-00:00

Re: [PATCH v3 08/10] IPC: message queue copy feature introduced
type: item
description: 12.08.2012 13:48, Manfred Spraul пишет: > I would keep it simple - unless there is a clear use case where "peek > by id" is useful. > > Or - since MSG_COPY is linux specific anyway: > What about storing the number of the message that should be returned in *msgp? > Store it as "int64", just to avoid any 32/64 bit issues. Sounds reasonable. But, probably, mtype suit better for message number. I'll update. -- Best regards, Stanislav Kinsbursky
creator: Stanislav Kinsbursky
date: 2012-08-13T10:35:26-00:00