磁盘挂载问题

title

磁盘挂载问题会影响系统启动、数据访问和存储扩展,是Linux运维中需要重点关注的问题。

🚨 问题现象

常见错误信息

# 挂载失败
mount: /dev/sdb1: can't find in /etc/fstab
mount: /dev/sdb1: mount point does not exist
mount: wrong fs type, bad option, bad superblock

# 设备忙
umount: /mnt/data: target is busy
umount: /mnt/data: device is busy

# 文件系统错误
mount: you must specify the filesystem type
mount: unknown filesystem type 'ntfs'

# 权限错误
mount: only root can mount /dev/sdb1 on /mnt/data
mount: permission denied

# 启动错误
systemd: Failed to mount /home
emergency mode: /dev/sdb1 does not exist

系统表现

  • 磁盘无法挂载
  • 系统启动失败
  • 应用无法访问数据
  • 挂载点显示为空
  • 自动挂载失效

🔍 问题诊断

1. 检查磁盘和分区状态

# 查看所有磁盘和分区
lsblk
fdisk -l
parted -l

# 查看磁盘使用情况
df -h
mount | column -t

# 查看磁盘UUID
blkid
ls -l /dev/disk/by-uuid/

2. 检查文件系统

# 检查文件系统类型
file -s /dev/sdb1
blkid /dev/sdb1

# 检查文件系统状态
fsck -n /dev/sdb1  # 只检查不修复
e2fsck -n /dev/sdb1  # ext文件系统
xfs_check /dev/sdb1  # XFS文件系统

# 查看文件系统详细信息
tune2fs -l /dev/sdb1  # ext文件系统
xfs_info /dev/sdb1    # XFS文件系统

3. 检查挂载配置

# 查看fstab配置
cat /etc/fstab

# 检查fstab语法
mount -a -v  # 测试所有fstab条目
findmnt --verify

# 查看当前挂载状态
mount
findmnt
cat /proc/mounts

4. 检查挂载点

# 检查挂载点目录
ls -ld /mnt/data
ls -la /mnt/data

# 检查挂载点权限
namei -l /mnt/data

# 查看挂载点使用情况
lsof /mnt/data
fuser -v /mnt/data

5. 检查系统日志

# 查看挂载相关日志
dmesg | grep -i mount
journalctl | grep mount
tail -f /var/log/messages | grep mount

# 查看磁盘错误日志
dmesg | grep -i error
dmesg | grep -i "I/O error"

🛠️ 解决方案

基本挂载问题

1. 手动挂载磁盘

# 创建挂载点
sudo mkdir -p /mnt/data

# 基本挂载命令
sudo mount /dev/sdb1 /mnt/data

# 指定文件系统类型
sudo mount -t ext4 /dev/sdb1 /mnt/data
sudo mount -t xfs /dev/sdb1 /mnt/data
sudo mount -t ntfs-3g /dev/sdb1 /mnt/data

# 使用UUID挂载
sudo mount UUID=12345678-1234-1234-1234-123456789012 /mnt/data

# 只读挂载
sudo mount -o ro /dev/sdb1 /mnt/data

2. 卸载磁盘

# 基本卸载
sudo umount /mnt/data
sudo umount /dev/sdb1

# 强制卸载(谨慎使用)
sudo umount -f /mnt/data
sudo umount -l /mnt/data  # 懒卸载

# 查找占用进程并终止
sudo fuser -km /mnt/data
sudo lsof /mnt/data

3. 配置自动挂载

# 编辑fstab文件
sudo vim /etc/fstab

# fstab条目格式示例
# 设备标识    挂载点      文件系统  挂载选项    dump  fsck
/dev/sdb1    /mnt/data   ext4      defaults    0     2
UUID=12345678-1234-1234-1234-123456789012 /mnt/data ext4 defaults 0 2

# 测试fstab配置
sudo mount -a

# 重新挂载所有fstab条目
sudo mount -o remount -a

文件系统问题解决

1. 修复损坏的文件系统

# 卸载文件系统
sudo umount /dev/sdb1

# 修复ext文件系统
sudo e2fsck -f /dev/sdb1      # 强制检查
sudo e2fsck -y /dev/sdb1      # 自动修复
sudo e2fsck -p /dev/sdb1      # 自动修复安全错误

# 修复XFS文件系统
sudo xfs_repair /dev/sdb1     # 修复XFS
sudo xfs_repair -n /dev/sdb1  # 只检查不修复

# 修复NTFS文件系统
sudo ntfsfix /dev/sdb1

2. 重新格式化磁盘

# 备份重要数据后再格式化

# 格式化为ext4
sudo mkfs.ext4 /dev/sdb1

# 格式化为XFS
sudo mkfs.xfs /dev/sdb1

# 格式化为NTFS
sudo mkfs.ntfs /dev/sdb1

# 创建分区并格式化
sudo fdisk /dev/sdb
sudo mkfs.ext4 /dev/sdb1

特殊挂载选项

1. 网络文件系统

# 挂载NFS
sudo mount -t nfs server_ip:/path/to/share /mnt/nfs

# 挂载CIFS/SMB
sudo mount -t cifs //server_ip/share /mnt/smb -o username=user,password=pass

# fstab中的网络挂载
server_ip:/path/to/share /mnt/nfs nfs defaults,_netdev 0 0
//server/share /mnt/smb cifs username=user,password=pass,_netdev 0 0

2. 特殊挂载选项

# 以特定用户权限挂载
sudo mount -o uid=1000,gid=1000 /dev/sdb1 /mnt/data

# 挂载为可执行/不可执行
sudo mount -o exec /dev/sdb1 /mnt/data      # 允许执行
sudo mount -o noexec /dev/sdb1 /mnt/data    # 禁止执行

# 挂载为读写/只读
sudo mount -o rw /dev/sdb1 /mnt/data        # 读写
sudo mount -o ro /dev/sdb1 /mnt/data        # 只读

# 禁用suid位
sudo mount -o nosuid /dev/sdb1 /mnt/data

🔧 磁盘挂载管理脚本

自动挂载检测脚本

#!/bin/bash
# mount_check.sh

LOG_FILE="/var/log/mount_check.log"

log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}

# 检查fstab中的挂载点
check_fstab_mounts() {
    log_message "检查fstab挂载点..."

    while read -r line; do
        # 跳过注释和空行
        [[ $line =~ ^#.*$ ]] && continue
        [[ -z $line ]] && continue

        # 解析fstab条目
        device=$(echo $line | awk '{print $1}')
        mountpoint=$(echo $line | awk '{print $2}')

        # 跳过特殊挂载点
        [[ $mountpoint =~ ^(proc|sysfs|devpts|tmpfs|none)$ ]] && continue

        # 检查挂载点是否存在
        if [ ! -d "$mountpoint" ]; then
            log_message "警告: 挂载点不存在 $mountpoint"
            continue
        fi

        # 检查是否已挂载
        if ! mountpoint -q "$mountpoint"; then
            log_message "错误: $mountpoint 未挂载,尝试挂载..."

            if mount "$mountpoint"; then
                log_message "成功: $mountpoint 已重新挂载"
            else
                log_message "失败: $mountpoint 挂载失败"
                # 发送告警
                echo "$mountpoint 挂载失败" | mail -s "挂载告警" admin@example.com
            fi
        else
            log_message "正常: $mountpoint 已挂载"
        fi

    done < /etc/fstab
}

# 检查磁盘空间
check_disk_space() {
    log_message "检查磁盘空间..."

    df -h | grep -vE '^Filesystem|tmpfs|cdrom|udev' | awk '{print $5 " " $1 " " $6}' | while read output; do
        usage=$(echo $output | awk '{print $1}' | cut -d'%' -f1)
        device=$(echo $output | awk '{print $2}')
        mountpoint=$(echo $output | awk '{print $3}')

        if [ $usage -ge 90 ]; then
            log_message "警告: $mountpoint ($device) 磁盘使用率 $usage%"
        fi
    done
}

# 主程序
log_message "开始挂载检查..."
check_fstab_mounts
check_disk_space
log_message "挂载检查完成"

磁盘挂载管理脚本

#!/bin/bash
# disk_mount_manager.sh

SCRIPT_NAME=$(basename "$0")

show_usage() {
    cat << EOF
用法: $SCRIPT_NAME [选项] <设备> <挂载点>

选项:
  -m, --mount        挂载设备
  -u, --umount       卸载设备
  -a, --auto         添加到fstab自动挂载
  -r, --remove       从fstab移除
  -f, --format       格式化设备
  -c, --check        检查文件系统
  -h, --help         显示帮助信息

示例:
  $SCRIPT_NAME -m /dev/sdb1 /mnt/data
  $SCRIPT_NAME -u /mnt/data
  $SCRIPT_NAME -a /dev/sdb1 /mnt/data
  $SCRIPT_NAME -f /dev/sdb1
EOF
}

mount_device() {
    local device=$1
    local mountpoint=$2

    if [ -z "$device" ] || [ -z "$mountpoint" ]; then
        echo "错误: 需要指定设备和挂载点"
        return 1
    fi

    # 创建挂载点
    if [ ! -d "$mountpoint" ]; then
        echo "创建挂载点: $mountpoint"
        sudo mkdir -p "$mountpoint"
    fi

    # 检查设备是否存在
    if [ ! -b "$device" ]; then
        echo "错误: 设备 $device 不存在"
        return 1
    fi

    # 挂载设备
    echo "挂载 $device$mountpoint..."
    if sudo mount "$device" "$mountpoint"; then
        echo "挂载成功"
        df -h "$mountpoint"
    else
        echo "挂载失败"
        return 1
    fi
}

umount_device() {
    local target=$1

    if [ -z "$target" ]; then
        echo "错误: 需要指定设备或挂载点"
        return 1
    fi

    # 检查是否已挂载
    if ! mountpoint -q "$target" 2>/dev/null; then
        echo "警告: $target 未挂载"
        return 0
    fi

    # 检查是否有进程在使用
    if lsof "$target" 2>/dev/null; then
        echo "警告: 有进程正在使用 $target"
        echo "正在使用的进程:"
        lsof "$target"
        read -p "是否强制卸载? (y/N): " confirm
        if [[ $confirm == [yY] ]]; then
            sudo fuser -km "$target"
            sleep 2
        else
            return 1
        fi
    fi

    # 卸载
    echo "卸载 $target..."
    if sudo umount "$target"; then
        echo "卸载成功"
    else
        echo "卸载失败,尝试强制卸载..."
        sudo umount -f "$target" || sudo umount -l "$target"
    fi
}

add_to_fstab() {
    local device=$1
    local mountpoint=$2
    local fstype=${3:-ext4}

    # 获取UUID
    local uuid=$(blkid -s UUID -o value "$device")

    if [ -z "$uuid" ]; then
        echo "错误: 无法获取设备 $device 的UUID"
        return 1
    fi

    # 检查是否已存在
    if grep -q "$uuid" /etc/fstab; then
        echo "警告: 设备已在fstab中"
        return 0
    fi

    # 添加到fstab
    echo "添加到 /etc/fstab..."
    echo "UUID=$uuid $mountpoint $fstype defaults 0 2" | sudo tee -a /etc/fstab
    echo "已添加自动挂载条目"

    # 测试挂载
    sudo mount -a
}

# 主程序
case "$1" in
    -m|--mount)
        mount_device "$2" "$3"
        ;;
    -u|--umount)
        umount_device "$2"
        ;;
    -a|--auto)
        add_to_fstab "$2" "$3" "$4"
        ;;
    -f|--format)
        echo "警告: 格式化将删除所有数据!"
        read -p "确认格式化 $2? (yes/no): " confirm
        if [ "$confirm" = "yes" ]; then
            sudo mkfs.ext4 "$2"
        fi
        ;;
    -c|--check)
        sudo fsck -n "$2"
        ;;
    -h|--help)
        show_usage
        ;;
    *)
        echo "错误: 未知选项 $1"
        show_usage
        exit 1
        ;;
esac

📊 挂载监控和维护

1. 定期检查脚本

# 添加到crontab
echo "*/10 * * * * /usr/local/bin/mount_check.sh" | crontab -

# 每日磁盘健康检查
echo "0 2 * * * /usr/local/bin/disk_health_check.sh" | crontab -

2. 自动修复脚本

#!/bin/bash
# auto_remount.sh

# 自动重新挂载失败的设备
grep -v '^#' /etc/fstab | while read device mountpoint fstype options dump pass; do
    if [ -n "$mountpoint" ] && [ "$mountpoint" != "none" ]; then
        if ! mountpoint -q "$mountpoint"; then
            echo "尝试重新挂载 $mountpoint"
            mount "$mountpoint"
        fi
    fi
done

🚨 应急处理

系统无法启动时

  1. 进入救援模式 ```bash

    启动到emergency模式

    systemctl rescue

或使用单用户模式

在grub中添加 single 或 emergency 参数


2. **修复fstab错误**
```bash
# 以只读方式重新挂载根分区
mount -o remount,rw /

# 备份并编辑fstab
cp /etc/fstab /etc/fstab.backup
nano /etc/fstab

# 注释有问题的行
# /dev/sdb1 /mnt/data ext4 defaults 0 2
  1. 手动挂载关键分区 ```bash

    挂载/home分区

    mount /dev/sdb2 /home

挂载/var分区

mount /dev/sdb3 /var ```

📚 相关工具

  • mount/umount - 挂载/卸载命令
  • lsblk - 列出块设备
  • blkid - 显示设备属性
  • fdisk - 磁盘分区工具
  • fsck - 文件系统检查工具
  • fuser - 查找使用文件的进程

通过系统的诊断和正确的操作,可以解决大多数磁盘挂载问题,确保数据的可访问性和系统的稳定性。


powered by Gitbook© 2025 编外计划 | 最后修改: 2025-07-28 12:47:16

results matching ""

    No results matching ""