为什么“pgrep -O 600”在 LXC 中失败?程序错误?

为什么“pgrep -O 600”在 LXC 中失败?程序错误?

非特权 LXC (proxmox) 中的 Debian 12.2。现在已经是当地时间上午 11 点 45 分左右了。早上 5:00,cron 启动了一个脚本:

USER      PID    %CPU %MEM  VSZ   RSS TTY      STAT START   TIME COMMAND
jan       26633  0.0  0.0   8500  2056 ?       S    05:00   0:00 /usr/sbin/CRON -f

我正在使用 pgrep pgrep -f CRON -O 600,并且我希望 pgrep 返回 PID 26633,因为该进程的历史远远超过 600 秒。但 pgrep 什么也没返回。如果我省略-O,它会正确返回 PID。

在主机上(即 LXC 之外)执行相同操作,它可以正常工作。
由于 pgrep 使用 procps,所以我查看了那里。
ps -o etime -p $pid在 LXC 中:(441077225-02:04:48 错误,因为从 5:00 开始,~6:45 过去了)
ps -o etime -p $pid在主机上:(06:43:29 正确)

这是 procps 中的错误还是与 LXC 有关?

答案1

LXC 安装一个假的/proc/uptime来模拟容器的正常运行时间而不是主机的正常运行时间,因为该属性没有命名空间。在(根)LXC 容器上:

# findmnt /proc/uptime
TARGET       SOURCE              FSTYPE     OPTIONS
/proc/uptime lxcfs[/proc/uptime] fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other

但是,并没有为每个进程的stat伪文件做出这样的规定/proc/PID/stat

因此,当比较时间时,电流和磁场pgrep之间存在差异,如下所述/proc/uptimestarttime/proc/PID/statproc(5)道具来源:

    PIDS_TIME_ELAPSED,      //     real     *  derived from stat: (/proc/uptime - start_time) / hertz

由于容器/proc/uptime是被LXC伪造的(我猜是通过使用主机的/proc/uptime减去LXC容器的pid 1启动时间),最终结果得到容器的启动时间减去,导致最初为负值(并且在一段时间内,但如果/当它后来变成正数时仍然是错误的),这是意想不到的,因为系统正常运行时间应该大于目标的进程 start_time (可能通过一个因子进行调整)$(getconf CLK_TCK))。过程工具无法正确处理这个问题。

我不知道解决方法:如果/proc/uptime恢复到其主机值,则pgrep -Ops -o etime -p将计算正确的值,但任何使用系统正常运行时间的工具现在都将获取主机的正常运行时间,而不是容器的(伪造的)正常运行时间。

相关内容