• 首页
  • 前端
    • HTML
    • CSS
    • Javascript
    • XML
    • AJAX
  • 前端框架
    • BootStrap
    • Jquery
  • PHP
    • 语法
    • 核心
    • 面向对象
    • PHP7
    • Socket
    • Swoole
  • 数据库
    • Mysql
    • Redis
    • Memcache
    • MongoDB
  • 优化
    • 优化方案
    • 页面静态化
    • Nginx
  • 后台框架与实战
    • Smarty
    • 源码Blog
    • TP3.2
    • TP3.2商城
    • TP5.0
    • TP5.0商城
    • Laravel
    • Laravel在线教育平台
    • Yii
    • Yii手机直播
    • CodeIgniter
    • Yaf
  • 移动开发
    • 微信公众号
    • 混合APP
  • 二次开发
    • DedeCMS
  • Linux
    • 基本操作
    • 环境搭建
  • 版本控制
    • GIT
    • SVN
  • Node.js
  • 资料库
没有结果
查看所有结果
  • 首页
  • 前端
    • HTML
    • CSS
    • Javascript
    • XML
    • AJAX
  • 前端框架
    • BootStrap
    • Jquery
  • PHP
    • 语法
    • 核心
    • 面向对象
    • PHP7
    • Socket
    • Swoole
  • 数据库
    • Mysql
    • Redis
    • Memcache
    • MongoDB
  • 优化
    • 优化方案
    • 页面静态化
    • Nginx
  • 后台框架与实战
    • Smarty
    • 源码Blog
    • TP3.2
    • TP3.2商城
    • TP5.0
    • TP5.0商城
    • Laravel
    • Laravel在线教育平台
    • Yii
    • Yii手机直播
    • CodeIgniter
    • Yaf
  • 移动开发
    • 微信公众号
    • 混合APP
  • 二次开发
    • DedeCMS
  • Linux
    • 基本操作
    • 环境搭建
  • 版本控制
    • GIT
    • SVN
  • Node.js
  • 资料库
没有结果
查看所有结果
没有结果
查看所有结果

重装 PVE 时彻底清理旧磁盘残留教程

Mr.Lee 由 Mr.Lee
2025年10月8日
在 资料
0
PVE_LOGO
0
分享
5
浏览

一、重装 PVE 时,安装器在扫描硬盘时可能检测到旧的 PVE 元数据(尤其是 LVM/ZFS),安装器在尝试重命名卷组失败时,会导致安装中断。   本文提供完整的清理方案,确保磁盘干净,PVE 安装器不会再触发 `pve-OLD` 重命名。

二、准备两个 U 盘

1. **SystemRescue U 盘**      用 Rufus 或其他写盘工具,将 [SystemRescue ISO](https://www.system-rescue.org/Download/) 写入一个 U 盘。

2. **pve-clean.sh 脚本 U 盘**      在另一台电脑上准备 U 盘,把以下脚本写入 `pve-clean.sh` 文件:


#!/usr/bin/env bash
# pve-clean.sh (改进版)
# 一键彻底清理指定磁盘的 LVM/ZFS/RAID/LUKS/分区表/签名/头尾元数据 等
# 请务必先阅读脚本并确认 TARGET 指向正确磁盘(例如 /dev/sda)
set -euo pipefail

# ---- 默认参数 ----
TARGET="/dev/sda"
DO_SECURE_ERASE=0   # -s 启用(高风险,仅在直连SATA时使用)
DO_HPA_DCO=0        # -H 启用(极高风险)
FORCE=0             # -y 跳过交互式确认
HEAD_TAIL_MB=32     # 抹头尾大小(MiB)
LOGFILE="/tmp/pve-clean.log"

# ---- 帮助 ----
usage() {
  cat <<EOF
Usage: $0 [options]
  -d/--disk   <device>   目标磁盘(默认: /dev/sda)
  -s/--secure-erase     启用 ATA Secure Erase(需 hdparm,直连 SATA,危险)
  -H/--hpa-dco          尝试恢复 HPA/DCO(极高风险,可能造成不可用)
  -y/--yes              跳过确认(危险)
  -h/--help             显示此帮助
Example:
  $0 -d /dev/sda
  $0 -d /dev/sda -y
EOF
  exit 1
}

# ---- 日志与退出处理 ----
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOGFILE"; }
die() { echo "[$(date '+%F %T')] ERROR: $*" | tee -a "$LOGFILE" >&2; exit 1; }

on_exit() {
  local rc=$?
  if [[ $rc -ne 0 ]]; then
    echo "[$(date '+%F %T')] 脚本异常退出, rc=$rc" | tee -a "$LOGFILE"
  else
    echo "[$(date '+%F %T')] 脚本正常结束" | tee -a "$LOGFILE"
  fi
}
trap on_exit EXIT

# ---- 参数解析(更严格:避免 -d 后无参数) ----
if [[ $# -eq 0 ]]; then
  # keep defaults
  :
fi

while [[ $# -gt 0 ]]; do
  case "$1" in
    -d|--disk)
      if [[ -z "${2-}" || "${2#-}" != "${2}" ]]; then
        die "缺少 -d/--disk 参数,或参数看起来像另一个选项:'$2'"
      fi
      TARGET="$2"; shift 2 ;;
    -s|--secure-erase) DO_SECURE_ERASE=1; shift ;;
    -H|--hpa-dco) DO_HPA_DCO=1; shift ;;
    -y|--yes) FORCE=1; shift ;;
    -h|--help) usage ;;
    *)
      echo "未知参数: $1"
      usage ;;
  esac
done

# ---- 环境与安全检查 ----
if [[ $(id -u) -ne 0 ]]; then
  die "请以 root 身份运行此脚本 (sudo)。"
fi

if [[ ! -b "$TARGET" ]]; then
  die "设备不存在或不是块设备: $TARGET"
fi

DEVNAME=$(basename "$TARGET")
log "目标磁盘: $TARGET (device name: $DEVNAME)"
lsblk -d -o NAME,MODEL,SERIAL,SIZE,TRAN "$TARGET" | tee -a "$LOGFILE" || true

# avoid glob expansion producing literal when no match
shopt -s nullglob

# 检查是否为根盘或系统盘(防止误擦除当前运行盘)
root_src=$(findmnt -n -o SOURCE / || true)
if [[ -n "$root_src" ]]; then
  # 例如 /dev/mapper/ubuntu--vg-root 或 /dev/sda2
  if [[ "$root_src" == "$TARGET" || "$root_src" == "$TARGET"* ]]; then
    die "目标磁盘 ($TARGET) 包含当前系统根分区 ($root_src)。为了安全起见,脚本终止。"
  fi
fi

# 通过 /proc/cmdline 或者 /etc/fstab 等也可做更多检查(这里保守处理)

# 检查 /dev/disk/by-id 中是否为 USB 桥接
USB_BRIDGE=0
for id in /dev/disk/by-id/* 2>/dev/null; do
  if [[ "$(readlink -f "$id")" == "$TARGET" ]]; then
    baseid=$(basename "$id")
    if [[ "$baseid" == usb-* || "$baseid" == *-usb-* ]]; then
      USB_BRIDGE=1
      break
    fi
  fi
done
if [[ $USB_BRIDGE -eq 1 ]]; then
  log "注意:检测到该盘通过 USB 桥接 (by-id 包含 usb-),hdparm/secure-erase/blkdiscard 可能无效或危险。"
fi

# 用户确认(非强制模式)
if [[ $FORCE -ne 1 ]]; then
  echo ""
  echo "!!! 警告:以下操作会彻底清除 $TARGET 上的所有数据(包括 LVM/ZFS/RAID/LUKS/分区表)。"
  echo "如果你确定继续,请输入磁盘名 (例如 $DEVNAME) 再按 Enter:"
  read -r CONFIRM
  if [[ "$CONFIRM" != "$DEVNAME" ]]; then
    die "未输入正确磁盘名,已取消。"
  fi
fi

log "开始清理流程,记录写入 $LOGFILE"

# ---- 辅助函数 ----
safe_cmd() {
  # 运行命令,捕获错误并记录,但不退出脚本(因为 set -e)
  # 用法: safe_cmd some command arg ...
  if ! "$@" 2>>"$LOGFILE"; then
    log "命令失败: $*(见 $LOGFILE 详情)"
    return 1
  fi
  return 0
}

# ---- 1) 基础停用/卸载 ----
log "1) 取消挂载、停用 swap、停用 LVM/MD/ZFS(开始)"
set +e
# 构造设备列表(包含 TARGET 自身和其可能的子设备)
devs=()
devs+=("$TARGET")
# 添加匹配的设备(例如 /dev/sda1 /dev/sda2 /dev/sda-part 等)
for match in "${TARGET}"*; do
  # 如果 match 与 TARGET 相同已经包含,nullglob 确保只有真实匹配进入
  if [[ -b "$match" && "$match" != "$TARGET" ]]; then
    devs+=("$match")
  fi
done

# 卸载所有该盘的挂载点(递归)
for part in "${devs[@]}"; do
  if [[ -b "$part" ]]; then
    mountpoint=$(findmnt -n -o TARGET --source "$part" 2>/dev/null || true)
    if [[ -n "$mountpoint" ]]; then
      log "尝试 umount -R $part (mounted at $mountpoint)"
      umount -R "$part" 2>>"$LOGFILE" || {
        log "umount -R 失败,尝试 lazy umount -l $part"
        umount -l "$part" 2>>"$LOGFILE" || log "umount 仍失败:$part"
      }
    fi
  fi
done

safe_cmd swapoff -a || true

# 停用所有 LVM 卷组(尽量停掉)
if command -v vgchange >/dev/null 2>&1; then
  safe_cmd vgchange -an || true
else
  log "vgchange (LVM) 不存在,跳过 vgchange -an"
fi

# 停止 mdadm 阵列(尽量尝试)
if command -v mdadm >/dev/null 2>&1; then
  safe_cmd mdadm --stop --scan || true
else
  log "mdadm 不存在,跳过 mdadm --stop --scan"
fi

# export zpool
if command -v zpool >/dev/null 2>&1; then
  safe_cmd zpool export -a || true
else
  log "zpool 不存在,跳过 zpool export -a"
fi

# dmsetup:谨慎处理(仅在有映射且不包含根映射时移除)
if command -v dmsetup >/dev/null 2>&1; then
  # 列出映射并检查是否有指向目标的路径
  dmsetup ls --target multipath 2>/dev/null || true
  # 不直接执行 remove_all(过于激进),仅尝试移除空闲映射
  # 如果你确实需要强制移除,请手动运行 dmsetup remove_all
else
  log "dmsetup 不存在或不可用,跳过 dmsetup 处理"
fi
set -e

# ---- 2) 清理 LVM(针对该盘的 PV) ----
log "2) 清除 LVM PV/VG/LV 元数据(仅针对与 $TARGET 相关的 PV)"
if command -v pvs >/dev/null 2>&1; then
  # 使用分隔符,避免 vg 名含空格导致解析出错
  while IFS='|' read -r pv vg; do
    pv=${pv:-}
    vg=${vg:-}
    # 仅处理以 TARGET 前缀匹配的 PV(如 /dev/sda1 或 /dev/mapper/...)
    if [[ -n "$pv" && "$pv" == "$TARGET"* ]]; then
      log "发现 PV $pv 在 VG $vg:执行 pvremove -ff -y $pv"
      pvremove -ff -y "$pv" >>"$LOGFILE" 2>&1 || log "pvremove 失败:$pv"
      # 检查该 VG 是否还有 PV
      if [[ -n "$vg" ]]; then
        if ! pvs --noheadings -o pv_name "$vg" 2>>"$LOGFILE" | grep -q .; then
          log "VG $vg 似乎没有 PV,尝试 vgremove -f $vg"
          vgremove -f "$vg" >>"$LOGFILE" 2>&1 || log "vgremove 失败:$vg"
        fi
      fi
    fi
  done < <(pvs --noheadings --separator '|' -o pv_name,vg_name 2>/dev/null || true)
else
  log "系统没有 pvs 工具,跳过 LVM 深度清理"
fi

# ---- 3) 清理 mdadm 超级块(软 RAID) ----
log "3) 清理 mdadm(superblock)(如果有)"
if command -v mdadm >/dev/null 2>&1; then
  for dev in "${devs[@]}"; do
    if [[ -b "$dev" ]]; then
      log "尝试 mdadm --zero-superblock -f $dev"
      mdadm --zero-superblock -f "$dev" >>"$LOGFILE" 2>&1 || log "mdadm --zero-superblock 失败: $dev"
    fi
  done
else
  log "mdadm 不存在,跳过 mdadm --zero-superblock"
fi

# ---- 4) 清理 ZFS 标签(头/尾) ----
if command -v zpool >/dev/null 2>&1; then
  log "4) 清理 ZFS 标签(如果存在)"
  for dev in "${devs[@]}"; do
    if [[ -b "$dev" ]]; then
      log "尝试 zpool labelclear -f $dev"
      zpool labelclear -f "$dev" >>"$LOGFILE" 2>&1 || log "zpool labelclear 失败: $dev"
    fi
  done
else
  log "zpool 不存在,跳过 ZFS labelclear"
fi

# ---- 5) 清理 LUKS (如果存在) ----
if command -v cryptsetup >/dev/null 2>&1; then
  log "5) 检测并处理 LUKS (cryptsetup)"
  for dev in "${devs[@]}"; do
    if [[ -b "$dev" ]]; then
      if cryptsetup isLuks "$dev" 2>>"$LOGFILE"; then
        log "$dev 被检测为 LUKS,覆盖前 4 MiB 以破坏 header(不可恢复)"
        dd if=/dev/zero of="$dev" bs=1M count=4 status=progress conv=fsync 2>>"$LOGFILE" || log "dd 覆盖 LUKS 头失败: $dev"
      fi
    fi
  done
else
  log "系统没有 cryptsetup,跳过 LUKS 检测"
fi

# ---- 6) wipefs 清理可见签名 ----
if command -v wipefs >/dev/null 2>&1; then
  log "6) wipefs -a 清除可见签名(文件系统/RAID/LVM 等)"
  for dev in "${devs[@]}"; do
    if [[ -b "$dev" ]]; then
      wipefs -a -f "$dev" >>"$LOGFILE" 2>&1 || log "wipefs 失败: $dev"
    fi
  done
else
  log "wipefs 不存在,跳过"
fi

# ---- 7) 清 GPT/MBR(sgdisk -Z/--zap-all) ----
if command -v sgdisk >/dev/null 2>&1; then
  log "7) sgdisk --zap-all $TARGET (清 GPT/MBR 主/备表)"
  sgdisk --zap-all "$TARGET" >>"$LOGFILE" 2>&1 || log "sgdisk --zap-all 失败"
else
  log "sgdisk 不存在,跳过 sgdisk --zap-all"
fi

# ---- 8) multipath 处理 ----
if command -v multipath >/dev/null 2>&1; then
  log "8) multipath 检查并删除包含该设备的 map(如果有)"
  # 从 multipath -ll 中提取 map 名称(鲁棒处理)
  maps=$(multipath -ll 2>/dev/null | awk '/^[^ ]/ {print $1}' || true)
  for map in $maps; do
    if multipath -ll "$map" 2>>"$LOGFILE" | grep -q "$DEVNAME"; then
      log "尝试 multipath -f $map"
      multipath -f "$map" >>"$LOGFILE" 2>&1 || log "multipath -f 失败: $map"
    fi
  done
else
  log "multipath 不存在,跳过"
fi

# ---- 9) 抹头(前 HEAD_TAIL_MB MiB) ----
log "9) 抹前 ${HEAD_TAIL_MB}MiB (尝试使用 direct oflag)"
# 尝试使用 oflag=direct,失败后回退
if dd if=/dev/zero of="$TARGET" bs=1M count=$HEAD_TAIL_MB status=progress conv=fsync oflag=direct 2>>"$LOGFILE"; then
  log "抹头完成(oflag=direct)"
else
  log "oflag=direct 不支持或失败,尝试不使用 oflag"
  dd if=/dev/zero of="$TARGET" bs=1M count=$HEAD_TAIL_MB status=progress conv=fsync 2>>"$LOGFILE" || log "抹头失败"
fi

# ---- 10) 抹尾(后 HEAD_TAIL_MB MiB) ----
log "10) 抹尾 ${HEAD_TAIL_MB}MiB(仅在容量允许时)"
if command -v blockdev >/dev/null 2>&1; then
  size_bytes=$(blockdev --getsize64 "$TARGET" 2>>"$LOGFILE" || echo 0)
  size_mb=$((size_bytes/1024/1024))
  if (( size_mb > HEAD_TAIL_MB * 2 )); then
    tail_start=$((size_mb - HEAD_TAIL_MB))
    log "磁盘总大小: ${size_mb}MiB;从 ${tail_start}MiB 开始写入 ${HEAD_TAIL_MB}MiB"
    if dd if=/dev/zero of="$TARGET" bs=1M seek=$tail_start count=$HEAD_TAIL_MB status=progress conv=fsync oflag=direct 2>>"$LOGFILE"; then
      log "抹尾完成(oflag=direct)"
    else
      log "oflag=direct 抹尾失败,尝试不使用 oflag"
      dd if=/dev/zero of="$TARGET" bs=1M seek=$tail_start count=$HEAD_TAIL_MB status=progress conv=fsync 2>>"$LOGFILE" || log "抹尾失败"
    fi
  else
    log "磁盘太小 (${size_mb}MiB),跳过尾部抹写"
  fi
else
  log "blockdev 不存在,无法获取磁盘大小,跳过尾部抹写"
fi
sync

# ---- 11) blkdiscard(如果是 SSD 且支持) ----
if command -v blkdiscard >/dev/null 2>&1; then
  if [[ $USB_BRIDGE -eq 0 ]]; then
    log "11) 尝试 blkdiscard -v $TARGET(如果设备支持)"
    blkdiscard -v "$TARGET" >>"$LOGFILE" 2>&1 || log "blkdiscard 失败或不支持"
  else
    log "设备通过 USB,跳过 blkdiscard(通常无效或危险)"
  fi
else
  log "blkdiscard 不存在,跳过"
fi

# ---- 12) 可选:ATA Secure Erase(高风险) ----
if [[ $DO_SECURE_ERASE -eq 1 ]]; then
  if [[ $USB_BRIDGE -eq 1 ]]; then
    log "检测到 USB 桥接,跳过 ATA Secure Erase(USB 桥通常不支持 ATA 命令)"
  elif ! command -v hdparm >/dev/null 2>&1 ; then
    log "hdparm 不存在,无法进行 ATA Secure Erase,跳过"
  else
    log "12) ATA Secure Erase 检查"
    # 查询并输出(记录)
    hdparm -I "$TARGET" 2>&1 | tee -a "$LOGFILE" || log "hdparm -I 失败"
    # 检查是否 frozen(宽松匹配)
    if hdparm -I "$TARGET" 2>/dev/null | grep -qi frozen; then
      log "磁盘状态显示为 FROZEN,无法直接执行 secure erase。请解除 frozen(例如 BIOS 热插/重启/挂起恢复),脚本不会自动挂起。"
    else
      # 额外确认(用户交互)
      if [[ $FORCE -ne 1 ]]; then
        echo ""
        echo "警告:你选择了 --secure-erase。这会触发硬件级安全擦除,可能需要较长时间且不可逆。输入 'yes' 确认继续:"
        read -r seconf
        if [[ "$seconf" != "yes" ]]; then
          log "用户未确认 secure erase,跳过"
        else
          ERASE_PW="pveclean"
          log "设置临时口令并尝试执行 --security-erase-enhanced(若不支持则 fallback 到普通)"
          hdparm --user-master u --security-set-pass "$ERASE_PW" "$TARGET" >>"$LOGFILE" 2>&1 || log "hdparm 设置口令失败"
          if hdparm --user-master u --security-erase-enhanced "$ERASE_PW" "$TARGET" >>"$LOGFILE" 2>&1; then
            log "执行 --security-erase-enhanced 成功(请等待完成)"
          else
            log "--security-erase-enhanced 不支持或失败,尝试 --security-erase"
            hdparm --user-master u --security-erase "$ERASE_PW" "$TARGET" >>"$LOGFILE" 2>&1 || log "--security-erase 也失败"
          fi
        fi
      else
        log "强制模式(-y)已开启,直接尝试 secure erase(风险自负)"
        ERASE_PW="pveclean"
        hdparm --user-master u --security-set-pass "$ERASE_PW" "$TARGET" >>"$LOGFILE" 2>&1 || log "hdparm 设置口令失败"
        if hdparm --user-master u --security-erase-enhanced "$ERASE_PW" "$TARGET" >>"$LOGFILE" 2>&1; then
          log "执行 --security-erase-enhanced 成功"
        else
          log "--security-erase-enhanced 不支持或失败,尝试 --security-erase"
          hdparm --user-master u --security-erase "$ERASE_PW" "$TARGET" >>"$LOGFILE" 2>&1 || log "--security-erase 也失败"
        fi
      fi
    fi
  fi
fi

# ---- 13) 可选:HPA/DCO 检查(脚本默认不自动更改) ----
if [[ $DO_HPA_DCO -eq 1 ]]; then
  if ! command -v hdparm >/dev/null 2>&1 ; then
    log "hdparm 不存在,无法做 HPA/DCO 操作,跳过"
  elif [[ $USB_BRIDGE -eq 1 ]]; then
    log "设备通过 USB,跳过 HPA/DCO 操作(USB 桥不支持)"
  else
    log "13) 检查 HPA / DCO(脚本仅显示,不自动修改)"
    # hdparm -N 输出解析(尽可能容错)
    hdparm_N_out=$(hdparm -N "$TARGET" 2>>"$LOGFILE" || true)
    if [[ -n "$hdparm_N_out" ]]; then
      # 尝试解析 native 和 current
      native=$(echo "$hdparm_N_out" | awk -F'(' '/native/ {print $1}' | grep -o '[0-9]\+' || true)
      cur=$(echo "$hdparm_N_out" | awk -F'(' '/current/ {print $1}' | grep -o '[0-9]\+' || true)
      log "hdparm -N 输出(摘录): $(echo "$hdparm_N_out" | tr '\n' ' ' | cut -c1-300)"
      log "解析结果:native=$native current=$cur"
      if [[ -n "$native" && -n "$cur" && "$cur" -lt "$native" ]]; then
        log "注意:current < native,表示存在 HPA/DCO,理论上可用 hdparm -N p<native> 恢复(高风险)。脚本不会自动执行恢复。"
      fi
    else
      log "hdparm -N 没有输出,可能不支持对该设备查询"
    fi
  fi
fi

# ---- 14) 再次 wipefs + sgdisk 兜底 ----
log "14) 最终 wipefs + sgdisk 再次清理(兜底)"
if command -v wipefs >/dev/null 2>&1; then
  for dev in "${devs[@]}"; do
    if [[ -b "$dev" ]]; then
      wipefs -a -f "$dev" >>"$LOGFILE" 2>&1 || log "最终 wipefs 失败: $dev"
    fi
  done
fi
if command -v sgdisk >/dev/null 2>&1; then
  sgdisk -Z "$TARGET" >>"$LOGFILE" 2>&1 || log "sgdisk -Z 失败"
fi

# ---- 15) 刷新内核设备表并自检 ----
log "15) 触发 udev 重新扫描并显示自检结果"
udevadm settle >>"$LOGFILE" 2>&1 || true
partprobe "$TARGET" >>"$LOGFILE" 2>&1 || true
sleep 1
log "lsblk:"
lsblk -o NAME,MODEL,SERIAL,SIZE,TYPE,MOUNTPOINT | tee -a "$LOGFILE" || true
log "wipefs 输出(应为空或仅残留):"
if command -v wipefs >/dev/null 2>&1; then
  wipefs "$TARGET" | tee -a "$LOGFILE" || true
fi
log "LVM (pvs/vgs/lvs):"
if command -v pvs >/dev/null 2>&1; then pvs 2>>"$LOGFILE" || true; fi
if command -v vgs >/dev/null 2>&1; then vgs 2>>"$LOGFILE" || true; fi
if command -v lvs >/dev/null 2>&1; then lvs 2>>"$LOGFILE" || true; fi

log "mdadm examine:"
if command -v mdadm >/dev/null 2>&1; then mdadm --examine --scan 2>>"$LOGFILE" || true; fi
if command -v zpool >/dev/null 2>&1; then
  log "zpool import -a (仅显示,不自动导入)"
  zpool import -a 2>>"$LOGFILE" || true
fi

log "清理完成。请在安装器或系统中重新检测磁盘 ($TARGET)。"
log "提示:如果安装器仍提示旧卷,请重启系统并再次运行此脚本,或检查 BIOS/RAID 控制器是否仍保存盘上元数据。如果还是不行请联系硬盘厂商提供官方工具清理到硬盘固件层数据,或者更换一块硬盘安装PVE,本脚本无法帮助你。"

exit 0

三、启动系统与执行清理

列出所有块设备与分区,找出 U 盘(根据 SIZE / MODEL 区分):


lsblk -o NAME,MAJ:MIN,RM,SIZE,MODEL,VENDOR,MOUNTPOINT


列出 by-id,以便精确识别 U 盘或目标盘:


ls -l /dev/disk/by-id/


假设脚本在 U 盘分区 `/dev/sdb1`(根据 `lsblk` 结果替换):


sudo mkdir -p /mnt/usb
sudo mount /dev/sdb1 /mnt/usb
ls -l /mnt/usb/pve-clean.sh
cd /mnt/usb


赋予执行权限并运行脚本(交互方式,需要输入磁盘名确认):


sudo chmod +x ./pve-clean.sh
sudo ./pve-clean.sh -d /dev/sda


> ⚠️ 替换 `/dev/sda` 为你要清理的目标磁盘!

四、执行后验证

确认没有任何签名:


wipefs /dev/sda


确认没有 LVM PV/VG/LV:


pvs || true
vgs || true
lvs || true


确认 mdadm 没有残余:


mdadm --examine --scan || true


确认 ZFS 不会列出旧池:


zpool import -a 2>/dev/null || true


查看磁盘是否还有分区:


lsblk -o NAME,SIZE,FSTYPE,TYPE,MOUNTPOINT


卸载 U 盘:


sudo umount /mnt/usb

五、清理后自检(在同一 Live 环境或 PVE 安装器 shell)

lsblk -e7 -o NAME,SIZE,FSTYPE,TYPE,MOUNTPOINT
blkid /dev/sda || true
pvs; vgs; lvs || true
zpool import || true
mdadm --examine --scan || true

六、开始安装 PVE 前的 BIOS/控制器检查

– **SATA 模式**:确保 BIOS 里是 AHCI,不是 “Intel RST/RAID”。

– **硬件 RAID**:如果用过主板/阵列卡的硬件 RAID,请在控制器管理界面删除磁盘组并清除元数据,否则 OS 仍可能在尾部发现控制器格式的超级块(不同厂商有各自工具,需在控制器 BIOS/CLI 里操作)。

– 回到 PVE 安装器,重新扫描磁盘。

七、总结

 **普通情况**(单盘、无 RAID/ZFS/LUKS):


sudo wipefs -a /dev/sdX


即可清理残留,PVE 安装器不会触发 `pve-OLD` 重命名。

- **复杂情况**(RAID/ZFS/LUKS、企业存储):

使用完整的 `pve-clean.sh` 脚本彻底清理磁盘头尾、LVM、RAID、ZFS、LUKS 等残留信息。

---

✅ **说明**:

1. 所有命令都在 代码块中,支持 GitHub、Typora、Obsidian、VS Code 等环境自动显示“复制”按钮。
2. 可直接复制此内容保存为 `.md` 文件,开箱即用。
3. 脚本已考虑安全确认、设备去激活、前后元数据清除,适用于企业级残留清理。

---

📌 **建议**:将此文档与 `pve-clean.sh` 一同放入 U 盘,便于现场维护。

标签: pve
上一篇文章

copilot使用体验,神奇的代码提示

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Search

没有结果
查看所有结果

About Me

个人随笔

Winston Lee

Programmer

Hello & welcome to my blog! My name is Winston Lee and am a programmer and am keen on sharing.

Winston Lee

About Me

Hello & welcome to my blog! My name is Winston Lee and am a programmer and am keen on sharing.

Categories

  • AJAX
  • BootStrap
  • CodeIgniter
  • CSS
  • DedeCMS
  • GIT
  • HTML
  • Javascript
  • Jquery
  • Laravel
  • Laravel在线教育平台
  • Linux
  • Memcache
  • MongoDB
  • MVC
  • Mysql
  • Nginx
  • Node
  • PDO
  • PHP
  • PHP7
  • PHP基本语法
  • PHP核心编程
  • Redis
  • Smarty
  • Socket
  • SVN
  • Swoole
  • TP3.2
  • TP3.2商城
  • TP5.0
  • TP5.0商城
  • XML
  • Yaf
  • Yii
  • Yii手机直播
  • 二次开发
  • 优化方案
  • 前端技术
  • 前端框架
  • 后台框架
  • 基本操作
  • 微信公众号
  • 数据库
  • 未分类
  • 混合APP
  • 源码Blog项目
  • 版本控制
  • 环境搭建
  • 移动端开发
  • 网站优化
  • 资料
  • 面向对象
  • 面向对象编程
  • 页面静态化

Tags

DOM Json RBAC 事件 传参 函数 分页 判断语句 匿名函数 变量 图片上传 存储过程 安装 对象 封装 属性 接口 控制器 数据库操作 数据类型 数据表 数组 文件上传 无刷新分页 权限 标签 模型 正则 流程控制 目录结构 算法 类 索引 继承 缩略图 表关系 视图 路由 运算符 选择器 递归 配置 错误处理 页面静态化 验证码
  • 首页
  • 前端
  • 前端框架
  • PHP
  • 数据库
  • 优化
  • 后台框架与实战
  • 移动开发
  • 二次开发
  • Linux
  • 版本控制
  • Node.js
  • 资料库

沪公网安备31011502400873 | 沪ICP备2024050435号-3

没有结果
查看所有结果
  • 首页
  • 前端
    • HTML
    • CSS
    • Javascript
    • XML
    • AJAX
  • 前端框架
    • BootStrap
    • Jquery
  • PHP
    • 语法
    • 核心
    • 面向对象
    • PHP7
    • Socket
    • Swoole
  • 数据库
    • Mysql
    • Redis
    • Memcache
    • MongoDB
  • 优化
    • 优化方案
    • 页面静态化
    • Nginx
  • 后台框架与实战
    • Smarty
    • 源码Blog
    • TP3.2
    • TP3.2商城
    • TP5.0
    • TP5.0商城
    • Laravel
    • Laravel在线教育平台
    • Yii
    • Yii手机直播
    • CodeIgniter
    • Yaf
  • 移动开发
    • 微信公众号
    • 混合APP
  • 二次开发
    • DedeCMS
  • Linux
    • 基本操作
    • 环境搭建
  • 版本控制
    • GIT
    • SVN
  • Node.js
  • 资料库

沪公网安备31011502400873 | 沪ICP备2024050435号-3