¿Cómo puedo hacer una copia completa del contenido de un sistema de archivos btrfs? Por copia completa me refiero no solo a los datos actuales , sino también a diferentes subvolúmenes con sus instantáneas , idealmente preservando sus estructuras de CoW (es decir, no duplicando bloques con el mismo contenido).
Parece que una copia a nivel de bloque (como con dd
) no es una buena idea, ya que duplica el UUID, y aparentemente no hay una manera de cambiarlo fácilmente .
No he encontrado ninguna solución preparada hasta el día de hoy (2016-05-06), pero resolví el problema para mis propósitos, incluido el manejo de Copia en escritura. Los pasos para "clonar"
/source
a/target
son:Obtener una lista de subcaudales ordenados por
ogen
:btrfs subvolume list -qu --sort ogen /source
. La clasificación es probablemente suficiente para garantizar que las instantáneas o subvolúmenes que dependen de los anteriores se manejen primero. Esto es importante para tratar con Copiar en escritura, porque primero debemos transferir los volúmenes base.Haga que todos los subvolúmenes sean de solo lectura usando
btrfs property set -ts /source/some-volume ro true
.Ahora, para cada subvolumen de la lista anterior, comenzando en la parte superior, haga lo siguiente:
Si el volumen no tiene un UUID primario (mostrado como
-
) o el UUID primario ya no existe en la lista, ejecute:btrfs send /source/some/volume | btrfs receive /target/some/
Si el volumen tiene un UUID principal que todavía existe, ya deberíamos haberlo transferido
--sort ogen
y podemos usarlo como base para evitar la duplicación de datos. Por lo tanto, busque la ruta del UUID principal en la lista y ejecute:btrfs send -p /source/parent/volume/ -c /source/parent/volume/ /source/some/volume/ | btrfs receive /target/some/
(btrfs probablemente adivinará el-p
argumento automáticamente, pero prefiero ser explícito).Después de ejecutar uno de los comandos anteriores hacen que el destino y fuente de lectura y escritura de nuevo:
btrfs property set -ts /source/some/volume ro false; btrfs property set -ts /target/some/volume ro false
. Este paso se puede omitir si la fuente ha sido previamente de solo lectura.Esto debería manejar muchos casos. Advertencias:
Puede haber algunas complicaciones con respecto al pedido al anidar subvolúmenes / instantáneas.
Todo el proceso es obviamente más divertido cuando está programado.
btrfs send
acepta múltiples-c
argumentos de fuente de clonación ( ). Puede ser ventajoso no solo especificar la ruta de volumen del padre, sino también la de cualquier antepasado o simplemente cualquier volumen enviado previamente. Aquí no hizo ninguna diferencia, pero podría, solo una suposición, ayudar a evitar la duplicación de datos en algunos casos.No estoy seguro de si se pierde información meta en instantáneas o subvolúmenes en el camino, pero se debe preservar casi todo lo interesante para la mayoría de los casos de uso.
Todo el proceso me ayudó a transferir un sistema de archivos de 800 GB con 3.8 GB utilizados (según
df
) a una imagen de 10 GB con 3.8 GB utilizados. Transferencia sin-p
y-c
habría usado alrededor de 190 GB, por lo que se evitó la duplicación de datos.fuente
ogen
significa?ogen
es la "generación de origen" del subvolumen. Tengo que admitir que no entiendo completamente las diferencias o si usar la generación (no de origen) sería correcto, pero supongo que alguna prueba indicó que esto funcionó mejor (evitó la duplicación). La generación parece actualizarse cuando se crean instantáneas basadas en un subvolumen, ogen no. Me interesaría saber acerca de algunos hallazgos. Probablemente sea mejor consultar IRC o la lista de correo de Btrfs.He creado una herramienta de Python que puede hacer esto. Hice esto porque probé el enfoque de @Thomas Luzat tanto en mi propia implementación como en la de @Johannes Ernst, y el espacio utilizado se duplicó de 20GB a 40GB en el procedimiento de clonación. Pensé que se necesitaba algo más eficiente.
Considere este historial común del sistema de archivos:
Con el algoritmo de Thomas, "actual" se clonaría primero, y todas las instantáneas (que son instantáneas de estados anteriores de "actual") usarían "actual" como fuente de clon / padre. Obviamente, sería mejor basar snap3 en snap4, snap2 en snap3, etc.
Y esto es solo la punta del iceberg; encontrar las "mejores" fuentes de clonación (en términos de ahorro de espacio) en un sistema de archivos btrfs con un historial complejo es un problema no trivial. Se me ocurrieron otras 3 estrategias para resolver este problema, que parecen utilizar el espacio de manera mucho más eficiente. Uno de ellos ha resultado en clones de tamaño ligeramente inferior al de la fuente.
Puede leer los detalles en la página de Github si está interesado.
fuente
Hay una pregunta similar en unix.stackexchange.com que apunta a partclone.btrfs, pero no sé nada específico sobre esto.
También hay una discusión sobre la lista de correo del núcleo , que no parece realmente prometedora ...
fuente
Con
btrfs-send
lo que vi por última vez, todavía había parches experimentales flotando en la lista de correo de btrfs.fuente