Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Tue, 13 Aug 2002 11:56:04 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Tue, 13 Aug 2002 11:56:04 -0400 Received: from c-24-126-73-164.we.client2.attbi.com ([24.126.73.164]:10490 "EHLO kegel.com") by vger.kernel.org with ESMTP id ; Tue, 13 Aug 2002 11:55:54 -0400 Date: Tue, 13 Aug 2002 09:04:25 -0700 From: dank@kegel.com Message-Id: <200208131604.g7DG4PO03553@kegel.com> To: linux-kernel@vger.kernel.org Subject: [PATCH] Fix crash bugs in khttpd Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12216 Lines: 425 This patch has been working for me for some time. It's been posted both on l-k and on the khttpd mailing list. It not only fixes oopses, it also adds crucial usage notes to the readme. Although this is against 2.4.17, it seems to apply cleanly to 2.4.19. Marcello, please apply. - Dan diff -x '*times*' -x '.*' -x '*.o' -Naur linux-2.4.17-orig/net/khttpd/README linux/net/khttpd/README --- linux-2.4.17-orig/net/khttpd/README Thu Nov 16 14:07:53 2000 +++ linux/net/khttpd/README Mon May 27 22:43:43 2002 @@ -44,6 +45,7 @@ echo 1 > /proc/sys/net/khttpd/stop echo 1 > /proc/sys/net/khttpd/unload + sleep 2 rmmod khttpd @@ -71,7 +73,7 @@ Before you can start using kHTTPd, you have to configure it. This is done through the /proc filesystem, and can thus be done from inside - a script. Most parameters can only be set when kHTTPd is not active. + a script. Most parameters can only be set when kHTTPd is stopped. The following things need configuration: @@ -117,26 +119,31 @@ Port 8080 + Starting kHTTPd + =============== + Once you have set up the configuration, start kHTTPD by running + echo 1 > /proc/sys/net/khttpd/start + It may take a jiffie or two to start. - Stopping kHTTPd =============== - In order to change the configuration, you should stop kHTTPd by typing + To stop kHTTPd, do echo 1 > /proc/sys/net/khttpd/stop - on a command-prompt. + It should stop in a jiffy or two. - If you want to unload the module, you should type + Unloading kHTTPd + =============== + To unload the module, do + echo 1 > /proc/sys/net/khttpd/stop echo 1 > /proc/sys/net/khttpd/unload - after stopping kHTTPd first. + #killall -HUP khttpd + sleep 2 + rmmod khttpd - If this doesn't work fast enough for you (the commands above can wait for + If this doesn't work fast enough for you (unloading can wait for a remote connection to close down), you can send the daemons a "HUP" signal after you told them to stop. This will cause the daemon-threads to stop immediately. - - Note that the daemons will restart immediately if they are not told to - stop. - 4. Permissions @@ -212,7 +219,21 @@ maxconnect 1000 Maximum number of concurrent connections -6. More information +6. Known Issues + kHTTPd is *not* currently compatible with tmpfs. Trying to serve + files stored on a tmpfs partition is known to cause kernel oopses + as of 2.4.18. This is due to the same problem that prevents sendfile() + from being usable with tmpfs. A tmpfs patch is floating around that seems + to fix this, but has not been released as of 27 May 2002. + kHTTPD does work fine with ramfs, though. + + There is debate about whether to remove kHTTPd from the main + kernel sources. This will probably happen in the 2.5 kernel series, + after which khttpd will still be available as a patch. + + The kHTTPd source code could use a good spring cleaning. + +7. More information ------------------- More information about the architecture of kHTTPd, the mailinglist and configuration-examples can be found at the kHTTPd homepage: @@ -221,4 +242,6 @@ Bugreports, patches, etc can be send to the mailinglist (khttpd-users@zgp.org) or to khttpd@fenrus.demon.nl + Mailing list archives are at + http://lists.alt.org/mailman/listinfo/khttpd-users diff -x '*times*' -x '.*' -x '*.o' -Naur linux-2.4.17-orig/net/khttpd/main.c linux/net/khttpd/main.c --- linux-2.4.17-orig/net/khttpd/main.c Sun Mar 25 18:14:25 2001 +++ linux/net/khttpd/main.c Mon May 27 23:17:08 2002 @@ -95,11 +95,17 @@ { int CPUNR; sigset_t tmpsig; + int old_stop_count; DECLARE_WAITQUEUE(main_wait,current); MOD_INC_USE_COUNT; + /* Remember value of stop count. If it changes, user must have + * asked us to stop. Sensing this is much less racy than + * directly sensing sysctl_khttpd_stop. - dank + */ + old_stop_count = atomic_read(&khttpd_stopCount); CPUNR=0; if (cpu_pointer!=NULL) @@ -125,11 +131,9 @@ atomic_inc(&DaemonCount); atomic_set(&Running[CPUNR],1); - while (sysctl_khttpd_stop==0) + while (old_stop_count == atomic_read(&khttpd_stopCount)) { int changes = 0; - - changes +=AcceptConnections(CPUNR,MainSocket); if (ConnectionsPending(CPUNR)) @@ -194,11 +198,9 @@ DECLARE_WAIT_QUEUE_HEAD(WQ); - sprintf(current->comm,"khttpd manager"); daemonize(); - /* Block all signals except SIGKILL and SIGSTOP */ spin_lock_irq(¤t->sigmask_lock); tmpsig = current->blocked; @@ -206,42 +208,35 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - /* main loop */ while (sysctl_khttpd_unload==0) { int I; - + int old_stop_count; /* First : wait for activation */ - - sysctl_khttpd_start = 0; - while ( (sysctl_khttpd_start==0) && (!signal_pending(current)) && (sysctl_khttpd_unload==0) ) { current->state = TASK_INTERRUPTIBLE; interruptible_sleep_on_timeout(&WQ,HZ); } - if ( (signal_pending(current)) || (sysctl_khttpd_unload!=0) ) break; + sysctl_khttpd_stop = 0; /* Then start listening and spawn the daemons */ - if (StartListening(sysctl_khttpd_serverport)==0) { + sysctl_khttpd_start = 0; continue; } - + ActualThreads = sysctl_khttpd_threads; if (ActualThreads<1) ActualThreads = 1; - if (ActualThreads>CONFIG_KHTTPD_NUMCPU) ActualThreads = CONFIG_KHTTPD_NUMCPU; - /* Write back the actual value */ - sysctl_khttpd_threads = ActualThreads; InitUserspace(ActualThreads); @@ -249,87 +244,63 @@ if (InitDataSending(ActualThreads)!=0) { StopListening(); + sysctl_khttpd_start = 0; continue; } if (InitWaitHeaders(ActualThreads)!=0) { - I=0; - while (I0) - interruptible_sleep_on_timeout(&WQ,HZ); - StopListening(); - } - - - + /* Wait for the daemons to stop, one second per iteration */ + while (atomic_read(&DaemonCount)>0) + interruptible_sleep_on_timeout(&WQ,HZ); + StopListening(); + sysctl_khttpd_start = 0; + /* reap the zombie-daemons */ + do + waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG); + while (waitpid_result>0); } - + sysctl_khttpd_start = 0; sysctl_khttpd_stop = 1; + atomic_inc(&khttpd_stopCount); /* Wait for the daemons to stop, one second per iteration */ while (atomic_read(&DaemonCount)>0) interruptible_sleep_on_timeout(&WQ,HZ); - - - waitpid_result = 1; + StopListening(); /* reap the zombie-daemons */ - while (waitpid_result>0) + do waitpid_result = waitpid(-1,NULL,__WCLONE|WNOHANG); - - StopListening(); - + while (waitpid_result>0); (void)printk(KERN_NOTICE "kHTTPd: Management daemon stopped. \n You can unload the module now.\n"); @@ -344,16 +315,13 @@ MOD_INC_USE_COUNT; - I=0; - while (INext; } - LeaveFunction("WaitHeaders"); + LeaveFunction("WaitForHeaders"); return count; } @@ -178,6 +178,12 @@ EnterFunction("DecodeHeader"); + if (Buffer[CPUNR] == NULL) { + /* see comments in main.c regarding buffer managemnet - dank */ + printk(KERN_CRIT "khttpd: lost my buffer"); + BUG(); + } + /* First, read the data */ msg.msg_name = 0; --- linux-2.4.17-orig/Documentation/networking/khttpd.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/networking/khttpd.txt Mon May 27 23:19:03 2002 @@ -0,0 +1 @@ +See net/khttpd/README for documentation on khttpd, the kernel http server. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/