Xử lý lỗi APD và PDL trong VMware vSphere: Phân biệt và khắc phục All Paths Down, Permanent Device Loss

VMware tutorial - IT technology blog
VMware tutorial - IT technology blog

2 giờ sáng, điện thoại rung lên. Alert từ vCenter báo hàng loạt VM đang Not Responding. Mình vào console, datastore chuyển màu vàng, log vmkernel đỏ rực. Đây là kịch bản mình đã gặp ba lần trong mấy năm quản lý cluster VMware với 8 host ESXi tại công ty — và mỗi lần như vậy, câu hỏi đầu tiên luôn là: đây là APD hay PDL?

Hai trạng thái này trông giống nhau ngoài mặt — VM đứng hình, I/O timeout, storage không accessible — nhưng nguyên nhân và cách xử lý hoàn toàn khác. Nhầm giữa hai cái có thể tốn thêm cả tiếng đồng hồ, tệ hơn là làm hỏng data.

APD và PDL khác nhau chỗ nào?

All Paths Down (APD)

APD xảy ra khi tất cả đường dẫn (path) từ ESXi host đến storage device đều bị mất, nhưng ESXi chưa xác định được đây là tạm thời hay vĩnh viễn. Host giữ nguyên I/O queue, tiếp tục retry, và đặt device vào trạng thái “APD timeout” sau đúng 140 giây mặc định.

Nguyên nhân thường gặp:

  • Cáp FC bị đứt, SFP hỏng, switch SAN restart đột ngột
  • iSCSI network gián đoạn (VLAN misconfiguration, NIC flap)
  • Storage array tạm thời offline do maintenance không báo trước
  • Zoning thay đổi trên FC switch

Permanent Device Loss (PDL)

PDL nặng hơn APD một bậc. Storage array gửi lại SCSI sense code xác nhận thiết bị không còn tồn tại — cụ thể là sense code 0x05/0x25 (logical unit not supported) hoặc 0x02/0x3a (medium not present). ESXi nhận tín hiệu rõ ràng này và biết ngay: mất vĩnh viễn, không cần chờ timeout.

Các tình huống dẫn đến PDL:

  • LUN bị xóa hoặc unmapped trực tiếp trên storage array
  • Storage array failover không hoàn chỉnh
  • Disk group trên vSAN bị lỗi toàn bộ
  • HBA driver crash khiến device bị detach ở kernel level

So sánh nhanh

  • APD: Chưa rõ tạm thời hay vĩnh viễn — ESXi chờ 140s rồi vào timeout state, VM bị treo (hung), có thể tự phục hồi khi connectivity quay lại
  • PDL: Xác nhận vĩnh viễn ngay qua SCSI sense code — phản hồi tức thì, VM nhận I/O error, cần can thiệp thủ công để recovery

Xác định bạn đang gặp APD hay PDL

Đừng đoán mò. SSH vào ESXi host bị ảnh hưởng và chạy ngay các lệnh sau:

# Kiểm tra trạng thái path đến storage device
esxcli storage nmp path list | grep -A5 "State"

# Tìm APD/PDL events trong vmkernel log
grep -i "APD\|PDL\|permanent device\|all paths down" /var/log/vmkernel.log | tail -50

# Kiểm tra trạng thái device cụ thể
esxcli storage nmp device list

# Xem SCSI sense codes (quan trọng để phân biệt PDL)
grep -i "H:0x0 D:0x2 P:0x0 Valid sense\|sense data" /var/log/vmkernel.log | tail -20

Song song đó, mở vCenter Event Log và lọc theo host bị ảnh hưởng. APD sẽ có event esx.problem.storage.apd.start, còn PDL sẽ có esx.problem.storage.permanentDeviceLoss.set. Thấy cái nào là biết ngay.

Xử lý APD

Bước 1: Kiểm tra kết nối vật lý

Trước khi đụng vào phần mềm, kiểm tra phần cứng trước. Mình từng mất 20 phút troubleshoot trên CLI rồi mới phát hiện ra người vận hành datacenter vô tình rút nhầm cáp FC. Bài học đắt giá.

# Kiểm tra HBA port status
esxcli storage san fc list

# Với iSCSI, kiểm tra kết nối network
esxcli iscsi adapter list
esxcli iscsi session list

# Ping storage IP từ VMkernel interface
vmkping -I vmk1 192.168.10.50

Bước 2: Rescan storage adapters

Kết nối vật lý đã ổn? Rescan để ESXi rediscover lại các path:

# Rescan tất cả storage adapter
esxcli storage core adapter rescan --all

# Hoặc rescan adapter cụ thể (ví dụ vmhba1)
esxcli storage core adapter rescan --adapter vmhba1

Sau rescan, VM thường tự resume nếu kết nối đã được khôi phục. Không cần restart VM.

Tùy chỉnh APD timeout và response

Mặc định ESXi chờ 140 giây trước khi vào APD timeout. Sau đó, HA có thể tự động power off VM đang hung — thay vì để VM treo vô thời hạn. Cấu hình qua PowerCLI:

# Kết nối vCenter
Connect-VIServer -Server vcenter.company.com

# Bật APD handling trên tất cả host trong cluster
# Khi APD timeout, HA được phép power off VM hung thay vì chờ vô thời hạn
$cluster = Get-Cluster "Production-Cluster"
Get-VMHost -Location $cluster | ForEach-Object {
    $esxHost = $_
    Get-AdvancedSetting -Entity $esxHost -Name "Disk.APDHandlingEnable" |
        Set-AdvancedSetting -Value 1 -Confirm:$false
    Write-Host "APD handling enabled on $($esxHost.Name)"
}

Xử lý PDL

PDL khó chịu hơn nhiều vì VM không bao giờ tự phục hồi. Đồng nghiệp mình từng vô tình xóa nhầm LUN trên NetApp trong lúc maintenance — 12 VM rơi vào PDL ngay lập tức, không cái nào boot được. Phải mất gần 3 tiếng để recovery toàn bộ.

Bước 1: Xác định VM bị ảnh hưởng

# Tìm VM đang bị ảnh hưởng bởi PDL
Get-VM | Get-View | Where-Object {
    $_.Runtime.ConnectionState -eq "inaccessible" -or
    ($_.Runtime.PowerState -eq "poweredOn" -and
    $_.Runtime.ConnectionState -eq "disconnected")
} | Select-Object Name, @{N="ConnectionState";E={$_.Runtime.ConnectionState}}

Bước 2: Force power off VM bị hung

VM trong trạng thái PDL không thể shutdown bình thường. Phải dùng kill:

# SSH vào ESXi host đang chạy VM đó
# Tìm world ID của VM
esxcli vm process list

# Force kill VM (thay 12345 bằng world ID thực tế)
esxcli vm process kill --type=force --world-id=12345

# Nếu force không được, dùng hard kill
esxcli vm process kill --type=hard --world-id=12345

Bước 3: Khôi phục storage và re-register VM

Sau khi fix vấn đề storage (recreate LUN, remap, hoặc restore từ backup snapshot của storage array):

# Rescan để ESXi nhận diện lại datastore
esxcli storage core adapter rescan --all

# Kiểm tra datastore đã accessible chưa
esxcli storage vmfs extent list
# Re-register VM nếu nó bị removed khỏi inventory
$datastore = Get-Datastore "DS-Production-01"
$vmxFiles = Get-ChildItem -Path "vmstore:\datacenter\$($datastore.Name)" -Recurse -Filter "*.vmx"

foreach ($vmx in $vmxFiles) {
    $resourcePool = Get-ResourcePool "Resources" -Location (Get-Cluster "Production-Cluster")
    New-VM -VMFilePath $vmx.DatastoreFullPath -ResourcePool $resourcePool
    Write-Host "Registered: $($vmx.Name)"
}

Script monitoring để phát hiện sớm

Ba lần bị đánh thức lúc 2 giờ sáng là đủ. Mình viết script này chạy mỗi 5 phút qua Task Scheduler — gửi cảnh báo trước khi sự cố leo thang:

# apd-pdl-monitor.ps1 — chạy mỗi 5 phút qua Task Scheduler hoặc cron
Connect-VIServer -Server vcenter.company.com -User admin -Password $env:VC_PASS

$alerts = @()

# Kiểm tra tất cả datastore
Get-Datastore | ForEach-Object {
    $ds = $_
    if ($ds.State -ne "Available") {
        $alerts += "[CRITICAL] Datastore '$($ds.Name)' state: $($ds.State)"
    }

    # Kiểm tra host mount status
    $ds.ExtensionData.Host | ForEach-Object {
        $mountInfo = $_.MountInfo
        if (-not $mountInfo.Accessible) {
            $alerts += "[CRITICAL] Datastore '$($ds.Name)' inaccessible on host $($_.Key)"
        }
    }
}

# Kiểm tra VM disconnected
Get-VM | Where-Object {$_.ExtensionData.Runtime.ConnectionState -eq "inaccessible"} | ForEach-Object {
    $alerts += "[WARNING] VM '$($_.Name)' is inaccessible — possible APD/PDL"
}

if ($alerts.Count -gt 0) {
    $body = $alerts -join "`n"
    # Gửi email hoặc webhook Slack/Teams
    Send-MailMessage -To "[email protected]" -Subject "vSphere Storage Alert" -Body $body -SmtpServer "smtp.company.com"
    Write-Host $body
}

Disconnect-VIServer -Confirm:$false

Bài học từ những đêm trực sự cố

Qua những lần đó, mình rút ra bốn việc cần làm ngay khi storage có vấn đề:

  1. Không restart ESXi host ngay — phản xạ tự nhiên nhưng sai. Restart host đang có VM chạy là rủi ro mất thêm data.
  2. Đọc vmkernel.log trước — 5 phút đọc log tiết kiệm 2 tiếng troubleshoot mù quáng.
  3. Phân biệt APD/PDL trước khi hành động — APD có thể tự giải quyết, PDL thì không. Chờ sai chỗ là mất thời gian.
  4. Cấu hình HA/APD response trong vSphere HA — vào Cluster Settings → vSphere HA → Advanced Options, đặt das.config.fdm.apd.timeout theo nhu cầu để HA tự handle khi bạn đang ngủ.

Và điều căn bản nhất: multipath phải được cấu hình đúng từ đầu. Một LUN một path là APD đang chờ xảy ra. Tối thiểu cần 2 path độc lập — lý tưởng là 4 (2 HBA × 2 fabric).

Share: