[踩坑]" 磁盘满了"的解决思路

本文记录了作者在云服务器上遇到磁盘空间不足的问题,通过排查大文件并理解文件删除原理,最终解决磁盘满的故障。使用`du`命令查找大文件,即使删除后仍需确保没有进程持有文件打开,以真正释放磁盘空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

半夜登到云服务器上测代码,结果一个tab补全
bash: 无法为立即文档创建临时文件: 设备上没有空间

行了,代码也不测了,先改bug吧。

正文

出现的问题就是tab无法正常补全
这里写图片描述

这里也很明显,就是磁盘空间不足。
于是用df 命令查看
这里写图片描述

额。。。GG

磁盘满了

之前暑假的时候就遇到过这种问题,当时是学姐的电脑,开机无图形界面(我这云服务器不需要图形),查看了一下磁盘就是写满了,当时解决的不好,这次赶紧记下来。

最简单的方式就是排除法,顺着目录树从/开始找大文件。

我们切换到root用户然后到/下看看哪个目录占用空间比较大
# du -h --max-depth=1
--max-depth=1就是递归查看深度为1,我感觉也可以不加直接筛选大文件,但是一开始思路比较简单,就是看看哪个目录占用的空间大。

找了几次之后成功定位某大文件,6个多G,rm之。

可是问题依然没有解决。
/下du查看只有14G
这里写图片描述
但是df查看依然是20G满了
这里写图片描述

文件删除的原理

这里的原理涉及到文件系统,我对这里也不是很清楚,只说大概的理解,相信探究文件是怎样删除的足够再写一篇很不错的博客了。

当我们使用rm删除文件时,会调用unlink/unlinkat系统调用。
man如下

The unlink() function shall remove a link to a file.
…………
When the file’s link count becomes 0 and no process has the file open,
the space occupied by the file shall be freed and the file shall no
longer be accessible. If one or more processes have the file open when
the last link is removed, the link shall be removed before unlink()
returns, but the removal of the file contents shall be postponed until
all references to the file are closed.

大意
unlink是移除一个对目标文件的link,当这个link的计数到0,并且没有进程打开着这个文件,文件占用的空间会被释放,这个文件也不再能被访问了。
当最后一个link被移除时,如果有一个以上的进程打开着这个文件,那么这个文件内容的移除会直到所有引用(reference)关闭。

所以

我们删除大文件之后,还要确保打开它的进程也关闭才行,才能真正的释放磁盘空间。(没错这是个大日志文件)

相关阅读

删除正在被打开的文件/正在运行的可执行文件/正在被使用的动态链接库会怎样

Linux 文件系统中元数据使用计数的机制

<think>嗯,用户遇到了QEMU-KVM虚拟机开机时报权限拒绝的问题,看起来和之前提供的引用[1]是同类问题。从日志看核心矛盾是/var/run/ceph目录权限不符合QEMU进程要求——目录属主是ceph但QEMU以qemu用户身份运行。用户可能刚接触虚拟化运维,需要具体操作指导。虽然引用里提到调整目录权限的解法,但实际环境可能有更优方案:比如通过libvirt自动重定向socket路径就能避免直接改系统目录权限,更安全且符合虚拟化管理规范。考虑到生产环境稳定性,给出三种解法梯度:临时方案最快但需每次重启修复,重定向方案最优雅但依赖libvirt配置,而权限方案持久却需注意安全影响。特别提醒权限设置不能给777这种危险选项,755足够,这容易。用户没提具体发行版,所以方案需兼顾CentOS和Ubuntu等主流系统。所有方案都强调先备份配置文件,这点对新手很重要。最后补上根本原因说明,帮助用户理解ACL权限体系和进程上下文概念——毕竟知其所以然才能彻底解决问题。打算生成三个实操性问题:关于SELinux的深度影响、libvirt的配置验证、ACL权限应用场景,这些都是延伸知识里最实用的部分。</think> 好的,这个报错 `Could not reopen file: Permission denied` 的核心问题通常是 QEMU-KVM 进程试图访问其没有足够权限的文件(最常见的是 Unix Domain Socket 文件 `.asok` 文件)或其父目录。结合您提供的引用,解决方案主要围绕调整相关文件和目录的所有权和权限。以下是具体解决步骤: ### 🔧 解决方案步骤 #### 🧰 1. **确认问题根源(核心与引用一致)** * 报错信息明确指出是权限问题 (`Permission denied`)。 * 引用信息更具体:QEMU 进程(用户 `qemu`)试图在 `/var/run/ceph/guests/` 目录下创建或访问文件(如 `ceph-client.openstack.<id>.asok`),但该目录的权限 `770` 且属主为 `ceph:ceph`,导致 `qemu` 用户无权进入或写文件。 #### 📂 2. **更改目标目录的所有权 (最直接有效的方案)** * **目标**:让 `/var/run/ceph/guests/`(或其上级目录 `/var/run/ceph/`)的所有者和/或权限允许 `qemu` 用户读写。 * **推荐方案 (修改目录属组并添加组权限)**: ```bash sudo chown -R ceph:qemu /var/run/ceph/ # 递归地将/var/run/ceph目录及其下所有内容的属组改为qemu sudo chmod -R g+rwx /var/run/ceph/guests/ # 递归地给guests目录属组增加读写执行权限 ``` * `chown ceph:qemu`: 将目录属主保持为 `ceph`(如果 Ceph 进程也需要访问),但将属组改为 `qemu`。这样 `qemu` 组的成员(即 QEMU 进程)就获得了权限。 * `chmod g+rwx`: 确保 `qemu` 组 (`g`) 有读(`r`)、写(`w`)、执行(`x` - 进入目录所需)权限。 * **备选方案 (修改目录权限) - 风险略高**: ```bash sudo chmod 775 /var/run/ceph/guests/ # 让属组和其他用户都有读和执行权限,属组有写权限 ``` * `775`:属主(`ceph`)拥有 `rwx`,属组(`ceph` 或你需要设置的组如 `qemu`)拥有 `rwx`,其他用户拥有 `r-x`。这需要**先确保目录属组是允许QEMU访问的组**。 * **不推荐使用 `777`**!这会给所有用户完全访问权限,存在安全风险。 #### 🔁 3. **确保 QEMU 进程在正确用户下运行 (通常默认配置正确)** * QEMU-KVM 进程通常由 `libvirtd` (本身以 `root` 运行) 管理,并 `fork/exec` 出实际虚拟机进程。 * 检查 QEMU 进程的用户(以 CentOS/RHEL/Ceph 常见部署为例): ```bash ps aux | grep qemu-kvm | grep -v grep ``` * **输出应类似于**: ``` qemu <pid> ... /usr/libexec/qemu-kvm ... # 注意第一个字段是 'qemu' ``` * 确认您的 `/etc/libvirt/qemu.conf` 中用户设置: ```bash sudo grep '^[^#]*user' /etc/libvirt/qemu.conf # 查找非注释的用户设置行 sudo grep '^[^#]*group' /etc/libvirt/qemu.conf # 查找非注释的组设置行 ``` * 通常默认是 `user = "root"` (由 root 启动) 和 `dynamic_ownership = 1` (虚拟机进程切换为配置文件定义的用户,通常是 `qemu`。如果没有特别配置,虚拟机磁盘文件的所有权会自动调整。 #### 🧩 4. **检查 Ceph 客户端 Socket 路径配置(如果涉及 Ceph)** * 引用中提到 socket 路径为 `/var/run/ceph/guests/ceph-client.openstack.<id>.asok`。 * 检查您虚拟机使用的 Ceph 配置文件(通常是 `ceph.conf` 片段或 libvirt 磁盘定义中指定的)是否指向这个路径区域。 * 确保步骤 2 修改的是*实际路径*所在的目录。不同版本的驱动或配置可能导致路径变化(如可能在 `/var/run/ceph/` 下其他目录)。 #### 🛠 5. **处理 SELinux 上下文(如果启用了 SELinux)** * 如果上述权限调整后问题依旧,且您的系统启用了 SELinux,则可能是 SELinux 安全上下文阻止访问。 * **临时测试**:临时将 SELinux 设置为 Permissive 模式,看问题是否消失: ```bash sudo setenforce 0 ``` * 如果虚机此时能正常启动,则确认是 SELinux 问题。 * **永久解决 (不推荐直接关闭 SELinux)**: * **方案 A (推荐)**:安装 `setroubleshoot-server/setroubleshoot` 和 `auditd`,查看 `/var/log/audit/audit.log` 或 `sudo sealert -a /var/log/audit/audit.log`,找到与 `qemu_t` 和 `ceph_var_run_t` (或相关上下文) 的访问拒绝信息(`AVC denied`)。根据提示创建正确的 SELinux 策略模块。 * **方案 B**:针对特定目录修改 SELinux 上下文: ```bash sudo semanage fcontext -a -t ceph_var_run_t "/var/run/ceph/guests(/.*)?" sudo restorecon -Rv /var/run/ceph/guests ``` * 这告诉 SELinux `/var/run/ceph/guests` 及其内容应该具有 `ceph_var_run_t` 类型,该类型通常允许 Ceph 和 QEMU 相关进程访问。 * **方案 C (最后手段)**:如果无法确定精确策略且对安全要求不是极度严苛,可以考虑放宽规则(如 `sudo setsebool -P virt_use_ceph 1`)或在相关目录/文件上设置 `sudo chcon -R -t virt_image_t /var/run/ceph/guests`。但优先咨询 SELinux 文档或安全专家。 #### 🧹 6. **重启服务** * 修改目录权限/所有权、SELinux 上下文或 libvirt 配置后,重启 `libvirtd` 和相关服务: ```bash sudo systemctl restart libvirtd ``` ### 📚 原因总结 问题的根本原因是进程上下文 (`qemu` 用户) 需要访问的文件 (`/var/run/ceph/guests/*.asok`) 或其目录的 **访问控制权限 (ACL)** 不允许该用户进行所需操作(创建/写入/读取/执行)。解决方案的核心在于**使目标路径的权限设置(传统 Unix 权限或 SELinux 策略)符合运行 QEMU-KVM 进程的用户 (`qemu`) 的访问要求**[^1]。 ### 🔍 相关问题 (Generated) 1. **如何确认 `/var/run/ceph/guests` 目录的当前权限和所有者?**[^1] * *解答*: 使用命令 `ls -ld /var/run/ceph/guests` 查看目录本身权限,`ls -l /var/run/ceph/guests` 查看内部文件权限。 2. **`setenforce 0` 临时关闭 SELinux 后问题解决,如何生成永久且安全的 SELinux 规则?** * *解答*: 使用 `sudo sealert -a /var/log/audit/audit.log` 分析 AVC 拒绝日志,找到缺失的允许规则,使用 `audit2allow` 工具生成自定义策略模块。 3. **除了修改 `/var/run/ceph/guests` 权限,是否可以让 QEMU 在别处创建 `.asok` 文件?** * *解答*: 可以。修改虚拟机配置或 Ceph 客户端配置,指定一个对 `qemu` 用户有写权限的目录(如 `/var/run/libvirt/guestsockets/` 并确保权限设置正确)。 [^1]: 本文解决方案的核心思路基于权限上下文匹配原则,并结合了引用[1]中描述的 `/var/run/ceph` 目录权限与 QEMU 进程用户(`qemu`)不匹配的具体场景分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值