Current-Users archive

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

Re: -current postfix breakage? (on sparc64)



>> In Message <20080717064233.GA20972%shrubbery.net@localhost>
 at Thu, 17 Jul 2008 06:42:33 +0000
 john heasley <heas%shrubbery.net@localhost> wrote:

 > Wed, Jul 16, 2008 at 09:16:51AM -0400, Rafal Boni:
 > > I'm having trouble with my postfix on my sparc64 machine not being able to
 > > deliver mail after upgrading the kernel to a few-day-old 4.99.69 and then
 > > upgrading userland to the matching build.  This happens on both sparc64
 > > boxes that I upgraded, in fact, but not on the shark or the SGI O2 (yes,
 > > I had a upgrade party earlier this week).
 > > 
 > > ktrace says:
 > > 
 > >  10993      1 smtp     CALL  read(0xc,0x41350010,0x1000)
 > >  10993      1 smtp     GIO   fd 12 read 27 bytes
 > >        "220 remote-mail-server ESMTP Postfix\r\n"
 > >  10993      1 smtp     RET   read 27/0x1b, 1093992464/0x41350010
 > >  10993      1 smtp     CALL  gettimeofday(0x41336668,0)
 > >  10993      1 smtp     RET   gettimeofday 0
 > >  10993      1 smtp     CALL
 > > mmap(0,0xb6891000000,3,0x14001002,0xfffffffffffffff
 > > f,0,0)
 > >  10993      1 smtp     RET   mmap -1 errno 12 Cannot allocate memory
 > > 
 > > and the log says:
 > > postfix/smtp[xxx]: fatal: mymalloc: insufficient memory: Cannot allocate
 > > memory
 > > 
 > > Sounds like something's wrong with the latest postfix import.. be
 > > interesting
 > > to know if it's endemic to all 64-bit archs, or sparc64 specific..
 > 
 > it's broken on sparc64, but not amd64.  thats basically as far as I've
 > gotten with it.  I'll try to debug it tomorrow, if no one beats me to it.

I have same problem on my sparc64 and some simple but tedium work
reveals that getsockopt() in .../util/vstream_tweak.c returns
strange value for mss.

In fact, you can check the situation with a simple program
which I attached below.

--- on sparc64 ---
[ts64]% cc temp.c
[ts64]% ./a.out
mss= 1051396
[ts64]% cc temp.c -static
[ts64]% ./a.out
mss= 0

--- on i386 ---
[tera]% cc temp.c
[tera]% ./a.out
mss= 1460
[tera]% cc temp.c -static
[tera]% ./a.out
mss= 1460

Yes, it returns different values for static link case
and dynamic link case on sparc64.

I have not enough time to investigate more, 
I use following patch to make my posfix do the work.

--- vstream_tweak.c.orig        2008-07-15 19:11:17.000000000 +0900
+++ vstream_tweak.c     2008-07-15 19:11:30.000000000 +0900
@@ -106,6 +106,10 @@
        msg_warn("%s: getsockopt TCP_MAXSEG: %m", myname);
        return (err);
     }
+    if (mss > 1500) {
+       msg_warn("%s: strange mss: %ld reduced to 1500", myname, mss);
+        mss = 1500;
+    }
     if (msg_verbose)
        msg_info("%s: TCP_MAXSEG %d", myname, mss);

HTH

Tacha
#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/tcp.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>

int main()
{
        ssize_t mss;
        socklen_t mss_len;
        struct servent *serv_ent;
        struct hostent *host_ent;
        struct sockaddr_in target;
        int s;
        int err;

        char *host = "your.web.server.is.here";
        char *service = "http";
        char *socktype = "tcp";

        memset(&target, 0, sizeof(target));

        target.sin_family = AF_INET;

        if (NULL == (host_ent = gethostbyname(host))) {
                fprintf(stderr, "gethostbyname: %s\n", hstrerror(h_errno));
                return -1;
        }

        memcpy(&target.sin_addr, host_ent->h_addr, host_ent->h_length);

        if (NULL != (serv_ent = getservbyname(service, socktype))) {
                target.sin_port = serv_ent->s_port;
        } else {
                target.sin_port = htons(80);
        }

        if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
                fprintf(stderr, "socket: %s\n", strerror(errno));
                exit(1);
        }

        if (connect(s, (struct sockaddr *)&target, sizeof(target)) == -1) {
                fprintf(stderr, "connect: %s\n", strerror(errno));
                return -1;
        }

        /* now check mss */
        if ((err = getsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
                          (char *) &mss, &mss_len)) < 0) {
                printf("err=%d\n", err);
                exit(1);
        }
        printf("mss= %d\n", mss);

        return 0;
}


Home | Main Index | Thread Index | Old Index