在 cron 下运行时 mount 和 umount 的行为不同

Jos*_*nis 5 mount cron fuse umount centos-6

在 AWS 中运行 CentOS 6,我所看到的让我感到困惑。

有一个s3fs挂载/etc/fstab有时会失去读取和写入的能力。我有一个运行了好几个月的 cron 工作,它会简单地每分钟测试安装是否良好,如果它失去了连接,它只会umountmount共享。在无负载下,安装座往往会更频繁地消失,然后在实际负载下,所以这是一个很好的解决方案。

出于某种原因,这个停止工作,而现在的机器上来无法从共享的读/写,因为机器设置之后做引导时的第一件事就是umountmount共享。

现在我在尝试阅读时遇到的错误是:

cp: cannot open `/app/canary.txt' for reading: Input/output error
Run Code Online (Sandbox Code Playgroud)

/var/log/messages我看到这个:

kernel: s3fs[3077]: segfault at e66000 ip 00007f833663d94e sp 00007ffc849c5b18
error 4 in libc-2.12.so[7f83365b4000+18a000]
Run Code Online (Sandbox Code Playgroud)

现在,当我以 root 身份在控制台中运行完全相同的脚本时,它可以完美运行。卸载和安装驱动器并使其处于工作状态。

我的第一个猜测是环境中的某些东西导致了差异,所以我source /root/.bash_profile在我的脚本中添加了一个,但无济于事。

/etc/fstab 中的行是一个怪物,但经过多次微调尝试后,我们发现这是最有效的:

ourbucket /app fuse.s3fs _netdev,allow_other,endpoint=us-west-2,url=https://s3-us-west-2.amazonaws.com,use_path_request_style,use_sse,gid=1001,umask=0007,use_cache=/srv/s3fs,retries=20,parallel_count=30,connect_timeout=30,readwrite_timeout=60,stat_cache_expire=86400,max_stat_cache_size=100000 0 0
Run Code Online (Sandbox Code Playgroud)

这是 cronfile 的样子:

* * * * * root /usr/bin/sudo /root/check_mount.sh
Run Code Online (Sandbox Code Playgroud)

我在有和没有 sudo 的情况下都尝试过,因为我认为它可能会影响环境。

我已经尝试了该脚本的许多变体,但是这些命令中的大多数都曾在某个时间点使用过。无论umount我做什么类型,都会出现同样的问题。

\cp /app/canary.txt /tmp/canary.txt
retVal=$?
sleep 1
if [ ${retVal} -ne 0 ]; then
    echo "Copy failed, trying to umount"
    umount /app
    echo "umount returned $?"
    sleep 1
    echo "Trying umount -f"
    umount -f /app
    echo "umount -f returned $?"
    sleep 1
    echo "Trying fusermount -u"
    /usr/local/bin/fusermount -u /app
    echo "fusermount returned $?"
    sleep 1
    echo "Trying to mount"
    mount /app
    echo "mount returned $?"
    sleep 1
    echo "Trying copy after mount"
    \cp /app/canary.txt /tmp/canary.txt
fi
Run Code Online (Sandbox Code Playgroud)

这个脚本最初在python,关键部分只是炮击到os.system,但我想从等式中删除它。它给出了同样的问题。

Jos*_*nis 5

这是我的完整解决方案:

首先,我目视审核了audit.log。为了捕捉正确的事情并且只捕捉正确的事情,我过去常常audit2allow创建一个策略和类型强制规则。

grep mount /var/log/audit/audit.log | audit2allow -R -M mounts3fs
Run Code Online (Sandbox Code Playgroud)

我 grep 挂载所以我只得到正确的东西。

这创建了一个mounts3fs.ppmounts3fs.te文件。该mounts3fs.te看起来是这样的:

policy_module(mounts3fs, 1.0)

require {
    type file_t;
    type var_t;
    type mount_t;
    type cert_t;
    class dir { write remove_name add_name };
    class file { create unlink link setattr };
}

#============= mount_t ==============
#!!!! The source type 'mount_t' can write to a 'dir' of the following types:
# user_home_t, etc_runtime_t, var_run_t, mount_var_run_t, mount_tmp_t, user_home_dir_t, etc_t, nfs_t, tmpfs_t, tmp_t, var_t

allow mount_t cert_t:dir { write remove_name add_name };
allow mount_t cert_t:file { create unlink };
allow mount_t file_t:dir { remove_name add_name };
allow mount_t file_t:file { unlink link setattr };
allow mount_t var_t:file link;
Run Code Online (Sandbox Code Playgroud)

要安装该策略,我运行以下命令:

semodule -i mounts3fs.pp
Run Code Online (Sandbox Code Playgroud)

我发现这对于某些操作来说还不够,所以我创建了一个额外的策略,如下所示:

module s3fs 1.0;

require {
    type file_t;
    type mount_t;
    class dir create;
    class file create;
}

#============= mount_t ==============

#!!!! This avc is allowed in the current policy
allow mount_t file_t:dir create;
allow mount_t file_t:file create;
Run Code Online (Sandbox Code Playgroud)

selinux 还是可以直接下地狱的。

  • 一旦我有了它,我会发布一个完整的解决方案。基本上,`selinux` 会阻止对已安装卷的读/写。 (2认同)