Archive for category embedded

php on noMMU

php su una piattaforma noMMU è facilmente compilabile e funziona tranquillamente, ma ovviamente può causare problemi di frammentazione di memoria

Nel tentativo di risolvere questi problemi, ho provato a utilizzare una soluzione con lighttpd che via
fastcgi contatta php: in questo modo php viene avviato una volta e non deve essere lanciato ad ogni richiesta di un file php; la memoria occupata è quella iniziale e resta quella.

Il tutto funziona molto bene, permettendo di far girare egregiamente applicazioni php su piattaforme noMMU.
L’unico problema che ho riscontrato e che mi ha fatto perdere diverso tempo, è che php-fcgi dopo un po’ moriva senza dare errori di nessun tipo.

Dopo varie ricerche ho scoperto che questo è il comportamento normale.

Normalmente in una piattaforma con MMU avremmo un processo php, che forka n processi figli
(con n basato sulla variabile d’ambiente PHP_FCGI_CHILDREN) ognuno dei quali gestisce
al massimo PHP_FCGI_MAX_REQUESTS, che di default vale 500.
Si ritiene questo sistema il più efficiente, perché avere un processo php che gestisce infinite richieste
potrebbe permettere ad alcune funzioni php, note per avere alcuni problemi di memory leak, di destabilizzare il sistema.

Su sistemi noMMU, però, il processo php non può usare fork per creare processi figli, percui
lui da solo è l’unico che riesce a girare e dopo aver risposto alle 500 richieste di default
se ne esce bellamente, convinto di aver finito il suo lavoro.

Nel mio caso ho risolto il problema portando a 0 il numero di PHP_FCGI_MAX_REQUESTS,
cioè infinite e ora è li bello che ha già risposto a qualche centinaia di migliaia di connessioni
senza fiatare. Un’altra soluzione sarebbe modificare php in modo che possa usare vfork
invece di fork, ma questo è oltre le mie capacità e se non l’ha fatto nessun’altro, figuriamoci
se mi metto a farlo io.

Riporto parzialmente lo stesso post anche in inglese, perché so che è tornato utile ad altri:

In these days I had a problem with lighttpd and php in fastcgi mode on noMMU systems:
php dies after a while, with no error or whatsoever.

I have done some research and found that, php is dying after exactly
500 connections.

That’s normal behaviour for php in fastcgi mode.

Normally, on a MMUfull system, there would be a php process, spawning
n childrens (based on PHP_FCGI_CHILDREN environment var) each of them
handling PHP_FCGI_MAX_REQUESTS, which by default is 500.

On a noMMU system, php is not able to “fork” childrens, so it can handle only the first 500 connections.

In my case I solved by setting PHP_FCGI_MAX_REQUESTS to 0 and
now php never dies. I didn’t tried to patch php to use vfork
instead of fork, ’cause it is probably beyond my abilities,
but that may be another solution … even if this may lead
to more memory fragmentation.

, ,

No Comments

Asterisk non va senza ADSL, soluzione

È un problema noto che Asterisk smette di funzionare e di permettere le chiamate anche tra telefoni interni, quando l’ADSL non va o in generale non funziona il DNS. Provate infatti a cercare con google “asterisk DNS problem” o “asterisk adsl non va”, o cose simili e avrete decine di link a persone che si sono scontrate con questo problema.

Il problema sta nel fatto che chan_sip si arrabbia, se non può contattare il DNS e si blocca. Nell’attesa, già alquanto lunga, che sistemino la cosa direttamente in asterisk, bisogna trovare una soluzione temporanea.

Generalmente si consiglia di installare un DNS server che faccia da cache come dnsmasq, ma questo non basta perché dnsmasq non fa il caching delle query SRV _sip. Altri quindi consigliano di impostare
su sip.conf srvlookup=no, il che però non risolve sempre il problema e comunque non è consigliabile.

La soluzione completa è usare si un DNS cache server, ma che sia in grado di fare il caching anche delle query SRV. A tal proposito io ho risolto usando pdnsd.

Ora Asterisk continua a funzionare, anche quando l’ADSL o il DNS cade.

, ,

2 Comments

Pacchetto Debian per target su host

Uso il blog spesso per tenere traccia di cose che continuo a dimenticare, tanto lo devo leggere solo io. Ecco che mi ritrovo a scrivere di cose che non frega a nessuno.

Il mio problema di oggi era: come creo un pacchetto debian per una architettura TARGET non nota, su una macchina HOST di architettura nota (ex. i386)? In una situazione “normale” dh_gencontrol o dh_buildpackage si rifiutano di completare il loro lavoro, se nel campo Architecture: del file control non c’è l’architettura HOST (a meno che non sia specificato all).

Nel mio caso volevo creare su una macchina i386, un pacchetto per un altra architettura, tra l’altro non presente in Debian: non i386, amd64, sparc, arm, etc.; chiamiamola ‘xyz’.

La cross-compilazione è facile (sapendo come la si fa) e questa infatti andava a buon fine. Non riuscivo però a ottenere la pacchettizzazione per l’architettura xyz. La soluzione qual è?

   DEB_HOST_ARCH=xyz fakeroot debian/rules binary

In pratica la variabile DEB_HOST_ARCH, rende tutto il processo trasparente e alla fine mi crea il mio bel pacchetto_xyz.deb, anziché il consueto pacchetto_i386.deb.

Se non avete capito niente, pazienza, tanto questo è un reminder solo per me.

,

No Comments

ipkg, uClinux, circular dependencies

Per una piattaforma embedded su cui sto lavorando, sto cercando di far funzionare ipkg. Ipkg è un gestore di pacchetti per sistemi linux embedded molto simile a dpkg, tanto che è in grado di installare normali pacchetti debian e fornisce anche funzionalità simili a apt-get. Per intenderci è possibile costruire repository di pacchetti ipkg, così come si farebbe con i deb, e utilizzare ipkg per installarli da rete, risolvendo le dipendenze:

ipkg update
ipkg install pacchetto

Farlo funzionare su uClinux non era facile e ci sono riuscito solo grazie alla patch per busybox.

Grazie a questa patch, ipkg diventa un comando fornito da busybox. Questa versione, nel mio caso, funziona benissimo, tranne il fatto che non è in grado di gestire le dipendenze circolari. Cioè se ho un pacchetto A, che dipende da B, che dipende da A, ipkg falliva l’installazione, perché tentava di installare A, poi B, poi di nuovo A ma non trovava più i file di A che nel frattempo erano stati rimossi.

Personalmente ho risolto patchando la funzione ipkg_install_pkg quando durante l’installazione del pacchetto vengono verificate e installate le dipendenze, se il pacchetto stesso risulta già in stato UNPACKED all’uscita della funzione, significa che non devo installarlo più, visto che l’ha già fatto un pacchetto precedente.

if (conf->nodeps == 0) {
        err = satisfy_dependencies_for(conf, pkg);
        ipkg_message(conf, IPKG_DEBUG,
                            "  ipkg_install_pkg: calling satisfy_dependencies_for for %s, err: %i.\n",
                            pkg->name, err);
        /* paci: this is necessary to resolve circular dependencies */
        if (pkg->state_status == SS_UNPACKED) {
                ipkg_message(conf, IPKG_DEBUG2,
                               "  ipkg_install_pkg: pkg is already unpacked!!!\n");
                return 0;
        }
        if (err) { return err; }
}

,

No Comments

MontaVista riceve nuovi finanziamenti.

Montavista è una vecchia conoscenza del mercato Embedded Linux. Nata nel 1999, si è imposta subito come leader di mercato; oggi è leggermente in difficoltà, messa in penombra da giganti come Wind River.

Ha però annunciato di aver appena ricevuto un finanziamento da 21 milioni di dollari, in particolare dalla venture capital di Siemens.

Già in passato MontaVista aveva ricevuto dei round di finanziamenti, ma più piccoli e più distanti nel tempo; non sembra quindi prossima una sua quotazione in borsa. Certo è che il mercato embedded Linux è ormai stimato valere miliardi di dollari.

No Comments