You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Marc Slemko <ma...@worldgate.com> on 1997/07/07 07:36:12 UTC

HUPs under Solaris

Running a test server, port 6666, as me, Solaris 2.5.1.

A HUP always gives:

bind: Invalid argument
httpd: could not bind to port 6666

and it dies.  Should this work, or am I crazy? 

Haven't had a chance to look at it yet...


Re: HUPs under Solaris

Posted by Marc Slemko <ma...@worldgate.com>.
On Mon, 7 Jul 1997, Dean Gaudet wrote:

> On Mon, 7 Jul 1997, Dean Gaudet wrote:
> 
> > Grr.  You can do "socket, dup, bind" once, but not twice (yep everything
> > is closed in between).  Nothing else seems to have this problem.  I tested
> > this with a tiny test program. 
> 
> Here's the test program I used.

Interesting.  Even if I try it on different ports each time through the
loop, it still fails. 

If I remove the close(t) and try it on different ports, it works.  Hmm.
I'm having trouble thinking of any way to put spin on it to make it look
like a feature...

I will see if I can get anyone to give me some answers.  If not, I can
probably wheedle something at the University into opening a ticket with
their support contract to see what is going on.



> 
> Dean
> 
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <errno.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> #include <netdb.h>
> 
> void main (void)
> {
>     int s, t;
>     struct sockaddr_in sa;
>     int i;
> 
>     sa.sin_family = AF_INET;
>     sa.sin_addr.s_addr = htonl (INADDR_ANY);
>     sa.sin_port = htons (2718);
> 
>     for (i = 0; i < 2; ++i) {
> 	printf ("starting loop\n");
> 	if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
> 	    perror ("socket");
> 	    exit (1);
> 	}
> 	if ((t = dup (s)) == -1) {
> 	    perror ("dup");
> 	    exit (1);
> 	}
> 	close (s);
> 	if (bind (t, (struct sockaddr *)&sa, sizeof (sa)) == -1) {
> 	    perror ("bind");
> 	    exit (1);
> 	}
> 	close (t);
>     }
>     exit (0);
> }
> 



Re: HUPs under Solaris

Posted by Dean Gaudet <dg...@arctic.org>.
On Mon, 7 Jul 1997, Dean Gaudet wrote:

> Grr.  You can do "socket, dup, bind" once, but not twice (yep everything
> is closed in between).  Nothing else seems to have this problem.  I tested
> this with a tiny test program. 

Here's the test program I used.

Dean

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

void main (void)
{
    int s, t;
    struct sockaddr_in sa;
    int i;

    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = htonl (INADDR_ANY);
    sa.sin_port = htons (2718);

    for (i = 0; i < 2; ++i) {
	printf ("starting loop\n");
	if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
	    perror ("socket");
	    exit (1);
	}
	if ((t = dup (s)) == -1) {
	    perror ("dup");
	    exit (1);
	}
	close (s);
	if (bind (t, (struct sockaddr *)&sa, sizeof (sa)) == -1) {
	    perror ("bind");
	    exit (1);
	}
	close (t);
    }
    exit (0);
}


Re: HUPs under Solaris

Posted by Dean Gaudet <dg...@arctic.org>.
On Mon, 7 Jul 1997, Marc Slemko wrote:

> On Mon, 7 Jul 1997, Dean Gaudet wrote:
> 
> > Grr.  You can do "socket, dup, bind" once, but not twice (yep everything
> > is closed in between).  Nothing else seems to have this problem.  I tested
> > this with a tiny test program. 
> 
> Any ideas why?  Interesting part is that it gives "invalid argument".
> Unless there is some structure we are using that it is messing with and
> we aren't resetting it properly...

I eyeballed the struct sockaddr_in, and it looked the same in both calls.
This really feels like a problem with the streams layer interaction.  Anyone
have access to 2.6 that can try it out?

Incidentally, the box I was doing it on was running nscd, I wonder if that
interacts at all with the servername problem you were having.  I have
access to boxes with and without nscd, I can try without later and see if
it changes anything. 

> If you don't get a chance, I have a person or two there involved with
> networking that I could try bugging...

If you've got a contact there then give them a try.  I don't officially
have any support contract with Sun and I couldn't find a damn place to get
a bugid for this ... if I could get a bugid I do know people to pass it
to, but I couldn't get to step #1.

Dean


Re: HUPs under Solaris

Posted by Marc Slemko <ma...@worldgate.com>.
BTW, I also noticed that particular server wouldn't run without me
manually setting a ServerName.   It does have proper DNS setup, so I'm
guessing that may be related.  Haven't had time to look yet or see if
NO_SLACK fixes that problem.

On Mon, 7 Jul 1997, Dean Gaudet wrote:

> Grr.  You can do "socket, dup, bind" once, but not twice (yep everything
> is closed in between).  Nothing else seems to have this problem.  I tested
> this with a tiny test program. 

Any ideas why?  Interesting part is that it gives "invalid argument".
Unless there is some structure we are using that it is messing with and
we aren't resetting it properly...

> 
> If I move the bind() before the ap_slack() it works OK.  But if I pummel
> it with SIGHUPs it still barfs.  But that's not new to 1.2.1, at least it
> isn't for me.  I get bind errors under 1.2.0 as well, when pummeling it
> with SIGHUPs that is. 
> 
> I can't reproduce this last behaviour easily in a small test program, so I
> suspect it's related to children not exiting fast enough for Solaris'
> tastes.  It's probably fixed in 2.6 when sockets move back out of userland
> into the kernel.  I'll see if I can't talk to someone at sun about this. 

If you don't get a chance, I have a person or two there involved with
networking that I could try bugging...


Re: HUPs under Solaris

Posted by Dean Gaudet <dg...@arctic.org>.
> > On Sun, 6 Jul 1997, Marc Slemko wrote:
> > 
> > > Running a test server, port 6666, as me, Solaris 2.5.1.
> > > 
> > > A HUP always gives:
> > > 
> > > bind: Invalid argument
> > > httpd: could not bind to port 6666
> > > 
> > > and it dies.  Should this work, or am I crazy? 
> > > 
> > > Haven't had a chance to look at it yet...

Grr.  You can do "socket, dup, bind" once, but not twice (yep everything
is closed in between).  Nothing else seems to have this problem.  I tested
this with a tiny test program. 

If I move the bind() before the ap_slack() it works OK.  But if I pummel
it with SIGHUPs it still barfs.  But that's not new to 1.2.1, at least it
isn't for me.  I get bind errors under 1.2.0 as well, when pummeling it
with SIGHUPs that is. 

I can't reproduce this last behaviour easily in a small test program, so I
suspect it's related to children not exiting fast enough for Solaris'
tastes.  It's probably fixed in 2.6 when sockets move back out of userland
into the kernel.  I'll see if I can't talk to someone at sun about this. 

At any rate, there are two workarounds: NO_SLACK, or using SIGUSR1 instead
of SIGHUP.  And there's the patch below that at least makes it as lame as
1.2.0 w.r.t. sighup pummeling.

Dean

--- apache_1.2.1-dist/src/http_main.c	Sun Jun 29 11:08:37 1997
+++ apache_1.2.1/src/http_main.c	Mon Jul  7 02:09:33 1997
@@ -1971,6 +1971,32 @@
     return 0;
 }
 
+
+static void sock_bind (int s, const struct sockaddr_in *server)
+{
+#ifdef MPE
+/* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
+    if (ntohs(server->sin_port) < 1024) GETPRIVMODE();
+#endif
+    if(bind(s, (struct sockaddr *)server,sizeof(struct sockaddr_in)) == -1)
+    {
+        perror("bind");
+#ifdef MPE
+        if (ntohs(server->sin_port) < 1024) GETUSERMODE();
+#endif
+	if (server->sin_addr.s_addr != htonl(INADDR_ANY))
+	    fprintf(stderr,"httpd: could not bind to address %s port %d\n",
+		    inet_ntoa(server->sin_addr), ntohs(server->sin_port));
+	else
+	    fprintf(stderr,"httpd: could not bind to port %d\n",
+		    ntohs(server->sin_port));
+        exit(1);
+    }
+#ifdef MPE
+    if (ntohs(server->sin_port) < 1024) GETUSERMODE();
+#endif
+}
+
 static int make_sock(pool *pconf, const struct sockaddr_in *server)
 {
     int s;
@@ -1982,6 +2008,10 @@
         exit(1);
     }
 
+#ifdef SOLARIS2
+    sock_bind (s, server);
+#endif
+	
     s = ap_slack(s, AP_SLACK_HIGH);
 
     note_cleanups_for_fd(pconf, s); /* arrange to close on exec or restart */
@@ -2031,27 +2061,10 @@
 	}
     }
 
-#ifdef MPE
-/* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
-    if (ntohs(server->sin_port) < 1024) GETPRIVMODE();
-#endif
-    if(bind(s, (struct sockaddr *)server,sizeof(struct sockaddr_in)) == -1)
-    {
-        perror("bind");
-#ifdef MPE
-        if (ntohs(server->sin_port) < 1024) GETUSERMODE();
-#endif
-	if (server->sin_addr.s_addr != htonl(INADDR_ANY))
-	    fprintf(stderr,"httpd: could not bind to address %s port %d\n",
-		    inet_ntoa(server->sin_addr), ntohs(server->sin_port));
-	else
-	    fprintf(stderr,"httpd: could not bind to port %d\n",
-		    ntohs(server->sin_port));
-        exit(1);
-    }
-#ifdef MPE
-    if (ntohs(server->sin_port) < 1024) GETUSERMODE();
+#ifndef SOLARIS2
+    sock_bind (s, server);
 #endif
+
     listen(s, 512);
     return s;
 }


Re: HUPs under Solaris

Posted by Dean Gaudet <dg...@arctic.org>.
Sniff, pout.  I tested this.  Under linux.  What the hell does solaris do
differently. 

Dean

On Sun, 6 Jul 1997, Marc Slemko wrote:

> Ok.
> 
> First:
> 	
> 	fopen: Interrupted system call
> 
> should retry.
> 
> I like boxes where I can recompile the server from scratch in 33 seconds
> using the distributed Configuration.  Without -O2, it runs 25.  Much nicer
> for debugging than my home box.
> 
> I just verified that using NO_SLACK fixes it.  Grr.  Grr.  This is with
> 1.2.1.
> 
> On Sun, 6 Jul 1997, Marc Slemko wrote:
> 
> > Running a test server, port 6666, as me, Solaris 2.5.1.
> > 
> > A HUP always gives:
> > 
> > bind: Invalid argument
> > httpd: could not bind to port 6666
> > 
> > and it dies.  Should this work, or am I crazy? 
> > 
> > Haven't had a chance to look at it yet...
> > 
> 
> 


Re: HUPs under Solaris

Posted by Marc Slemko <ma...@worldgate.com>.
It is also not a problem if I have a Listen directive.

Ah well, bed time.  By the time I wake up Dean will have a patch.  <g>

On Sun, 6 Jul 1997, Marc Slemko wrote:

> I just verified that using NO_SLACK fixes it.  Grr.  Grr.  This is with
> 1.2.1.
> 
> On Sun, 6 Jul 1997, Marc Slemko wrote:
> 
> > Running a test server, port 6666, as me, Solaris 2.5.1.
> > 
> > A HUP always gives:
> > 
> > bind: Invalid argument
> > httpd: could not bind to port 6666
> > 
> > and it dies.  Should this work, or am I crazy? 
> > 
> > Haven't had a chance to look at it yet...
> > 
> 


Re: HUPs under Solaris

Posted by Marc Slemko <ma...@worldgate.com>.
Ok.

First:
	
	fopen: Interrupted system call

should retry.

I like boxes where I can recompile the server from scratch in 33 seconds
using the distributed Configuration.  Without -O2, it runs 25.  Much nicer
for debugging than my home box.

I just verified that using NO_SLACK fixes it.  Grr.  Grr.  This is with
1.2.1.

On Sun, 6 Jul 1997, Marc Slemko wrote:

> Running a test server, port 6666, as me, Solaris 2.5.1.
> 
> A HUP always gives:
> 
> bind: Invalid argument
> httpd: could not bind to port 6666
> 
> and it dies.  Should this work, or am I crazy? 
> 
> Haven't had a chance to look at it yet...
>