- 출처 / 참고: VMware Broadcom Knowledge Base (Investigating virtual machine file locks on ESXi - KB 10051, Virtual machine consolidation fails with error: The file is locked - KB 2107795)
명령어:
vmkfstools,lsof,voma,grep,awk,hexdump
키워드: Virtual machine disks consolidation failed, File is locked, vmkfstools -D, VMFS lock, MAC address, Backup Proxy, hostd, vpxa
사용처: vSphere 환경에서 스냅샷 디스크 통합 중 ‘파일이 잠겨 있습니다’ 오류로 작업 실패 시 락을 쥐고 있는 호스트 및 프로세스 강제 해제
실행예제
vSphere Client에서 가상 머신 디스크 통합(Consolidate) 작업 실행 시 가상 시스템 디스크를 통합하지 못했습니다. 파일이 잠겨 있습니다(The file is locked) 오류가 발생했을 때, 해당 VMDK(또는 델타 sesparse) 파일을 배타적으로 잠그고 있는 ESXi 호스트의 MAC 주소와 프로세스를 추적하는 과정입니다.
# 1. 대상 가상 머신의 vmware.log에서 파일 잠금 실패 내역 확인
$ tail -n 30 /vmfs/volumes/datastore1/App-Server-01/vmware.log | grep -i "locked"
# [출력 예시]
# DISKLIB-VMFS : VmfsDiskOpen: Open of "/vmfs/volumes/datastore1/App-Server-01/App-Server-01-000002-sesparse.vmdk" failed with error: File is locked.
# SNAPSHOT: SnapshotConsolidate failed: File is locked (16390).
# 2. vmkfstools -D 명령어를 사용하여 잠긴 VMDK의 VMFS 분산 락(Lock) 정보 덤프
$ cd /vmfs/volumes/datastore1/App-Server-01/
$ vmkfstools -D App-Server-01-000002-sesparse.vmdk
# [출력 예시 - vmkernel.log 에 출력됨]
# Lock [type 10c00001 offset 48512000 v 312, hb offset 3854336
# gen 15, mode 1, owner 652a1b20-84dc-11ee-8204-e4434b123456]
# -> mode 1 은 배타적 읽기/쓰기 락(Exclusive Lock)을 의미하며, owner의 마지막 12자리가 락을 잡은 ESXi 호스트의 물리 NIC MAC 주소임 (e4:43:4b:12:34:56)
# 3. vmkernel.log에서 락 소유자(Lock Owner) 상세 내용 실시간 확인
$ tail -n 20 /var/log/vmkernel.log | grep -A 2 -i "Lock \[type"
# 2026-10-24T14:15:20.123Z cpu4:2098451)FS3: 312: Lock [type 10c00001 offset 48512000 v 312, hb offset 3854336
# gen 15, mode 1, owner 652a1b20-84dc-11ee-8204-e4434b123456]
# 4. 락 소유자 MAC 주소(e4:43:4b:12:34:56)를 가진 호스트가 로컬 호스트인지 확인
$ esxcli network nic list
# Name PCI Device Driver Admin Status Link Status Speed Duplex MAC Address
# vmnic0 0000:01:00.0 ixgben Up Up 10000 Full e4:43:4b:12:34:56
# -> MAC 주소가 일치하면 '현재 로컬 ESXi 호스트'의 특정 데몬/VM이 물고 있는 상태임
# 5. 로컬 호스트 내부에서 해당 VMDK 파일을 물고 있는 프로세스(World ID) 조회
$ lsof | grep "App-Server-01-000002-sesparse.vmdk"
# [출력 예시]
# 2104523 vmx-vthread 12 /vmfs/volumes/datastore1/App-Server-01/App-Server-01-000002-sesparse.vmdk
# -> 2104523 프로세스(백업 솔루션 프록시 가상 머신)가 파일을 열어둔 채 닫지 않음
스크립트
잠겨 있는 VMDK 파일명을 인자로 받아 vmkfstools -D를 호출하여 락 소유자(MAC 주소)를 추출하고, 로컬 호스트 소유 여부 판별 및 로컬 호스트인 경우 해당 파일을 열고 있는 World ID(프로세스)를 식별해 주는 진단 쉘 스크립트입니다.
#!/bin/sh
# trace_vmdk_lock.sh - Identify Lock Owner and World ID for locked VMDKs on ESXi
TARGET_VMDK=${1:-""}
echo "=========================================="
echo " [VMware ESXi VMDK 파일 잠금(Lock) 추적기]"
echo "=========================================="
if [ -z "$TARGET_VMDK" ] || [ ! -f "$TARGET_VMDK" ]; then
echo " [오류] 잠긴 VMDK 파일의 전체 경로를 지정하십시오."
echo " 사용법: $0 /vmfs/volumes/.../vm_name-000001-sesparse.vmdk"
exit 1
fi
echo " 대상 디스크 파일: ${TARGET_VMDK}"
# 1. vmkfstools -D 실행하여 vmkernel.log로 덤프 유도
vmkfstools -D "$TARGET_VMDK" >/dev/null 2>&1
# 2. vmkernel.log에서 방금 찍힌 Lock owner 정보 파싱
LOCK_LOG=$(tail -n 30 /var/log/vmkernel.log | grep -A 1 "Lock \[type" | tail -n 2)
LOCK_OWNER=$(echo "$LOCK_LOG" | grep -oE "owner [0-9a-f\-]+" | awk '{print $2}')
LOCK_MODE=$(echo "$LOCK_LOG" | grep -oE "mode [0-9]+" | awk '{print $2}')
if [ -z "$LOCK_OWNER" ]; then
echo " [알림] VMFS 잠금 정보를 찾을 수 없습니다. (파일이 잠겨 있지 않거나 로그 순환됨)"
exit 0
fi
echo -e "\n[1] VMFS 파일 락 메타데이터:"
echo " - 락 모드(Lock Mode) : ${LOCK_MODE} (1: Exclusive Lock 배타적 잠금)"
echo " - 소유자 UUID : ${LOCK_OWNER}"
# 소유자 UUID의 마지막 12자리가 관리 호스트 NIC MAC 주소임
OWNER_MAC_RAW=$(echo "$LOCK_OWNER" | awk -F'-' '{print $NF}')
FORMATTED_MAC=$(echo "$OWNER_MAC_RAW" | sed 's/../&:/g;s/:$//')
echo " - 락 소유 호스트 MAC : ${FORMATTED_MAC}"
# 3. 로컬 ESXi 호스트의 MAC 목록과 대조
LOCAL_MATCH=$(esxcli network nic list 2>/dev/null | grep -i "$FORMATTED_MAC")
echo -e "\n[2] 호스트 위치 판별:"
if [ -n "$LOCAL_MATCH" ]; then
echo " [식별] 락 소유자는 '현재 로컬 ESXi 호스트'입니다."
# 4. 로컬 프로세스(World ID) 추적
echo -e "\n[3] 파일 점유 프로세스(World ID) 탐색:"
LOCKING_PROC=$(lsof 2>/dev/null | grep "$TARGET_VMDK")
if [ -n "$LOCKING_PROC" ]; then
echo " [발견] 파일을 점유 중인 프로세스:"
echo "$LOCKING_PROC" | sed 's/^/ /'
WID=$(echo "$LOCKING_PROC" | awk '{print $1}')
# 프로세스 이름 및 가상 머신 매핑
VM_NAME=$(esxcli vm process list 2>/dev/null | grep -B 2 "World ID: $WID" | grep "Display Name:" | awk -F': ' '{print $2}')
if [ -n "$VM_NAME" ]; then
echo " -> 가상 머신: [${VM_NAME}] 가 해당 디스크를 HotAdd 등으로 마운트 중입니다."
echo " -> 조치: [${VM_NAME}] 가상 머신 설정 편집에서 해당 디스크를 '제거(Remove)'하십시오."
fi
else
echo " - lsof로 단일 프로세스를 특정하지 못했습니다. hostd 또는 vpxa 데몬 점유 가능성."
echo " -> 조치: '/etc/init.d/hostd restart && /etc/init.d/vpxa restart' 권장."
fi
else
echo " [주의] 락 소유자는 클러스터 내 '다른 ESXi 호스트'(${FORMATTED_MAC})입니다."
echo " -> 조치: 해당 MAC 주소를 가진 ESXi 호스트를 찾아 그 호스트에서 VM/프로세스를 정리해야 합니다."
fi
echo -e "\n=========================================="
echo " [진단 완료]"
echo "=========================================="
해설
가상 머신 디스크 통합(Consolidation)은 스냅샷 델타 디스크에 기록된 변경 블록들을 읽어 베이스 VMDK 디스크에 반영하는 작업입니다. 이때 통합 대상 디스크 파일 중 하나라도 다른 프로세스나 다른 ESXi 호스트에 의해 배타적 락(Exclusive Lock, Mode 1)으로 잠겨 있으면, ESXi의 VMFS 파일시스템 드라이버는 데이터 정합성 보호를 위해 작업을 거부하고 The file is locked 에러를 반환합니다.
1. 주요 발생 원인
- 백업 솔루션(Veeam, Commvault, Avamar 등) 가상 어플라이언스의 HotAdd 잠금:
- 백업 솔루션이 스냅샷 데이터를 네트워크가 아닌 스토리지 레벨에서 고속 백업하기 위해, 백업 프록시 VM의 가상 SCSI 컨트롤러에 대상 VM의 델타 디스크(
*-000001.vmdk)를 직접 연결(HotAdd)합니다. - 백업 작업이 완료되거나 타임아웃 오류로 비정상 중단되었을 때, 프록시 VM에서 디스크 연결을 분리(Detach)하지 못하고 물고 있으면 해당 디스크는 백업 VM에 종속되어 영구 잠금 상태가 됩니다.
- 백업 솔루션이 스냅샷 데이터를 네트워크가 아닌 스토리지 레벨에서 고속 백업하기 위해, 백업 프록시 VM의 가상 SCSI 컨트롤러에 대상 VM의 델타 디스크(
- ESXi 호스트 간 분산 락(Distributed Lock) 해제 누락:
- VM이 vMotion으로 다른 호스트로 마이그레이션되었거나 HA에 의해 페일오버되었을 때, 이전 ESXi 호스트의
hostd프로세스가 VMFS 메타데이터 하트비트(Heartbeat) 락을 제때 반환하지 않고 유지하는 경우.
- VM이 vMotion으로 다른 호스트로 마이그레이션되었거나 HA에 의해 페일오버되었을 때, 이전 ESXi 호스트의
- vCenter/ESXi 관리 에이전트(
hostd,vpxa)의 행(Hang) 상태:- 스냅샷 삭제 스레드가 죽었거나 데몬이 응답하지 않아 내부 핸들이 닫히지 않은 경우.
2. 단계별 복구 및 해결 방법
1) 백업 프록시 VM의 디스크 수동 분리 (가장 빈번한 해결책)
- 백업 프록시 가상 머신(예:
Veeam-Proxy-01)의 가상 시스템 설정 편집(Edit Settings)으로 들어갑니다. - 하드 디스크 목록 중 잠금 오류를 일으킨 대상 VM의 디스크 경로(예:
[datastore1] App-Server-01/App-Server-01-000002.vmdk)가 연결되어 있는지 확인합니다. - 해당 하드 디스크의 제거 아이콘(X)을 누르고, 반드시 “가상 시스템에서 제거(디스크 파일은 삭제하지 않음)”를 선택하여 분리합니다.
- 분리 완료 후 대상 VM에서 다시
통합(Consolidate)을 실행합니다.
2) ESXi 관리 데몬 재시작 (로컬 호스트 잠금 시)
파일을 잡고 있는 별도 VM이 없는데도 락이 풀리지 않는다면, 관리 에이전트를 재시작하여 캐시된 파일 디스크립터를 강제로 비웁니다 (현재 호스트에서 돌고 있는 다른 가상 머신들의 서비스에는 영향 없음).
# hostd 및 vpxa 데몬 재시작
/etc/init.d/hostd restart
/etc/init.d/vpxa restart
3) 대상 가상 머신 전원 재인가 (Power Cycle)
만약 대상 VM 자체의 vmx 프로세스가 이전 스냅샷 델타 포인터를 잘못 물고 있는 경우라면, VM을 정상 종료(Guest Shutdown)한 후 완전히 꺼진 상태에서 디스크 통합을 실행하면 락 충돌 없이 100% 깔끔하게 병합됩니다.
4) vMotion을 이용한 호스트 강제 전환
디스크 락을 쥔 이전 ESXi 호스트와 현재 호스트 간 메타데이터 동기화가 꼬인 경우, 해당 VM을 클러스터 내 다른 ESXi 호스트로 Compute Only vMotion 시키면 VMFS 드라이버가 락 소유권을 새로운 호스트로 강제 이전 및 갱신하면서 고아 락이 풀립니다.
주의사항
- 백업 프록시 VM에서 디스크 분리 시 ‘디스크 삭제’ 선택 절대 금지:
- 백업 프록시 가상 머신에서 마운트된 디스크를 분리할 때 옵션을 잘못 보고
데이터스토어에서 파일 삭제(Delete files from datastore)를 체크하면 원본 운영 VM의 스냅샷 델타 파일 자체가 영구 삭제되어 운영 데이터가 유실됩니다. 반드시 단순 분리(Remove from virtual machine) 옵션인지 확인해야 합니다.
- 백업 프록시 가상 머신에서 마운트된 디스크를 분리할 때 옵션을 잘못 보고
- 통합 재시도 전 데이터스토어 남은 용량 체크:
- 락을 풀고 통합을 다시 돌릴 때, 델타 파일들의 합산 크기가 수십 GB 이상이라면 데이터스토어에 최소 수 GB 이상의 여유 공간이 있어야 임시 블록 스왑이 가능합니다. 용량이 100%에 도달하면 통합 작업이 실패하면서 가상 머신 전체가 일시 중지(Suspend)될 수 있습니다.
vmkfstools -L등의 강제 락 해제 명령 지양:- 내부적인 VMFS 메타데이터를 강제로 수정하는 비공식 명령어를 사용하면 공유 스토리지 볼륨의 메타데이터 블록이 손상되어 동일 데이터스토어에 있는 모든 VM의 디스크가 인식이 안 되는 치명적 참사(Metadata Corruption)가 발생할 수 있습니다. 정상적인 데몬 재시작이나 마운트 분리 절차로 해결해야 합니다.