我通过二进制包装器以 root 权限从 PHP (5.4) 运行 Bash-Scripts(请参阅 [通过 PHP 执行 root 命令),除了以下示例外,它工作得非常好。另外,我在 CentOS7 上使用 zfs-on-linux。
我准备了 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-Bit 有关,但是在控制台中使用非特权用户调用脚本可以正常工作。如果我尝试(以 root 身份)
zfs mount raid1/testpart
在控制台中我得到
filesystem 'raid1/testpart' is already mounted
cannot mount 'raid1/testpart': mountpoint or dataset is busy
这很奇怪。我也无法从控制台销毁“分区”,这仅适用于 PHP。另一方面,如果我直接从 bash 以 root 身份创建一个分区并尝试通过 PHP 删除它,它也不起作用。看起来分区以某种方式通过上下文彼此分离。如果我这样做,一切都会再次同步
systemctl restart httpd
我认为 apache 或 PHP 在某种程度上使 zfs 系统保持忙碌,但我完全不知道为什么以及如何。非常感谢任何解释或一些解决方法。