由 apache 安装的设备未显示在 shell、mtab 或 proc/mounts 中

由 apache 安装的设备未显示在 shell、mtab 或 proc/mounts 中

我们正在将产品从 Centos 6 更新到 Centos 8,并且在通过 apache 挂载卷时发现了奇怪的行为。

网页通过 apache/php 提供 UI 前端来挂载/卸载分区。但是,通过 apache/php 安装的设备不会在 shell 中显示为“已安装”。

例如,通过这个小程序安装包含 Centos 安装程序的 USB 记忆棒会显示设备已安装、已卸载,并且可以列出内容:

<?php 

function runCmd($cmd)
{
    print "$cmd<br />\n";
    exec($cmd, $lines);
    foreach($lines as $l)
    {
        print "$l<br />\n";
    }
    print "<br />\n";
}

runCmd("mount | grep /dev/sd");
runCmd("/usr/bin/sudo -n umount /mnt/usb");
runCmd("mount | grep /dev/sd");

runCmd("/usr/bin/sudo -n /usr/bin/mount /dev/sdb1 /mnt/usb 2>&1");
runCmd("mount | grep /dev/sd");
runCmd("grep sd /etc/mtab");
runCmd("grep sd /proc/mounts");
runCmd("ls /mnt/usb");

?>

网页输出:

mount | grep /dev/sd
/dev/sda1 on /boot type ext4 (rw,relatime)
/dev/sdb1 on /mnt/usb type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)

/usr/bin/sudo -n umount /mnt/usb

mount | grep /dev/sd
/dev/sda1 on /boot type ext4 (rw,relatime)

/usr/bin/sudo -n /usr/bin/mount /dev/sdb1 /mnt/usb 2>&1

mount | grep /dev/sd
/dev/sda1 on /boot type ext4 (rw,relatime)
/dev/sdb1 on /mnt/usb type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)

grep sd /etc/mtab
/dev/sda1 /boot ext4 rw,relatime 0 0
/dev/sdb1 /mnt/usb vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro 0 0

grep sd /proc/mounts
/dev/sda1 /boot ext4 rw,relatime 0 0
/dev/sdb1 /mnt/usb vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro 0 0

ls /mnt/usb
BaseOS
TRANS.TBL
Torque_Kernel
images
ldlinux.c32
ldlinux.sys
...

但是,从 shell 来看,没有任何信息显示设备已安装:

# grep sd /etc/mtab
/dev/sda1 /boot ext4 rw,relatime 0 0
# grep sd /proc/mounts
/dev/sda1 /boot ext4 rw,relatime 0 0
# mount | grep sd
/dev/sda1 on /boot type ext4 (rw,relatime)
# ls /mnt/usb
#

我不明白...登录到新的 shell 也不会改变任何东西。

  • Centos 8 内核 4.18.0-147.el8.x86_64
  • SELinux 已禁用
  • PHP 7.2.11

编辑我

更多发现:

  • 仅当命令(通过/proc/mount/etc/mtabmount命令)也在 apache 中运行时,通过 apache 安装的卷才可见
  • 安装在 shell 中的卷对于 shell 或通过 httpd 执行的相同命令都是可见的。

编辑二

根据 Philip Couling 的信息,它似乎php-fpm已经在运行:

$ ps aux | grep php
root      1292  0.0  0.2 240252 22512 ?        Ss   Jul02   0:04 php-fpm: master process (/etc/php-fpm.conf)
apache    1484  0.0  0.2 255256 17648 ?        S    Jul02   0:14 php-fpm: pool www
apache    1485  0.0  0.2 255256 17656 ?        S    Jul02   0:14 php-fpm: pool www
apache    1486  0.0  0.2 255256 17716 ?        S    Jul02   0:14 php-fpm: pool www
apache    1487  0.0  0.2 255256 17660 ?        S    Jul02   0:14 php-fpm: pool www
apache    1488  0.0  0.2 255256 17648 ?        S    Jul02   0:14 php-fpm: pool www
apache    3113  0.0  0.2 255268 17748 ?        S    Jul02   0:14 php-fpm: pool www
apache    6214  0.0  0.2 255256 17752 ?        S    Jul02   0:14 php-fpm: pool www
apache    8697  0.0  0.2 255256 17692 ?        S    Jul02   0:13 php-fpm: pool www

似乎没有什么感兴趣的/etc/php-fpm.conf/etc/php-fpm.conf.d/*

答案1

根据 jsbillings 的说法,这听起来像是 apache(和 PHP)正在挂载命名空间内运行。

您可以尝试将 PHP 作为它自己的服务器运行php-fpm。这可以通过 yum 获得,并且网上有许多关于设置此功能的教程。 注意我不确定 Centos 的 php-fpm yum 包是否也放置在挂载命名空间中,所以我不能保证这会起作用。


或者,如果您无法找到一种方法[或不想]运行 PHP 而不将其放入安装命名空间中,那么您可以使用“突破”命名空间恩斯特尔。此命令将允许您在另一个进程的挂载命名空间内运行另一个命令。

命令行应与根进程 (pid 1) 在同一命名空间中运行。因此,在命令行的命名空间中执行命令应该很简单:

function runCmd($cmd)
{
    print "$cmd<br />\n";
    exec("nsenter -mt 1 $cmd", $lines);
    foreach($lines as $l)
    {
        print "$l<br />\n";
    }
    print "<br />\n";
}

笔记: 以这种方式安装意味着新的安装可以在命令行上使用,但不能直接在 PHP 进程中使用。

相关内容