Busybox-Httpd als websrv-Ersatz

McNetic

Mitglied
Mitglied seit
7 Feb 2007
Beiträge
674
Punkte für Reaktionen
0
Punkte
16
Wie im Inetd-Thread bereits angesprochen kann der Busybox-Httpd eventuell als Ersatz für den speicherhungrigeren websrv aus der Original-FW dienen.

Die Pfadprobleme des BB-Httpd aus Version 1.4.1 sind ja mit dem Inetd-Patch bzw. dem kommenden ds26-15 behoben. Das Webinterface an sich und die Einstellungsmöglichkeiten funktioniert somit.

Offene Punkte sind somit noch:

  • LCR-Autoupdater (kriegaex?)
  • Firmware-Update
    Das habe ich mir jetzt mal genauer angesehen. Meine Vermutung, dass nach dem Upload des Images firmwarecfg selbst am Port 80 lauscht um eine nicht signierte Firmware zu bestätigen war wohl falsch. Ich dachte wohl, mal beobachtet zu haben, dass zu diesem Zeitpunkt der websrv nicht mehr lief - sorry.

    Jedenfalls habe ich mal /bin/prepare_fwupdate so angepasst, dass auch ein laufender httpd gekillt wird (an den Stellen, wo bisher der websrv beendet wird - ich denke, es wäre im dsmod auch generell sinnvoll, diese Datei anzupassen, damit auch die anderen zusätzlichen Dienste vom Mod beendet werden - zum Einen wegen dem Speicher zum Auspacken des Images, zum anderen weil verschiedene Dienste, insbesondere die DSMod-Konfiguration auch parallel noch ins Flash schreiben könnten, was wohl eher suboptimal ist), den websrv beendet und das WebIf stattdessen über httpd gestartet.

    Das Update startet auch so weit, dass prepare... aufgerufen wird, dann das Image ausgepackt wird - und irgendwann bricht es dann ab mit der Meldung "Das Firmware-Update ist fehlgeschlagen: Die angegebene Datei ist zu groß.". Das Verhalten an der Stelle ist reproduzierbar. Und diesmal liegt es auch prinzipiell nicht am httpd, denn ich habe das gleiche dann auch noch mit dem thttpd ausprobiert - WebIf läuft (wie bereits erwähnt), Firmware-Update bricht mit gleicher Fehlermeldung ab. Wer es testen möchte, im Anhang ist der thttpd. Gestartet werden muss er mit
    Code:
    thttpd -d /usr/www/html/ -nos -u root -c /cgi-bin/*
    Vorher muss man verschiedenen Dateien in /usr/www/html/die Ausführungsrechte entziehen (chmod 644 /usr/www/html/html/*.html), dann funktioniert das WebIf zumindest rudimentär (thttpd liefert keine Dateien aus, die ein x gesetzt haben, ausser CGIs).

    Ich bin jetzt ziemlich ratlos, woran das liegen könnte. Vielleicht hat ja jemand anders noch eine Idee.

Gruss, Nico
 

Anhänge

FirmwareUpdate als ds-mod Paket

Zum Firmwareupdate. Ich würde es nicht so tragisch sehen, wenn es mit AVM-Webinterface nicht gehen würde. Ich hatte schon vor einer Weile hier nachgefragt, wie man Remote-Update (aus dem Internet aus, nicht aus dem internen LAN-Netz) der Box realisieren könnte. Alex hat dazu auch sofort einen fertigen Skript realisiert. Ich hatte mir die Sache nicht näher angeschaut, da ich zunächst mit meinem Downloader beschäftigt war. Man kann jedoch die Ideen von Alex auch als WebFronted realisieren. Zum Teil kann man die WebCGI vom Downloader nehmen und es dann darein integrieren, oder separat realisieren. Also ein eigenes UpdateCGI schreiben mit erweiterten Möglichkeiten. In diesem CGI und in den dazugehörigen Skripten kann man (und sollte man sogar!) die ds-mod Dienste beenden. Also entweder eine Alternative zu prepare_firmware, oder etwas was davor/danach/währenddessen aufgerufen wird.
Ich persönlich bin zurzeit völlig busy um sowas zu schreiben. Wenn einer sich dazu bereit erklären sollte, stehe ich gerne als Unterstützung zur Verfügung.

MfG
 
Das wäre sicherlich auch eine Möglichkeit. Die Frage ist dabei aber auch, wie in Zukunft mit dem AVM-WebIf umgegangen werden soll. Wenn hier verschiedene Sachen nicht mehr funktionieren oder obsolet sind, wird das sicherlich zu mehr unnötigen Supportanfragen führen. Ausserdem weiss ich auch nicht genau, wie Danisahne vorhat, damit im 'neuen' Dsmod umzugehen - so wie ich es verstanden habe, sollen da ja keine Patches von Original-AVM-Dateien mehr drin sein?

Aber an sich denke ich, es wäre schon optimal, die Funktionalität des Original-WebIf so weit wie möglich zu erhalten. Ich kann mir auch vorstellen, dass das mit dem httpd möglich ist, das Update startet ja ganz normal, der Fehler ist nur etwas obskur...
 
Meine Meinung zu dem Thema ist, daß es sich um eine technisch interessante Herausforderung handelt, aber potentiell Instabilität in den Mod bringt. Daniels Grundsatz - deshalb wurde überhaupt ursprünglich httpd für den Mod verwendet - ist, das AVM-Original möglichst wenig anzufassen und zu manipulieren und im Mod nur zusätzliche Funktionalität anzubieten. Dinge wie das Entfernen oder Ersetzen von Original-Binaries kamen später aus einem einzigen Grund dazu (bzw. weg): Platzmangel im Flash.

Es gibt vermutlich außer beim FW-Update noch andere Stellen, wo darauf gesetzt wird, daß ein websrv mit bestimmten Aufrufparametern existiert und/oder läuft. So ein Prozeß wird dann evtl. mittels ps gesucht, mit Parametern gestartet, die man in einem Wrapper-Skript oder -Binary emulieren müßte, um Legacy-Anwendungen zufriedenzustellen usw. Wir würden also genau das tun, was Daniel ursprünglich vermeiden wollte: AVM hinterher programmieren - oder eben dem LCR Updater (obwohl man mit telefonsparbuch.de bestimmt reden könnte).

Was ich damit sagen möchte, ist, daß ich rein gefühlsmäßig momentan keine großen Chancen und auch wenig Bedarf sehe, websrv durch httpd abzulösen, auch wenn es evtl. bzgl. RAM-Bedarf und reiner "Schönheits-Aspekte" bzw. wegen inetd wünschenswert wäre. Ich beobachte aber weiter Eure Erkenntnisse zum Thema und werde irgendwann auch mal mit dem LCR herumspielen.

es wäre schon optimal, die Funktionalität des Original-WebIf so weit wie möglich zu erhalten
... und das geht am einfachsten mit websrv selbst - Binsenweisheit.

Frage: Wie hoch ist denn ca. der Speicherbedarf von httpd, wenn er die AVM-Seiten serviert? Im Vergleich habe ich mal Folgendes gemacht:
Code:
# Erst mal wegräumen und neu starten
killall websrv
websrv

# Jetzt einfach mal http://fritz.box im Browser aufrufen.
# Der Speicherbedarf geht kurzzeitig hoch, beruhigt sich aber nach
# dem Schließen des Browsers wieder. Vielleicht nach der Aktion
# mal 30 Sekunden warten. Dann hier weiter:
free

# Nochmal websrv wegräumen und Unterschied bei "Total - free" notieren
killall websrv
free
So ungefähr komme ich dabei auf 700 KB RAM-Bedarf im Ruhezustand des Servers, ca. 30-60 Sekunden nach der letzten Benutzung. Wie sieht das Ganze mit httpd aus? Achtung, auch die anderen httpd-Prozesse (DS-Mod, WoL) mit killall wegräumen, damit sie nicht mit einkalkuliert werden.

P.S.: Umgekehrt sollte es auch gehen - DS-Mod- und WoL-Web-Oberfläche im websrv laufen lassen. Die Rudi-Shell z.B. läuft samt Haserl darin (auch ohne DS-Mod), das hat schon jemand probiert.
 
Zuletzt bearbeitet:
Tja. Mir ist wie gesagt völlig unklar, warum es mit dem websrv geht und mit dem httpd nicht - der Ablauf an sich funktioniert ja zumindest bis zum Auspacken korrekt.

Was den Speicherbedarf betrifft: Mit Deiner Methode komme ich auf ca. 440 KB RAM-Bedarf beim websrv gegenüber 170 KB beim httpd.
 
McNetic schrieb:
der Ablauf an sich funktioniert ja zumindest bis zum Auspacken korrekt

Heißt das inklusive oder exklusive Auspacken?
 
Das Auspacken startet in jedem Fall, d.h. es ist für einige Zeit (ähnlich lange wie bei einem 'funktionierenden' Update) der tar-Prozess sichtbar.
 
Könnte es einfach sein, daß ihm beim Entpacken der RAM-Speicher ausgeht, weil Du noch ds26-Dienste laufen hast? Stoppe die mal bitte vor dem Update, falls Du das noch nicht probiert hast.

Noch eine Frage: Sieht man das Image bei beiden Varianten (websrv bzw. httpd) jeweils im Dateisystem? Im Grunde könnte man ja auch die Datei direkt beim Hochladen auf der Box in die Standardeingabe von Tar schreiben (Pipeline bzw. FIFO). Wie AVM das macht, habe ich bisher nie untersucht. Wenn ich ab und zu via Telnet manuell flashe, arbeite ich normalerweise so, daß ich das Archiv nicht erst komplett abspeichere und entpacke, sondern z.B. aus Wget heraus direkt an Tar weiterleite.
 
Das mit dem RAM kann ich mir nicht vorstellen. Ich habe alles unnötige abgeschossen (bis auf meinen telnet-Prozess). Dadurch, dass der websrv nicht läuft, sollte sogar mehr Speicher frei sein. Und wie gesagt, beim Update über websrv waren es die gleichen Bedingungen.

Zur zweiten Frage: Ich denke, AVM macht das genau so. Ich weiss es nicht mehr exakt, aber der tar-Prozess sieht bei ps nur so ähnlich aus 'tar xf -', d.h. er liest von stdin.

EDIT: Jetzt habe ich eine Idee. Es wäre evtl. denkbar, dass es sich wieder um ein Pfad-Problem handelt, d.h. dass das cgi evtl. im falschen Pfad ausgeführt wird, und der tar darum zu einem falschen Ziel entpackt. Frage ist bloss, wie kann man das nachvollziehen.
 
Indem Du schaust, wo die Dateien landen, die tar entpackt. Normalerweise muß im Root-Verzeichnis entpackt werden. Wenn er woanders versucht, ein var-Verzeichnis usw. anzulegen, paßt es nicht. Sollte er versuchen, das Entpacken sogar in einem Read-Only-Verzeichnis zu machen, geht es komplett schief, und das könnte er interpretieren als "Festplatte voll" = "Image zu groß".

Wenn du schnell genug bist, kannst Du über ps die PID von tar ermitteln oder direkt mittels
Code:
cat /proc/$(pidof tar)/environ
das Environment auslesen bzw. über
Code:
ls -l /proc/$(pidof tar)/cwd
das aktuelle Arbeitsverzeichnis des Prozesses feststellen.
 
Tja. Interessantes Ergebnis:

1) websrv hat als cwd /
2) httpd hat als cwd /usr/www/html (d.h. das Webroot)
3) tar hat in beiden Fällen als cwd /
4) Und jetzt der Clou (bzw. das Problem oder auch des Pudels Kern):

websrv-Environment:
Code:
PATH=/bin:/usr/bin
SERVER_SOFTWARE=AVM websrv
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.0
REQUEST_METHOD=POST
PATH_INFO=/cgi-bin/firmwarecfg
PATH_TRANSLATED=/usr/www/html/cgi-bin/firmwarecfg
SCRIPT_NAME=/cgi-bin/firmwarecfg
REMOTE_ADDR=192.168.216.6
HTTP_REFERER=http://fritz.box/cgi-bin/webcm?getpage=..%2Fhtml%2Fde%2Fmenus%2Fmenu2.html&errorpage=..%2Fhtml%2Fde%2Fmenus%2Fmenu2.html&var%3Alang=de&var%3Apagename=update_OnClick_1&var%3Aerrorpagename=update_OnClick_1&var%3Amenu=system&var%3Apagemaster=&time%3Asettings%2Ftime=1181933736%2C-120&var%3Ashowall=&logger%3Asettings%2Ffilter=2
HTTP_USER_AGENT=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4
HTTP_ACCEPT=text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
HTTP_ACCEPT_ENCODING=gzip,deflate
HTTP_ACCEPT_LANGUAGE=de-de,en-us;q=0.7,en;q=0.3
CONTENT_TYPE=multipart/form-data; boundary=---------------------------297202307116038
HTTP_HOST=fritz.box
CONTENT_LENGTH=5499125
TZ=CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00
OEM=avm
Country=049
CONFIG_FON=y
CONFIG_WLAN=y
CONFIG_DSL=y
CONFIG_INSTALL_TYPE=ar7_8MB_xilinx_4eth_3ab_isdn_nt_te_pots_wlan_usb_host_25762
CONFIG_VERSION_MAJOR=29
CONFIG_VERSION=04.33
CONFIG_SUBVERSION=ds-0.2.9_26-14
CONFIG_ROMSIZE=8
CONFIG_PRODUKT_NAME=FRITZ!Box Fon WLAN 7170
ANNEX=B
CLIENTCONNECTION=192.168.216.6:52995

httpd-Environment
Code:
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/mod/sbin:/mod/bin:/mod/usr/sbin:/mod/usr/bin
SERVER_PORT=80
PATH_INFO=
REQUEST_METHOD=POST
REQUEST_URI=/cgi-bin/firmwarecfg
SCRIPT_FILENAME=/usr/www/all/cgi-bin/firmwarecfg
SCRIPT_NAME=/cgi-bin/firmwarecfg
QUERY_STRING=
SERVER_SOFTWARE=busybox httpd/1.35 6-Oct-2004
SERVER_PROTOCOL=HTTP/1.0
GATEWAY_INTERFACE=CGI/1.1
REMOTE_ADDR=192.168.216.6
CONTENT_LENGTH=5499121
CONTENT_TYPE=multipart/form-data; boundary=---------------------------9154587311099
HTTP_REFERER=http://fritz.box/cgi-bin/webcm?getpage=..%2Fhtml%2Fde%2Fmenus%2Fmenu2.html&errorpage=..%2Fhtml%2Fde%2Fmenus%2Fmenu2.html&var%3Alang=de&var%3Apagename=update_OnClick_1&var%3Aerrorpagename=update_OnClick_1&var%3Amenu=system&var%3Apagemaster=&time%3Asettings%2Ftime=1181933041%2C-120&var%3Ashowall=&logger%3Asettings%2Ffilter=2

Fraglich ist jetzt, woher genau die Environment-Variablen kommen (websrv oder firmwarecfg) und warum sie, wenn letzteres der Fall ist, beim httpd nicht gesetzt werden können. Ich bin mal wieder ratlos.
 
So, TV-Werbepause... ganz kurz mal: Umgebungsvariablen werden z.B. gesetzt durch
Code:
. /etc/init.d/rc.conf
, falls sie aus dem aufrufenden Prozeß exportiert werden sollen. In httpd.c wiederum wird das Environment gesetzt mittels diverser Aufrufe von setenv1, z.B. in sendCgi. Da könnte man bei Bedarf leicht zusätzliche Variablen hinein patchen. Ein Beispiel für das Durchreichen einer Environment-Variablen ist z.B. in der auskommentierten Zeile
Code:
setenv1("PATH", getenv("PATH"));
zu sehen. Viel Spaß beim Probieren, ich gebe an dieser Stelle nur theoretische Tips - es sei mir verziehen, hoffe ich.
 
Die Environment-Variablen, für die sich das firmwarecfg interessiert, sind:
CONFIG_ROMSIZE
REMOTE_ADDR
REQUEST_METHOD
CONTENT_LENGTH
TZ
LD_BIND_NOW

Mit diesem Patch funktioniert es. Wichtig ist vor allem der dritte Teil, clearenv() entfernen. Eleganter wäre es, dafür eine Option zu verwenden. Im ersten Teil wird noch der Buffer vergrößert, das ist nur für die Effizienz. Der zweite Teil schließt den Server-Socket im Child-Prozeß, das hat aber vermutlich keine Auswirkungen.
Code:
--- networking/httpd.c~
+++ networking/httpd.c
@@ -1245,7 +1245,7 @@
        while (1) {
                fd_set readSet;
                fd_set writeSet;
-               char wbuf[128];
+               char wbuf[4096];
                int nfound;
                int count;

@@ -1955,6 +1955,8 @@

                if (DEBUG || fork() == 0) {
                        /* child */
+                       if (!DEBUG)
+                               close(server);
 #if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
                        /* protect reload config, may be confuse checking */
                        signal(SIGHUP, SIG_IGN);
@@ -2123,7 +2125,7 @@
        {
                char *p = getenv("PATH");
                p = xstrdup(p); /* if gets NULL, returns NULL */
-               clearenv();
+               //clearenv();
                if (p)
                        setenv1("PATH", p);
                if (!(opt & OPT_INETD))
httpd wird dann gestartet mit
Code:
env -i CONFIG_ROMSIZE=8 httpd -h /usr/www/all
Anscheinend geht firmwarecfg ohne CONFIG_ROMSIZE davon aus, daß es sich um ein Gerät mit 4MB handelt. Nachdem andere Werte auch schon aus /proc/sys/urlader/environment gelesen werden, hätte es von dort auch die Größe des Flash-Speichers haben können, aber es läßt sich nun mal nicht ändern.

Beim Update erscheint dann die Meldung, daß die Firmware nicht von AVM ist.
Diese Seite enthält zwei normale POST-Formulare, die beide wieder firmwarecfg aufrufen, nur mit unterschiedlichen Werten für den Submit-Knopf.
Der Web-Server muß an dieser Stelle also noch laufen.
Die IP-Adresse des Clients steht in /var/tmp/fw_ip. firmwarecfg überprüft, ob das Update von dieser Adresse kommt.

Ich habe dann installieren ausgewählt, es erscheint die Meldung "Update fehlgeschlagen, Kein Fehler".
/var/install wurde anscheinend ausgeführt, /var/post_install wurde für ein Update angelegt, was noch fehlt, ist nur der Neustart. Das ist aber mit dem websrv auch so.

Wenn ich auf dieser Seiten "Neu Starten" auswähle, startet die Box tatsächlich neu und scheint das Update auch ausgeführt zu haben.

Es sieht also aus, als wäre env -i CONFIG_ROMSIZE=8 httpd -h /usr/www/all mit dem obigen Patch ein Ersatz für den websrv.
Man könnte das env aus weglassen, aber dann würde httpd und die CGI-Skripte das gesamte Environment mit sich herumschleppen.

Interessant ist dabei für mich noch weniger die Datei websrv, die man einsparen damit könnte, denn die ist nur ca. 67kB groß. Wichtiger sind mir die knapp 6MB Hauptspeicher, die verbraucht werden, wenn websrv läuft.
 
Wie kommst Du auf 6 MB Hauptspeicher? Ich messe (s.o.) ca. 700 KB, wenn websrv gerade etwas tut, sind es mehr.
 
Die knapp 6MB sind aus der Anzeige von ps oder top.
Code:
  PID  Uid        VSZ Stat Command
  812 root       1392 S   httpd
 1456 root       5980 S N websrv
 1457 root       5980 R N websrv
 1458 root       5980 S N websrv
 1459 root       5980 S N websrv
Allerdings ist das die Virtuelle Größe und damit nicht maßgeblich für den echten Speicherbedarf. War schon etwas spät gestern Abend.
Die Ausgabe von free ist aber auch nicht aussagefähig. Ich habe mal einige Seiten der Web Oberfläche angewählt, nur angeschaut, nichts gespeichert. Dabei ist die Anzeige von free nach einigen leichten Schwankungen plötzlich von 1332 auf 3548 gesprungen, ohne daß ich etwas auf der Box gestoppt hätte.
Ich hab mal das richtige ps für die Box erstellt, dies zeigt
Code:
F   UID  PID PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
1     0  812    1  20   0   1392   388 -      S    ?          0:00 httpd 
5     0 1456    1  34  19   5980  1796 -      SN   ?          0:08 websrv
1     0 1457 1456  34  19   5980  1796 -      SN   ?          0:00 websrv
5     0 1458 1457  39  19   5980  1796 -      SN   ?          0:00 websrv
5     0 1459 1457  39  19   5980  1796 -      SN   ?          0:00 websrv
Auch die einzelnen Seiten vom ds-mod hatte ich vorher aufgerufen. Anscheined ist der Speicherverbrauch vom websrv nicht so groß, wie es zunächst ausgesehen hat. Trotzdem ist der Unterschied immer noch deutlich.

Vor allem bringt es wenig, zwei Web-Server auf der Box laufen zu lassen, wenn dies nicht notwendig ist.

Weißt Du, warum das ds-mod den httpd verwendet und nicht den websrv? Das wäre doch vermutlich die einfachste Lösung gewesen.

Wenn aber beide funktionieren, scheint mir der httpd besser geeignet zu sein. Könnte man zumindest als Option anbieten.
 
RalfFriedl schrieb:
Weißt Du, warum das ds-mod den httpd verwendet und nicht den websrv? Das wäre doch vermutlich die einfachste Lösung gewesen.
Wie erwähnt, wollte danisahne unabhängig von irgenwelchen AVM-Capricen sein, sich auch nicht ins dortige Menü einhängen, und die BusyBox war sowieso schon da.

RalfFriedl schrieb:
Wenn aber beide funktionieren, scheint mir der httpd besser geeignet zu sein.
Funktioniert es denn wirklich? Du hattest noch das geschrieben:

RalfFriedl schrieb:
Ich habe dann installieren ausgewählt, es erscheint die Meldung "Update fehlgeschlagen, Kein Fehler".
/var/install wurde anscheinend ausgeführt, /var/post_install wurde für ein Update angelegt, was noch fehlt, ist nur der Neustart. Das ist aber mit dem websrv auch so.
Wozu ein manueller Neustart? Das ist normalerweise nicht nötig mit websrv. Oder hast Du ein selbst erstellltes Dummy-Image, das nur aus einem Install-Skript besteht (ähnlich dem, um Telnet zu aktivieren), getestet?
 
kriegaex schrieb:
Wozu ein manueller Neustart? Das ist normalerweise nicht nötig mit websrv.
Ich habe das Update-Image genommen, das mit ds-mod erzeugt wurde. Mit websrv passiert bei mir aber genau das Gleiche, sonst hätte ich das als Abweichung aufgeführt.
Es kann sein, daß das mit dem W900V und Überresten der Telekom-Firmware zusammenhängt.
 
Kostenlos!

Statistik des Forums

Themen
248,106
Beiträge
2,281,567
Mitglieder
377,316
Neuestes Mitglied
jrf