大量更新
This commit is contained in:
250
78-202603-重庆巫山监管/disk.sh
Normal file
250
78-202603-重庆巫山监管/disk.sh
Normal file
@@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
DISK="/dev/sdb"
|
||||
PART="${DISK}1"
|
||||
|
||||
NEW_VG="docker_vg"
|
||||
NEW_LV="docker_lv"
|
||||
MOUNT_POINT="/var/lib/docker"
|
||||
FS_TYPE="ext4" # 可改 ext4
|
||||
LV_SIZE="100%FREE"
|
||||
|
||||
log() {
|
||||
echo -e "\n[INFO] $*"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "\n[WARN] $*" >&2
|
||||
}
|
||||
|
||||
die() {
|
||||
echo -e "\n[ERROR] $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "缺少命令: $1"
|
||||
}
|
||||
|
||||
cleanup_mounts_on_disk() {
|
||||
log "检查 ${DISK} 相关挂载点"
|
||||
mapfile -t mps < <(lsblk -nrpo NAME,MOUNTPOINT "${DISK}" | awk '$2 != "" {print $2}' | sort -u)
|
||||
|
||||
if [[ ${#mps[@]} -gt 0 ]]; then
|
||||
warn "发现 ${DISK} 上存在挂载点: ${mps[*]}"
|
||||
for mp in "${mps[@]}"; do
|
||||
if mountpoint -q "$mp"; then
|
||||
log "卸载挂载点: $mp"
|
||||
umount -f "$mp" || die "无法卸载 $mp"
|
||||
fi
|
||||
done
|
||||
else
|
||||
log "未发现 ${DISK} 的活动挂载点"
|
||||
fi
|
||||
}
|
||||
|
||||
stop_docker() {
|
||||
log "停止 Docker 相关服务"
|
||||
systemctl stop docker 2>/dev/null || true
|
||||
systemctl stop docker.socket 2>/dev/null || true
|
||||
systemctl stop containerd 2>/dev/null || true
|
||||
}
|
||||
|
||||
deactivate_old_lvm() {
|
||||
log "检查旧 LVM 信息"
|
||||
|
||||
# 尝试识别 /dev/sdb 或 /dev/sdb1 所属 VG
|
||||
local old_vg=""
|
||||
old_vg="$(pvs --noheadings -o vg_name "${DISK}" 2>/dev/null | awk '{$1=$1;print}' | head -n1 || true)"
|
||||
|
||||
if [[ -z "${old_vg}" && -b "${PART}" ]]; then
|
||||
old_vg="$(pvs --noheadings -o vg_name "${PART}" 2>/dev/null | awk '{$1=$1;print}' | head -n1 || true)"
|
||||
fi
|
||||
|
||||
if [[ -n "${old_vg}" ]]; then
|
||||
warn "发现旧 VG: ${old_vg}"
|
||||
|
||||
log "列出旧 LV"
|
||||
lvs --noheadings -o lv_name "${old_vg}" 2>/dev/null | awk '{$1=$1;print}' || true
|
||||
|
||||
# 尝试卸载该 VG 下所有 LV 的挂载
|
||||
while read -r lv; do
|
||||
[[ -z "${lv}" ]] && continue
|
||||
local lv_path="/dev/${old_vg}/${lv}"
|
||||
if [[ -e "${lv_path}" ]]; then
|
||||
local mp
|
||||
mp="$(lsblk -nrpo MOUNTPOINT "${lv_path}" 2>/dev/null | awk 'NF{print; exit}' || true)"
|
||||
if [[ -n "${mp}" && "${mp}" != "[SWAP]" ]]; then
|
||||
log "卸载 LV 挂载点: ${mp}"
|
||||
umount -f "${mp}" || true
|
||||
fi
|
||||
fi
|
||||
done < <(lvs --noheadings -o lv_name "${old_vg}" 2>/dev/null | awk '{$1=$1;print}')
|
||||
|
||||
log "停用 VG: ${old_vg}"
|
||||
vgchange -an "${old_vg}" || true
|
||||
|
||||
# 再次激活以便删除 LV,部分系统需要先处于可见状态
|
||||
vgchange -ay "${old_vg}" || true
|
||||
|
||||
# 删除该 VG 下所有 LV
|
||||
while read -r lv; do
|
||||
[[ -z "${lv}" ]] && continue
|
||||
local lv_path="/dev/${old_vg}/${lv}"
|
||||
if [[ -e "${lv_path}" ]]; then
|
||||
log "删除旧 LV: ${lv_path}"
|
||||
lvremove -ff -y "${lv_path}" || true
|
||||
fi
|
||||
done < <(lvs --noheadings -o lv_name "${old_vg}" 2>/dev/null | awk '{$1=$1;print}')
|
||||
|
||||
log "停用并删除旧 VG: ${old_vg}"
|
||||
vgchange -an "${old_vg}" || true
|
||||
vgremove -ff -y "${old_vg}" || true
|
||||
else
|
||||
log "未发现 ${DISK} / ${PART} 上关联的 VG"
|
||||
fi
|
||||
|
||||
# 删除旧 PV
|
||||
if pvs "${PART}" >/dev/null 2>&1; then
|
||||
log "删除旧 PV: ${PART}"
|
||||
pvremove -ff -y "${PART}" || true
|
||||
fi
|
||||
|
||||
if pvs "${DISK}" >/dev/null 2>&1; then
|
||||
log "删除旧 PV: ${DISK}"
|
||||
pvremove -ff -y "${DISK}" || true
|
||||
fi
|
||||
|
||||
# 额外清理 device-mapper 残留
|
||||
log "清理可能遗留的 device-mapper 映射"
|
||||
dmsetup remove_all 2>/dev/null || true
|
||||
udevadm settle || true
|
||||
}
|
||||
|
||||
wipe_disk() {
|
||||
log "清理磁盘签名和分区表: ${DISK}"
|
||||
|
||||
swapoff -a 2>/dev/null || true
|
||||
|
||||
wipefs -a "${PART}" 2>/dev/null || true
|
||||
wipefs -a "${DISK}" 2>/dev/null || true
|
||||
|
||||
sgdisk --zap-all "${DISK}" || true
|
||||
dd if=/dev/zero of="${DISK}" bs=1M count=20 conv=fsync status=none || true
|
||||
|
||||
sync
|
||||
partprobe "${DISK}" || true
|
||||
blockdev --rereadpt "${DISK}" || true
|
||||
udevadm settle || true
|
||||
|
||||
# 如果分区节点还在,尝试删除
|
||||
if [[ -b "${PART}" ]]; then
|
||||
warn "${PART} 仍然存在,尝试删除分区表项"
|
||||
parted -s "${DISK}" rm 1 2>/dev/null || true
|
||||
partprobe "${DISK}" || true
|
||||
udevadm settle || true
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_mountpoint() {
|
||||
log "准备挂载目录: ${MOUNT_POINT}"
|
||||
|
||||
if mountpoint -q "${MOUNT_POINT}"; then
|
||||
umount -f "${MOUNT_POINT}" || die "无法卸载 ${MOUNT_POINT}"
|
||||
fi
|
||||
|
||||
mkdir -p "${MOUNT_POINT}"
|
||||
|
||||
if [[ -n "$(ls -A "${MOUNT_POINT}" 2>/dev/null || true)" ]]; then
|
||||
local backup_dir="${MOUNT_POINT}.bak.$(date +%F_%H%M%S)"
|
||||
warn "${MOUNT_POINT} 非空,备份到 ${backup_dir}"
|
||||
mv "${MOUNT_POINT}" "${backup_dir}"
|
||||
mkdir -p "${MOUNT_POINT}"
|
||||
fi
|
||||
}
|
||||
|
||||
create_new_lvm() {
|
||||
log "在整块磁盘 ${DISK} 上创建新的 LVM"
|
||||
|
||||
pvcreate -ff -y "${DISK}"
|
||||
vgcreate "${NEW_VG}" "${DISK}"
|
||||
lvcreate -n "${NEW_LV}" -l "${LV_SIZE}" "${NEW_VG}"
|
||||
|
||||
local lv_path="/dev/${NEW_VG}/${NEW_LV}"
|
||||
|
||||
log "格式化文件系统: ${FS_TYPE}"
|
||||
if [[ "${FS_TYPE}" == "xfs" ]]; then
|
||||
mkfs.xfs -f "${lv_path}"
|
||||
elif [[ "${FS_TYPE}" == "ext4" ]]; then
|
||||
mkfs.ext4 -F "${lv_path}"
|
||||
else
|
||||
die "不支持的文件系统: ${FS_TYPE}"
|
||||
fi
|
||||
|
||||
local uuid
|
||||
uuid="$(blkid -s UUID -o value "${lv_path}")"
|
||||
[[ -n "${uuid}" ]] || die "获取 UUID 失败"
|
||||
|
||||
log "写入 /etc/fstab"
|
||||
cp /etc/fstab "/etc/fstab.bak.$(date +%F_%H%M%S)"
|
||||
sed -i "\|[[:space:]]${MOUNT_POINT}[[:space:]]|d" /etc/fstab
|
||||
echo "UUID=${uuid} ${MOUNT_POINT} ${FS_TYPE} defaults 0 0" >> /etc/fstab
|
||||
|
||||
log "挂载 ${MOUNT_POINT}"
|
||||
mount -a
|
||||
|
||||
log "挂载结果校验"
|
||||
df -TH "${MOUNT_POINT}"
|
||||
lsblk
|
||||
}
|
||||
|
||||
start_docker() {
|
||||
log "启动 Docker"
|
||||
systemctl daemon-reload
|
||||
systemctl start containerd 2>/dev/null || true
|
||||
systemctl start docker
|
||||
systemctl enable docker 2>/dev/null || true
|
||||
}
|
||||
|
||||
main() {
|
||||
require_cmd lsblk
|
||||
require_cmd pvs
|
||||
require_cmd vgs
|
||||
require_cmd lvs
|
||||
require_cmd pvcreate
|
||||
require_cmd vgcreate
|
||||
require_cmd lvcreate
|
||||
require_cmd wipefs
|
||||
require_cmd sgdisk
|
||||
require_cmd partprobe
|
||||
require_cmd blkid
|
||||
require_cmd dmsetup
|
||||
require_cmd parted
|
||||
|
||||
[[ "$(id -u)" -eq 0 ]] || die "请使用 root 执行"
|
||||
|
||||
[[ -b "${DISK}" ]] || die "磁盘不存在: ${DISK}"
|
||||
|
||||
echo "======================================================"
|
||||
echo "即将彻底清空 ${DISK} 并挂载到 ${MOUNT_POINT}"
|
||||
echo "目标 VG: ${NEW_VG}"
|
||||
echo "目标 LV: ${NEW_LV}"
|
||||
echo "文件系统: ${FS_TYPE}"
|
||||
echo "警告: 此操作会销毁 ${DISK} 上所有数据"
|
||||
echo "======================================================"
|
||||
read -r -p "确认执行请输入 YES: " ans
|
||||
[[ "${ans}" == "YES" ]] || die "用户取消"
|
||||
|
||||
stop_docker
|
||||
cleanup_mounts_on_disk
|
||||
deactivate_old_lvm
|
||||
wipe_disk
|
||||
prepare_mountpoint
|
||||
create_new_lvm
|
||||
start_docker
|
||||
|
||||
log "完成: ${DISK} -> /dev/${NEW_VG}/${NEW_LV} -> ${MOUNT_POINT}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user