Problemas en VMWARE con CBT

Introducción

 

Las APIs de VMWare para hacer copias de seguridad se apoyan en un mecanismo que registra los bloques de disco cambiados (Changed Block Tracking o CBT). Se han detectado en varias ocasiones problemas con este mecanismo en los que si no funciona bien puede hacer que nuestras copias de seguridad no sean válidas.

 

Aunque estos problemas se detectan y solucionan rápidamente, puede ser interesante tomar ciertas medidas para prevenir que uno de estos fallos nos afecte. Por ejemplo, uno de los casos detectados de fallo en el funcionamiento del CBT es el siguiente:

 

QueryChangedDiskAreas API returns incorrect sectors after extending virtual machine VMDK file with Changed Block Tracking (CBT) enabled (2090639)

 

Este fallo puede ocurrir cuando se expande un disco virtual por encima de cierto límite. Esto puede afectar a que no se reporten correctamente los bloques de discos cambiados al sistema de copias de seguridad y nuestra copia de seguridad no sea consistente y nos falten datos.

 

 

Medidas de prevención

 

En este caso concreto, el fallo se puede producir cuando se amplia el volumen cumpliendo ciertas condiciones. Una opción para prevenir este problema es regenerar el CBT siempre que se amplíen un disco de nuestra máquina virtual. El procedimiento para regenerar el CBT es el siguiente:

 

  • Desactivar el CBT
  • Hacer un snapshot
  • Borrar el snapshot
  • Hacer una nueva copia de seguridad

 

Estas tareas se pueden hacer manualmente o programadas con un script similar al siguiente:

 

Obtener las máquinas con CBT habilitado:

$vms=get-vm | ?{$_.ExtensionData.Config.ChangeTrackingEnabled -eq $true}
 
Crear una configuración de VM deshabilitando el CBT:
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.ChangeTrackingEnabled = $false
 
Aplicar la configuración a la máquina virtual, crear y borrar un snapshot:
foreach($vm in $vms){ 
$vm.ExtensionData.ReconfigVM($spec) 
$snap=$vm | New-Snapshot -Name 'Disable CBT' 
$snap | Remove-Snapshot -confirm:$false}
 
Chequear que todo ha ido bien:
get-vm | ?{$_.ExtensionData.Config.ChangeTrackingEnabled -eq $true}

 

Hay que tener en cuenta que si se tiene la versión 7.7.2 de Netbackup puede ser de aplicación la siguiente nota técnica:

 

After upgrading to NetBackup 7.7.2, VMware CBT calls are not honored causing BLIB

 

Por otro lado, se podrían automatizar estas tareas con scripts más complejos como los que figuran a modo de ejemplo al final del artículo, que se podría programar antes de la copia de seguridad completa, y lo que hace es lo siguiente:

 

  • Recorrer todas las máquinas de nuestro virtual center
  • Suma el tamaño de sus discos. Si esta suma no es igual a la de la última ejecución, para esa máquina se aplica el procedimiento de regeneración del fichero de CBT
  • Para las máquinas que no han cambiado de tamaño sus discos aplica el procedimiento a un máximo de X máquinas (en este ejemplo 5) para las cuales no se haya cambiado en Y días (60 en este caso). De esta forma, periódicamente se va regenerando el fichero de CBT para todas las máquinas de nuestra infraestructura y poco a poco para no suponer gran carga extra en nuestra infraestructura de copias de seguridad y almacenamiento.

 

Además de estos consejos, es imprescindible las pruebas de restauración periódicas para poder detectar cualquier posible problema de forma preventiva, así como aplicar las buenas prácticas sobre copias de seguridad en VMWare y creación de planificaciones con la opción de Force Rescan habilitado de forma periódica.

 

 

Referencias

 

Changed Block Tracking (CBT) on virtual machines (1020128)

Enabling or disabling Changed Block Tracking (CBT) on virtual machines (1031873)

After resizing the virtual disk, there is a potential for data loss when backing up VMware clients with NetBackup using Changed Block Tracking (CBT)

 

 

Scripts de ejemplo

 

Mi más sincero agradecimiento a Juan Benjumea por crear y proporcionarme los siguientes scripts como muestra. Para que funcionen correctamente es necesario crear los siguientes campos personalizados en el virtual center:

 

  • CBT_RESET: Almacena la fecha de la última vez que se ha regenerado el CBT
  • VM_SIZE_DISK_GB: Contiene la suma de GB de todos los discos virtuales

 

Hay dos scripts, un primer script que rellena el tamaño de los discos (campo VM_SIZE_DISK_FB) y toma como parámetro el nombre del Virtual Center. Sólo hay que ejecutarlo la primera vez:

 

[void](Get-PSSnapin VMWare.VimAutomation.Core -ErrorVariable getVmwareSnapinErr 2> $null)
if ($getVmwareSnapinErr.Count -gt 0) {    Add-PSSnapin VMware.VimAutomation.Core }

Write-Host $args[0]
Connect-VIServer -server $args[0]
# Inicializamos variables
$VMs = Get-VM *
$Data = @()
 

 foreach ($VM in $VMs){
  
 $VMDKs = $VM | get-HardDisk
 $CapacityGBTOTAL = 0
 $into = New-Object PSObject
 
 foreach ($VMDK in $VMDKs) {
 
  if ($VMDK -ne $null){
   $CapacityGB = $VMDK.CapacityKB/1024/1024
   $CapacityGB = [int]$CapacityGB
  $CapacityGBTOTAL = ($CapacityGBTOTAL + $CapacityGB)

  }
  
 }
 get-vm $VM | Set-Annotation -CustomAttribute VM_SIZE_DISK_GB -value $CapacityGBTOTAL
 Add-Member -InputObject $into -MemberType NoteProperty -Name VMname $VM.Name
 Add-Member -InputObject $into -MemberType NoteProperty -Name CapacityGB $CapacityGBTOTAL
 
   
 $Data += $into
 $Data | Sort-Object VMname,VMDK | Export-Csv -Path C:\temp\VM-VMDKs-SIZE.csv -NoTypeInformation
 
   }
Disconnect-VIServer -Confirm:$False

 

Y un segundo script que se recorre todas las máquinas virtuales, regenera el CBT en las máquinas en las que se ha ampliado el disco y además 5 máquinas virtuales más en cada ejecución siempre que no haga 60 días que ya se ha cambiado (estos números habrá que cambiarlos en cada infraestructura dependiendo del número de máquinas virtuales). Hay que pasar como parámetro el nombre del Virtual Center:

 

[void](Get-PSSnapin VMWare.VimAutomation.Core -ErrorVariable getVmwareSnapinErr 2> $null)
if ($getVmwareSnapinErr.Count -gt 0) {    Add-PSSnapin VMware.VimAutomation.Core }

Write-Host $args[0]
Connect-VIServer -server $args[0]

# Inicializamos variables
$VMs = Get-VM | ?{$_.ExtensionData.Config.ChangeTrackingEnabled -eq $true}
$Data = @()
$VMPROC = [int]$VMPROC
$VMPROC = 0
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.ChangeTrackingEnabled = $false
$date = Get-Date
$datetxt = Get-Date $date -Format dd/MM/yy
 foreach ($VM in $VMs){
  $reset = “NO”
 $VMDKs = $VM | get-HardDisk
 $CapacityGBTOTAL = 0
 $into = New-Object PSObject
 
 #Sumamos el valor de los discos de cada VM
 foreach ($VMDK in $VMDKs) {
 
  if ($VMDK -ne $null){
   $CapacityGB = $VMDK.CapacityKB/1024/1024
   $CapacityGB = [int]$CapacityGB
   $CapacityGBTOTAL = ($CapacityGBTOTAL + $CapacityGB)
  }

 }
 Add-Member -InputObject $into -MemberType NoteProperty -Name VMname $VM.Name
 Add-Member -InputObject $into -MemberType NoteProperty -Name CapacityGB $CapacityGBTOTAL
 
 #Compara el tamaño actual de los discos con el del valor ya existente en el campo VM_SIZE_DISK_GB y si es diferente ejecuta el disable CBT
 
 $VM_SIZE_DISK_GB_OLD = (Get-VM $VM).CustomFields.Item{VM_SIZE_DISK_GB}
 $fechatxt = (Get-VM $VM).CustomFields.Item{CBT_RESET}
 $fechacsv = $fechatxt
 
 
 
 if (($VM_SIZE_DISK_GB_OLD -ne $CapacityGBTOTAL)-or ($fechatxt -eq “”)) {
 

  $vm.ExtensionData.ReconfigVM($spec)
  $snap=$vm | New-Snapshot -Name ‘Disable CBT’
  $snap | Remove-Snapshot -confirm:$false
  get-vm $VM | Set-Annotation -CustomAttribute VM_SIZE_DISK_GB -value $CapacityGBTOTAL
  get-vm $VM | Set-Annotation -CustomAttribute CBT_RESET -value $datetxt
  $VMPROC = $VMPROC + 1
  $reset = “YES”
  $fechacsv = $datetxt
  }
 #Compara la fecha actual con el del valor del campo CBT_RESET
 # y si la diferencia es mayor a 60 dias anteriores a la fecha actual ejecuta el disable CBT si no se ha realizado ya en 5 maquinas
 
 if ($VMPROC -lt “5”) {
 
  if ($VM_SIZE_DISK_GB_OLD -eq $CapacityGBTOTAL) {
  
   $fechatxt = (Get-VM $VM).CustomFields.Item{CBT_RESET}
   $fecha = Get-Date $fechatxt
   
   if ($fecha.adddays(60) -le $date)  {
  
    $vm.ExtensionData.ReconfigVM($spec)
    $snap=$vm | New-Snapshot -Name ‘Disable CBT’
    $snap | Remove-Snapshot -confirm:$false
    get-vm $VM | Set-Annotation -CustomAttribute CBT_RESET -value $datetxt
    $VMPROC = $VMPROC + 1
    $reset = “YES”
    $fechacsv = $datetxt
   }
  }
 }
 Add-Member -InputObject $into -MemberType NoteProperty -Name Reset $reset
 Add-Member -InputObject $into -MemberType NoteProperty -Name Date $fechacsv
  
 $Data += $into
 $Data | Sort-Object VMname,VMDK,Reset,Date | Export-Csv -Path C:\temp\VM-VMDKs.csv -NoTypeInformation
 
  
}
Disconnect-VIServer -Confirm:$False

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *