En corto

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Receptor preparado para reanudar: -s en el recv
zfs send -v -w tank/data@snap1 | ssh backup-host zfs recv -s backup/data

# Se cortó. En el receptor, pide el token:
zfs get -H -o value receive_resume_token backup/data

# En el emisor, retoma desde ese punto (sin nombrar dataset ni snapshot: el token lo lleva todo):
zfs send -v -t 1-d4f61d893-c0-789c636064000310a500c4ec50360710e72765a5… | ssh backup-host zfs recv -s backup/data

# Rendirse y liberar lo recibido a medias:
zfs recv -A backup/data

Funciona igual con envíos incrementales (-i / -I) y con envíos raw de datasets cifrados (-w).

Por qué

Sin -s, un zfs recv interrumpido descarta todo lo que había recibido: horas de transferencia a la basura por un corte de red o un reinicio. Con -s (OpenZFS desde 2017; Linux 0.7+, FreeBSD 12+) el receptor conserva el trozo recibido en un dataset oculto (backup/data/%recv) y expone la propiedad receive_resume_token.

El token es la descripción completa de lo que falta: identifica el snapshot origen, el objeto y el offset donde se quedó, y las opciones del stream (raw, comprimido, bloques grandes…). Por eso zfs send -t no necesita más argumentos y por eso no hace falta acordarse de qué flags llevaba el send original: se reconstruyen desde el token.

Paso a paso

  1. Recibe siempre con -s. No cuesta nada y es lo único que hay que recordar antes del corte.

  2. Tras la interrupción, en el receptor:

    1
    
    zfs get -H -o value receive_resume_token backup/data
    

    Si devuelve -, no hay estado parcial (el envío terminó o nunca empezó).

  3. En el emisor, zfs send -t <token> con la misma tubería de siempre hacia zfs recv -s. Puedes cortarlo y retomarlo tantas veces como haga falta; cada vez el token cambia.

  4. Comprueba el final: zfs get receive_resume_token vuelve a - y el snapshot aparece en zfs list -t snapshot -r backup/data.

Para ver el progreso, -v en el send (bytes enviados) o pv en medio; para amortiguar latencia en enlaces lentos, mbuffer entre send y ssh.

Abortar

1
zfs recv -A backup/data

Borra el %recv y libera el espacio. Necesario cuando el token ya no sirve (abajo) o cuando decides reenviar desde otro snapshot.

Con syncoid

syncoid usa recv -s y los tokens por su cuenta: si un envío se corta, la siguiente ejecución lo retoma sola. --no-resume lo desactiva si alguna vez estorba. Sanoid + syncoid son la forma cómoda de hacer esto en producción.

Trampas

  • Destruir el snapshot origen invalida el token. Si tu política de snapshots (o zfs destroy a mano) se lleva @snap1 a medio envío, el send -t falla: zfs recv -A y empieza desde un snapshot que exista. Un hold sobre el snapshot que estás enviando evita el problema.
  • Los dos extremos tienen que soportarlo: OpenZFS moderno en ambos. Solaris e Illumos antiguos no entienden -s.
  • -w se conserva en el token: un envío raw reanudado sigue siendo raw; no intentes mezclar un send -t con un recv de destino distinto del original.
  • Mientras hay estado parcial, zfs destroy del dataset destino se queja: primero recv -A.
  • Streams -R (paquetes con varios snapshots) también se reanudan, pero es más simple enviar snapshot por snapshot con -i, que es lo que hace syncoid.

Ver también