Problema com o apache / mod_php executando o rsync via exec ()

1

Estou tendo um problema com um script PHP executando o rsync em um dos meus servidores, mas apenas quando executado através do apache / mod_php.

Aqui está uma versão reduzida do script:

<?php
 exec("rsync -a /var/www/html/from/ /var/www/html/to");
?>

Muito simples. O objetivo deste comando é copiar uma estrutura de pastas (completa com as permissões apropriadas) para uma nova pasta. Mas o problema é que esse comando rsync trava e não é concluído.

Fazendo um pouco de investigação, notei que o script geraria dois processos de rsync:

> ps aux | grep rsync
apache   20752 56.9  0.0  10400   656 ?     R   11:29  1:37 rsync -a /var/www/html/from/ /var/www/html/to
apache   20753  0.0  0.0  10400   276 ?     S   11:29  0:00 rsync -a /var/www/html/from/ /var/www/html/to
root     22305  0.0  0.0  61212   764 pts/1 S+  11:32  0:00 grep rsync

Percebi que o primeiro processo estava no status "em execução". Então eu fiz um strace sobre isso, mas tudo que eu tenho para a saída foi o seguinte:

> strace -p 20752
<snip>
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
select(1037, [1026 1027 1028 1029], [], NULL, {60, 0}) = 4 (in [1026 1027 1028 1029], left {60, 0})
<snip>

Aqui está o que eu sei até agora:

  1. O script php funciona bem quando executado a partir do cli. Eu habilitei a habilidade para su apache e executar o script > php myscript.php e ele funciona bem. Mas a execução do link cria os dois processos, com um dos primeiros em estado de execução contínua. Isso me leva a acreditar que não é um problema de permissão. Como prova adicional, aqui está a ls -l output:

    > ls -l /var/www | grep html
    drwxr-xr-x 79 apache    apacheftp 4096 Aug 17 12:07 html
    
    > ls -l /var/www/html | grep from
    drwxrwxr-x 2 apache apache 4096 Aug 22 11:27 from
    

    Assim, o apache tem permissão para gravar no diretório e ler a partir do diretório.

  2. A execução do mesmo script em um servidor diferente das mesmas especificações funciona bem. As especificações dos dois servidores são:

    Apache version: Apache/2.2.3
    PHP version: 5.3.3
    rsync version: 2.6.8  protocol version 29
    OS: Red Hat Enterprise Linux Server release 5.6 (Tikanga)
    

O que eu não sei é por que o apache gera dois processos de rsync (ou porque o primeiro rsync gera um segundo), e porque o primeiro processo de rsync parece estar preso em select(1037...)

Alguém pode esclarecer isso?

    
por DTest 22.08.2012 / 18:53

1 resposta

0

Então, depois de modificar meu script para executar strace diretamente através da função exec() da seguinte forma:

/usr/bin/strace -fo /var/www/html/rsynce.log /usr/bin/rsync -a /var/www/html/from/ /var/www/html/to

e examinando a diferença no arquivo gerado pela execução de um navegador e a partir da linha de comando, encontrei esta linha (no log gerado a partir do script de execução do navegador):

select(1034, [1026 1027 1028 1029], [], NULL, {60, 0}) = -1 EBADF (Bad file descriptor)

Isso me fez pesquisar os descritores de arquivos no apache. Na minha configuração, executo muitos hosts virtuais e cada um deles definia três arquivos de log exclusivos. Assim, enquanto um processo do apache estava usando 1143 descritores de arquivos (via lsof -p pid | wc -l ), apenas 124 deles não eram logs.

Consegui remover os arquivos de log exclusivos do host virtual, reiniciei o apache e o script-run-through-the-browser funcionou bem.

    
por 30.08.2012 / 20:00