Einfahrt verboten

wall < "Fatal Error Unable to create lock file: Bad file descriptor (9)"

Broadcast message from spillerm@unixe.de (pts/1) (Fr Okt 09 11:49:00 2015):
4
Diesen Beitrag schrieb ich vor 3 Jahren. Behalte das beim Lesen bitte im Hinterkopf.

Und plötzlich liefen die PHP-Seiten auf einem Webserver nicht mehr — nur PHP, wohlgemerkt, HTML ging nach wie vor…

Versuchte ich, eine Webseite aufzurufen, die durch den PHP-Parser gejagt werden sollte, so erschien im Logfile des apache2 lediglich die folgende Meldung:

Thu Oct  1 11:22:05 2015 (8281): Fatal Error Unable to create lock file: Bad file descriptor (9)
[Thu Oct 01 11:22:05.072527 2015] [fcgid:warn] [pid 8231] (104)Connection reset by peer: [client 1.2.3.4:2596] mod_fcgid: error reading data from FastCGI server
[Thu Oct 01 11:22:05.072578 2015] [core:error] [pid 8231] [client 1.2.3.4:2596] End of script output before headers: index.php

Doch welches lock file eigentlich? Ich probierte viel herum, doch auch den apache2 im LogDebug brachte mich nicht weiter; ich fummelte an den DEBUG-Einstellungen von PHP5 herum, doch auch das machte mich nicht klüger. Und die Suche im Internet ergab: ja, das Problem hatten schon so einige — ein Lösungsansatz wurde jedoch nicht verraten. Hm.
Da auf der Maschine FastCGI und suexec im Einsatz sind kam ich auf die Idee, /var/log/apache2/suexec.log näher zu betrachten — doch auch hier konnte ich keine Auffälligkeiten feststellen: genau der konfigurierte User und…

[2015-10-01 11:29:26]: uid: (5003/ispconfig) gid: (5004/ispconfig) cmd: .php-fcgi-starter

das brachte mich auf eine Idee, und ich rief das php-cgi-Binary als root in der Konsole auf.

$ /usr/bin/php-cgi -v
PHP 5.5.9-1ubuntu4.13 (cgi-fcgi) (built: Sep 29 2015 15:27:16)
...

Das entsprach dem Output, den ich erwartet hatte; und erneut dieser Aufruf — jedoch als User ispconfig, der auch die Webseite bedienen soll!

$ sudo -u ispconfig /usr/bin/php-cgi -v
Thu Oct  1 11:27:14 2015 (9356): Fatal Error Unable to create lock file: Bad file descriptor (9)

Offenbar ist es also genau dieser User, der Probleme mit dem Aufruf hat, da bin ich doch noch einen Schritt weiter. Ich weiss zwar noch immer nicht, um welches lock file es eigentlich geht, aber nun habe ich eine Richtung und kann mit strace arbeiten: ich schreibe den Output in die Datei /tmp/strace_out und suche darin dann nach lock:

strace -f -o /tmp/strace_out sudo -u ispconfig /usr/bin/php-cgi -v
Thu Oct  1 11:27:14 2015 (9356): Fatal Error Unable to create lock file: Bad file descriptor (9)
9356  gettimeofday({1443691634, 15689}, NULL) = 0
9356  open("/tmp/.ZendSem.d21fle", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
9356  fchmod(-1, 0666)                  = -1 EBADF (Bad file descriptor)
9356  stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0
9356  write(2, "Thu Oct  1 11:27:14 2015 (9356):"..., 33) = 33
9356  write(2, "Fatal Error ", 12)      = 12
9356  write(2, "Unable to create lock file: Bad "..., 51) = 51

In /tmp soll also das lock file .ZendSem.d21fle gesetzt werden — und das schlägt fehl! Aber… wieso?!

$ ls -lad /tmp
drwxr-xr-x 4 root root 4096 Oct  1 11:27 /tmp/

Uff, okay — wenn nur root und sonst niemand nach /tmp schreiben darf ist das ja auch kein Wunder! Es genügt also in diesem Fall, die Rechte auf /tmp gerade zu biegen — und dann laufen auch die Webseiten wieder. Was jedoch die Rechte auf /tmp überhaupt verändert hatte — das konnte ich schlussendlich nicht herausfinden…

$ chmod 1777 /tmp/
$ ls -lad /tmp/
drwxrwxrwt 4 root root 4096 Oct  1 11:28 /tmp/
$ sudo -u ispconfig /usr/bin/php-cgi -v
PHP 5.5.9-1ubuntu4.13 (cgi-fcgi) (built: Sep 29 2015 15:27:16)
...
4
  1. I was stuck on this for 2 days until I found your website. Thanks for your post, and also thanks to Google Translate!

  2. Besten Dank!
    nach stunden des probierens wieso php nach dem read-only machen des raspberrypi raspian jessie lite lieferte mir diesen Beitrag den nötigen hint.
    /tmp ist als tmpfs eingebunden, aber die rechte waren immer 755, egal was in /etc/fstab stand (mode=1777). als hässlichen hack wird in rc.local
    chmod 777 /tmp
    service lighttpd restart
    gemacht, et voilà, es funzt!

Keine weitere Reaktionen mehr möglich.