I am developer of ko-worker library. I add feature with phar executable as daemons application. And found strange behavior with phar and process forking undex linux. Each time the master process fork`s more then 1 child i got error like that
include(phar:///opt/www/worker.phar/vendor/path/to/file.php):
failed to open stream: phar error: internal corruption of phar
"/opt/www/worker.phar" (crc32 mismatch on file "vendor/path/to/file.php")
in `phar:///opt/www/worker.phar/vendor/composer/ClassLoader.php` line 412
The stub (original stub here) of phar look`s like
#!/usr/bin/env php
<?php
Phar::mapPhar('worker.phar');
require_once 'phar://worker.phar/vendor/autoload.php';
//Execute next going fork code more then one 1 time
...
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
// we are the parent
...
} else {
// we are the child
...
exit(1);
}
__HALT_COMPILER();
I do not use cache_list. This happens only if phar is compressed with GZ or BZ2. Phar files without compression do not reproduce this bug. Is any workarounds around it or may be some information about restriction of compressed phars and forked process?
PHP Phar extension internally opens a Phar file and uses seek/tell/read operations on that descriptor to read the required files from the archive. Because forked processes all use the same descriptor and therefore also share the current file position pointer, then there is a race condition between these operations.
This problem is easily reproducible and happens with or without compression, but compression makes it more likely.
I'm not sure if this is actually a bug, because it is not easy to fix from PHP side and the same kind of problem likely exists for any PHP function, which have an open file descriptor in the background. It's more a problem of the documentation, which does not clearly state, that all the operations on the same Phar file share the same file descriptor in the background, even if it is not obvious from the PHP code.
The fix is to make sure you do not access the Phar before fork() or use some kind of locking mechanism when accessing the same Phar archive from different processes created by fork().
Seems like a PHP issue, report as a bug at https://bugs.php.net/ with steps to reproduce.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With