2015-11-12 2 views
-1

Я запускаю Bash-скрипты из PHP (5.4) с правами root через двоичную оболочку (см. [Execute root commands via PHP)), которая отлично работает, за исключением следующий пример. Кроме того, я использую zfs-on-linux на CentOS7.Различные ответы от одного и того же сценария в зависимости от вызывающего (php exec() vs. console)

Я подготовил 2 простых примеров Bash-скрипты:

test_zfsadd:

#!/bin/bash 

#ARGS=1 

err="$(zfs create $1 2>&1 > /dev/null)" 

if [ $? -ne 0 ] 
then 
     echo $err 
     exit 1 
fi 

echo "OK" 
exit 0 

test_zfspart:

#!/bin/bash 

#ARGS=1 

msg="$(zfs get mounted $1 -H | awk '{print $3}')" 

echo $msg 
exit 0 

Когда я вызвать в соответствии двоичные файлы из PHP с е. г.

<?php 

$partition = 'raid1/testpart'; 

$ret = shell_exec("/path/test_zfsadd_bin $partition"); 
echo "<p>Return value: $ret</p>\n"; 

$ret = shell_exec("/path/test_zfspart_bin $partition"); 
echo "<p>Is mounted: $ret</p>\n"; 

выход:

Return value: OK 
Is mounted: yes 

Это выглядит хорошо, но когда я называю 'test_zfspart_bin RAID1/testpart' непосредственно из консоли, я получаю правильный результат, который

no 

(означает, что раздел НЕ установлен, проверен в/proc/mounts). Поэтому я получаю 2 разных ответа от одного и того же сценария, которые каким-то образом зависят от контекста. Сначала я подумал, что это имеет какое-то отношение к SUID-Бит, но вызов скрипта на консоли с непривилегированным пользователем отлично работает. Если я пытаюсь (как корень)

zfs mount raid1/testpart 

в консоли я получаю

filesystem 'raid1/testpart' is already mounted 
cannot mount 'raid1/testpart': mountpoint or dataset is busy 

который является фантастическим. Я также не могу уничтожить «раздел» с консоли, это работает только с PHP. С другой стороны, если я создаю раздел как root напрямую из bash и пытаюсь удалить его через PHP, он тоже не работает. Похоже, что разделы как-то отделены друг от друга контекстом. Все синхронизируется снова, если я

systemctl restart httpd 

Я думаю, апач или PHP держит систему ZfS занят, в некоторой степени, но я не имею абсолютно никакого понятия, почему и как. Любое объяснение или некоторое обходное решение очень ценятся.

ответ

0

Я сам это выяснил. Проблема была не в самом процессе apache, а в том, как он запускается systemd. Существует опция «PrivateTmp», которая по умолчанию установлена ​​в «true» в файле службы httpd (по крайней мере, в CentOS7). Страница руководства говорит

PrivateTmp = Принимает логический аргумент. Если true задает новую файловую систему пространство имен для выполняемых процессов и монтирует закрытый внутри нее каталог private/tmp , который не используется процессами за пределами пространства имен. Это полезно для обеспечения доступа к временным файлам процесса, но делает невозможным совместное использование процессов через/tmp . По умолчанию false.

Это объясняет все, что я думаю. Созданный zfs-раздел монтируется в этой «виртуальной» файловой системе и поэтому невидим для остальной части системы, что в этом случае нежелательно.Процесс apache не может монтировать или отключать файловые системы за пределами своего пространства имен. После отключения опции все работало, как ожидалось.