chdir引起的磁盘目录占用的一种场景

进程占用磁盘的排查方式

工作中遇到了进程X 占用磁盘(或者说目录),引起磁盘无法格式化(可以近似认为目录无法被删除)的问题,之前出现这种情况,多为进程在磁盘(目录)上拥有打开的文件句柄,使用lsof命令可以看到有占用句柄的进程,故而在要进行磁盘格式化前后增加了模块退出机制,去除模块的对磁盘的占用。但本次的问题出现情况不同,对应进程X 从表现上看确实存在对磁盘的占用,使用lsof或者fuser命令都可以查看到占用磁盘路径的进程pid列表中存在对应进程X。但从代码层面看,进程X确实不涉及到对磁盘的占用。

fuser - identify processes using files or sockets
        -m NAME, --mount NAME
            指定文件或者挂载的设备
Usage:
    fuser -m "/path/"
 
 lsof  - 列出当前系统打开文件
 
 Usage:
    lsof "/path"
 

父子进程关联

排查过程中发现,杀死进程X 单独启动,发现对磁盘目录的占用就去除了。
因之前遇到过由于未设置 FD_CLOEXEC 标记位,而出现了代码中只起了一个监听套接字,但在netstat中出现了有两个监听相同端口的套接字的奇怪现象,最终发现是由于在创建套接字时,没有 cloexec,而导致套接字被子进程所继承导致。故而怀疑该占用是不是也是由于父进程的操作而引起的,因为对应进程X 恰好是由进程A 通过system调用启动的。

system实际的执行流程就是调用,fork->exec->wait。而fork的过程中,子进程会继承父进程的如下资源

  • 用户号UIDs和用户组号GIDs
  • 环境 Envronment
  • 堆栈
  • 共享内存
  • 打开的文件描述符
  • 执行时关闭标志
  • 信号控制设定
  • 进程组号
  • 当前工作目录
  • 根目录
  • 文件方式创建屏蔽字
  • 资源限制
  • 控制终端

其中可能引起占用的有两个点,一个为打开的文件描述符,一个为当前工作目录。

  1. 如果子进程包含打开的文件描述符,则lsof会显示打开的文件句柄的路径。但从代码中看进程X的实现代码确实不存在打开句柄的情况
  2. 故而更有可能的是子进程对父进程工作目录的继承,而引起的对路径的占用。

工作目录

关于工作目录,我们最常用的就是cd命令,通过cd命令,修改我们当前所在的shell的工作目录。调整了我们调用其他可执行文件的相对位置的起点。针对unix,可以使用 getcwd来获取当前的工作目录,也可以通过chdir来切换当前工作目录。

getcwd  - copies an absolute pathname of the current working directory to the array pointed to by buf, which is of length size

Usage:
    char szBuf[1024] = {0};
    getcwd(szBuf, sizeof(szBuf));
    
chdir  -  changes the current working directory of the calling process to the directory specified in path

    int chdir(const char *path);

通过排查找到父进程A 确实新引入了chdir,将工作目录切换到了磁盘路径,并在此后不再切换工作目录。
通过在模块结束时,重新将chdir工作目录切换到默认的工作目录,重新启动进程A,可以发现通过system调用的进程X不再占用 磁盘路径。磁盘可以正常被格式化。

这里的默认工作目录是什么呢?其实也就是进程A的父进程的工作目录,进程A是在开机启动过程中启动的,故而继承了系统shell的工作目录,这个工作目录是在/etc/bashrc中配置的。

这里要注意另外一点,父进程中切换工作目录是会影响后面system调用启动的子进程,但是子进程中调用chdir,或者脚本中调用cd,是不会影响到父进程的工作目录的。

参考

Linux中父子进程的继承关系
https://blog.csdn.net/feiyagogogo/article/details/79671398

popen/system与fork函数
https://blog.csdn.net/Cyrus_wen/article/details/80018721

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值