bug-hurd
[Top][All Lists]
Advanced

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

MACH_SEND_MSG_TOO_SMALL is mig breakage (was: Re: current CVS Hurd and g


From: Marcus Brinkmann
Subject: MACH_SEND_MSG_TOO_SMALL is mig breakage (was: Re: current CVS Hurd and glibc (except libthreads)
Date: Tue, 30 Jul 2002 02:12:49 +0200
User-agent: Mutt/1.4i

On Mon, Jul 29, 2002 at 04:17:28PM -0700, Thomas Bushnell, BSG wrote:
> > The other bug I found very soon is that "cat /some/file" gives a write
> > IPC error "msg too small".  Apparently, similar failures happen when
> > programs try to read configuration files (ping can not lookup icmp service
> > in /etc/services, for example).
> 
> Sounds for all the world like a version number mismatch in an RPC.  

Ha, it's much more interesting.

the "msg too small" is coming from the kernel, and it means that the io_write
client stub generated a wrong message.  I played a bit with dd and found out
that this was triggered if more than 2048 bytes were sent at once.

This is the limit up to which data is inlined.

/* Routine io_write */
mig_external kern_return_t __io_write
(
        io_t io_object,
        data_t data,
        mach_msg_type_number_t dataCnt,
        loff_t offset,
        vm_size_t *amount
)
{
        typedef struct {
                mach_msg_header_t Head;
                mach_msg_type_long_t dataType;
                char data[2048];
                mach_msg_type_t offsetType;
                loff_t offset;
        } Request;

Now, let's take a look at how size is calculated:

        msgh_size_delta = (InP->dataType.msgtl_header.msgt_inline) ?
(dataCnt + 3) & ~3 : sizeof(char *);

sizeof(char *) bytes of DATA are used when we don't inline, for the pointer. 
Otherwise, a multiple of a word bytes of DATA are used to inline.  This is
what is used from DATA.  Now the whole size:

        msgh_size = 52 + msgh_size_delta;

sizeof (mach_msg_header_t) is 24, sizeof (mach_msg_type_long_t) is 12,
sizeof (mach_msg_type_t) is 4, sizeof (loff_t) is 8.  The total is
48 + whatever we use from DATA, not 52 + whatever we use from DATA.
So MiG miscalculates the size of the message, doesn't it?

Now, don't ask me why it miscalculates the size.  I tried the old io.defs,
and it calculates the size correctly to 44 (with off_t being an int). 
Something is messed up here.  I looked into the MiG sources, but it is not
obvious to me.  Maybe an alignment issue?  Note that to actually get the
offset immediately after the DATA pointer, mig changes the pointer of InP
temporarily.

Thanks,
Marcus

-- 
`Rhubarb is no Egyptian god.' GNU      http://www.gnu.org    marcus@gnu.org
Marcus Brinkmann              The Hurd http://www.gnu.org/software/hurd/
Marcus.Brinkmann@ruhr-uni-bochum.de
http://www.marcus-brinkmann.de/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]