-1

I run Bash-Scripts from PHP (5.4) with root permissions through a binary wrapper (see [Execute root commands via PHP), which works perfectly fine except for the following example. Additionally, I am using zfs-on-linux on CentOS7.

I prepared 2 simple example Bash-Scripts:

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

When I call the according binaries from PHP with e. g.

<?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";

the output is:

Return value: OK
Is mounted: yes 

This looks good, but when I call 'test_zfspart_bin raid1/testpart' directly from console, I get the correct result which is

no

(means that the partition is NOT mounted, checked in /proc/mounts). So I get 2 different answers from the same script depending somehow on the context. I first thought it has something to do with the SUID-Bit, but calling the script in console with an unprivileged user works fine. If I try (as root)

zfs mount raid1/testpart

in console I get

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

which is weird. I also can't destroy the 'partition' from console, this works only from PHP. On the other hand, if I create a partition as root directly from bash and try to delete it via PHP, it doesn't work either. Looks like the partitions are somehow separated from each other by context. Everything gets synchronized again if I do

systemctl restart httpd

I think apache or PHP is keeping the zfs system busy to some extend, but I have absolutely no clue why and how. Any explanation or some workaround is much appreciated.

Community
  • 1
  • 1
luks11
  • 1

1 Answers1

0

I figured it out myself in the meantime.. The problem was not the apache process itself, it was how it is started by systemd. There is an option called 'PrivateTmp', which is set to 'true' in the httpd service file by default (at least in CentOS7). The man page says

PrivateTmp= Takes a boolean argument. If true sets up a new file system namespace for the executed processes and mounts a private /tmp directory inside it, that is not shared by processes outside of the namespace. This is useful to secure access to temporary files of the process, but makes sharing between processes via /tmp impossible. Defaults to false.

This explains it all I think. The newly created zfs partition is mounted in this 'virtual' file system and is therefore invisible to the rest of the system, what is not desired in this case. The apache process is not able to mount or unmount file systems outside its namespace. After disabling the option everything worked as expected.

luks11
  • 1