Re: Man page typo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Mihai, Michael,

On Wed, Apr 21, 2010 at 4:13 AM, Michael Witten <mfwitten@xxxxxxxxx> wrote:
> On Sun, Apr 18, 2010 at 10:57, Mihai Paraschivescu <paraschivescu_mihail@xxxxxxxxx> wrote:
>> If I'm not wrong, the exact name of that field in
>> the msqid_ds structure is msg_qbytes. The
>> same thing appears also on the online manual
>> pages, I checked it already.

I have corrected this in the man page (for 3.25).

> You are correct.
>
> The POSIX man pages do indeed list `msg_qbytes' for what seems
> like the equivalent concept of what the Linux man page lists as
> `msg_bytes'. The glibc header file <sys/msg.h> (specifically
> <bits/msq.h>) defines `struct msqid_ds' with not `msg_bytes'
> but rather `msg_qbytes'; the field `msg_qbytes' can indeed be
> set with `msgctl()' according to glibc's implementation of that
> function (see "sysdeps/unix/sysv/linux/i386/msgctl.c" in the
> glibc source).
>
> However, the Linux kernel seems to implement this messaging
> system on top of a more general IPC subsystem; `MSGMNB' (as
> referenced in the Linux man page) is used to set the field
> `msg_ctlmnb' of an object of type `struct ipc_namespace'
> (http://lxr.linux.no/#linux+v2.6.33/ipc/msg.c#L115):
>
>    112 void msg_init_ns(struct ipc_namespace *ns)
>    113 {
>    114         ns->msg_ctlmax = MSGMAX;
>    115         ns->msg_ctlmnb = MSGMNB;              /* <------------------- */
>    116
>    117         recompute_msgmni(ns);
>    118
>    119         atomic_set(&ns->msg_bytes, 0);        /* see below */
>    120         atomic_set(&ns->msg_hdrs, 0);
>    121         ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
>    122 }
>
> When creating a queue, an object of type `struct
> msg_queue' is created, and it's `q_qbytes' field is
> set to the associated namespace's `msg_ctlmnb' field
> (http://lxr.linux.no/#linux+v2.6.33/ipc/msg.c#L215):
>
>    181 static int newque(struct ipc_namespace *ns, struct ipc_params *params)
>    182 {
>    183         struct msg_queue *msq;
>    ...
>    215         msq->q_qbytes = ns->msg_ctlmnb; /* <------- Essentially assign MSGMNB */
>    ...
>    223         return msq->q_perm.id;
>    224 }
>
> So, it would appear that the Kernel internally uses `q_qbytes'
> of a `struct msg_queue' for what POSIX (userland side) considers
> `msg_qbytes' of a `struct msqid_ds'.
>
> This is corroborated by how the kernel implements the
> `msgctl()' system call to set a queue's maximum byte capacity
> (http://lxr.linux.no/#linux+v2.6.33/ipc/msg.c#L412):
>
>    412 static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
>    413                        struct msqid_ds __user *buf, int version)
>    414 {
>    ...
>    416         struct msqid64_ds uninitialized_var(msqid64);
>    417         struct msg_queue *msq;
>    418         int err;
>    419
>    420         if (cmd == IPC_SET) {
>    421                 if (copy_msqid_from_user(&msqid64, buf, version))   /* Copy from userspace */
>    422                         return -EFAULT;
>    423         }
>    ...
>    440         case IPC_SET:
>    441                 if (msqid64.msg_qbytes > ns->msg_ctlmnb &&
>    442                     !capable(CAP_SYS_RESOURCE)) {
>    443                         err = -EPERM;
>    444                         goto out_unlock;
>    445                 }
>    446
>    447                 msq->q_qbytes = msqid64.msg_qbytes;                 /* <------- Set here with a copy of input */
>    ...
>    462         }
>
> So, it's pretty clear that the `q_qbytes' of a `struct msg_queue'
> is indeed the kernelspace version of the POSIX `msg_qbytes' of a
> `struct msqid_ds'.
>
> So, my question is, what is the `msg_bytes' of
> a `struct ipc_namespace'? Here's how it's used
> in the kernel's implementation of `msgsnd()'
> (http://lxr.linux.no/#linux+v2.6.33/ipc/msg.c#L712):
>
>    636 long do_msgsnd(int msqid, long mtype, void __user *mtext,
>    637                 size_t msgsz, int msgflg)
>    638 {
>    639         struct msg_queue *msq;
>    ...
>    641         int err;
>    642         struct ipc_namespace *ns;
>    643
>    644         ns = current->nsproxy->ipc_ns;  /* from current task */
>    ...
>    708                 /* noone is waiting for this message, enqueue it */
>    709                 list_add_tail(&msg->m_list, &msq->q_messages);
>    710                 msq->q_cbytes += msgsz;
>    711                 msq->q_qnum++;
>    712                 atomic_add(msgsz, &ns->msg_bytes);     /* <-------------------- */
>    ...
>    724         return err;
>    725 }
>
> As you can see, `q_qnum' of a `struct msg_queue' corresponds
> to the POSIX `msg_qnum' of a `struct msqid_ds'; interestingly,
> the kernel also keeps track of the number of message bytes
> currently on the queue by using the field `q_cbytes' of a
> `struct msg_queue', which corresponds to the "private" field
> `__msg_cbytes' that glibc defines as an extension to the standard
> POSIX `struct msqid_ds'.
>
> More to the point, it would seem that the `msg_bytes' of a
> `struct ipc_namespace' is just the more general IPC namespace
> subsystem's personal copy of that byte count, so that whoever
> referenced `msg_bytes' in the Linux man page made a mistake in
> using it.
>
> My suggestion is that these sentences from the current msgsnd(2):
>
>    The queue capacity is defined by the msg_bytes field
>    in the  associated data structure for the message queue.
>    During queue creation this field is initialized to MSGMNB
>    bytes, but this limit can be modified using msgctl(2).
>
> should remove all references to such implementation details and
> instead stick to the user interface:
>
>    The queue capacity can be queried and set using
>    msgctl(2) and the msg_qbytes field of its msqid_ds
>    pointer parameter.

Michael, your analysis of the code is detailed, but the pieces that
you describe as implementation details are either actually important
userspace details. Associated data" is a general concept for SVIPC,
and MSGMNB is a user visible limit (that can be modified vua /proc).

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface" http://blog.man7.org/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux