Te lo explico en breve. Tengo dos subvolúmenes separados para películas y música, de los que estoy haciendo una copia de seguridad en otro disco con envío/recepción. Me gustaría fusionar los dos subvolúmenes en uno (con cp --reflink
) y enviarlo a la unidad de respaldo clonando archivos vinculados de instantáneas existentes.
Intenté crearlo new_volume
, luego cp -rx --reflink "music" "movies"
ingresarlo y luego:
btrfs send \
-c music-snapshot \
-c movies-snapshot \
new_volume-snapshot | btrfs receive /path/to/backup
pero se queja de que no se puede determinar el padre de new_volume
(identificado por identificación):
ERROR: parent determination failed for <id_number>
Por supuesto music-snapshot
y movies-snapshot
existe en la copia de seguridad. También intenté tomar una instantánea movies
, new_volume
luego cp -rx --reflink "music"
dentro de él, luego tomar una instantánea y enviarla con btrfs send -c music-snapshot -p movies-snapshot new_volume-snapshot
, pero parece que -c music-snapshot
no tiene ningún efecto, los datos se envían de todos modos.
¿Es posible lo que quiero hacer?
EDITAR: También intenté hacer esto:
btrfs sub snap -r movies movies-A
btrfs sub snap -r music music-A
btrfs sub snap movies new_volume
btrfs sub snap -r new_volume new_volume-A
En este punto tengo:
movies-A
music-A
new_volume-A (exact clone of movies-A)
Entonces:
cp -rx --reflink music/* new_volume/
btrfs sub snap -r new_volume new_volume-B
Al final, con ambos movies-A
y music-A
existiendo en destino, puedo hacer:
btrfs send \
-p movies-A \
new_volume-A | btrfs receive /backup/
y esto siempre funciona perfectamente (casi cero datos enviados). Pero...
btrfs send \
-p new_volume-A \
-c music-A \
new_volume-B | btrfs receive /backup/
No sé cómo explicarlo: con "algunos archivos" music
funciona, mientras que con otros sigue enviando datos porque ignora la fuente. Creo que de esta manera DEBERÍA funcionar definitivamente, pero no puedo reproducir de manera confiable ni el comportamiento de "trabajar" ni el de "no funcionar". Me tiendo a pensar que hay un error en alguna parte. ¿Alguien podría intentar esto?
Respuesta1
(DESCARGO DE RESPONSABILIDAD: el comentario de lgaudino sugiere que el enfoque propuesto para la fusión ya no funciona para btrfs-progs >=v5.14.2debido al cambiopropiedad btrfscomportamiento al cambiar el estado de solo lectura de una instantánea)
Lo que quieres se puede lograr, pero no directamente, porque btrfs send
(y btrfs receive
) son herramientas bastante simples,no hay forma de "fusionar" instantáneas en una proporcionando un padre secundariodesde el interior de las herramientas.
En el lado de envío ( btrfs send
)
btrfs send
salidassistema de archivosoperaciones de nivel (creación de directorio/archivo, transferencia de metadatos, transferencia de contenido de archivo, etc.) que pueden ser utilizadas en btrfs receive
el "lado receptor" para crear una instantánea equivalente en otro sistema de archivos btrfs. Estas operaciones se pueden ver realizando un "ejecución en seco" mediantebtrfs receive --dump
.
Unincrementalenviar (p. ej. btrfs send -p <parent> <snapshot>
) funciona exactamente igual en lo que a btrfs send
lo que respecta, excepto que solo se registran las operaciones del sistema de archivos necesarias para crear <snapshot>
mediante modificación (agregar/eliminar directorios/archivos, actualizar metadatos) <parent>
.
Tampoco se realiza ninguna verificación especial de la relación "padre-hijo". Suponiendo que el -p
parámetro se utiliza para especificar el "padre", btrfs send
simplemente genera los comandos necesarios para pasar de esa instantánea a otra (actuando como "secundario"). Esto funcionaría incluso si las dos instantáneas no tuvieran ninguna relación.
En el lado del envío, el único requisito btrfs send
es que todas las instantáneas seansolo lectura. Los subvolúmenes/instantáneas de solo lectura generalmente se generan mediante la -r
opción enbtrfs subvolume snapshot -r <subvol> <snap>
, a pesar debtrfs property set <snap> ro true/false
También se puede utilizar para cambiar la bandera después de la creación.
btrfs send
no tiene ninguna consideración por lo que está o no en el lado receptor, lo cual es inevitable ya que no hay comunicación bidireccional entre los lados, como en el rsync
caso de que btrfs send/receive ni siquiera se esté ejecutando al mismo tiempo y, en cambio, cada uno se ejecute en diferentes momentos. leer o escribir en un archivo.
Sólo puede haber un padre
Elpágina de manualy viejo)Preguntas frecuentes sobre wikislamentablemente son bastante confusos. el autor debtrfs-clone
afirmaque btrfs envía y recibe solo puede considerar como máximounopadre para transferencias incrementales. El padre se puede especificar directamente -p
o indirectamente mediante una o varias -c
opciones:
btrfs-send
de btrfs-tools 4.13 selecciona el padre para un subvolumen S y un conjunto de fuentes de clonación dadas C_icomo esto:
- si
-p
se especifica la opción, úsela- Si S no tiene
parent_uuid
un conjunto, o no se puede encontrar este uuid, abandone- si hay
C_i
conC_i->uuid == S->parent_uuid
(el subvolumen del cual S es un niño (instantánea), llamémoslo "mamá"), úsalo- si ningún C_i tiene lo mismo
parent_uuid
que S, ríndete- de todos los C_i que son hijos de "mamá", elige el que tenga la generación más cercana (en realidad,
ctransid
¿cuál es exactamente la diferencia entre "generación"?) y "mamá".Tenga en cuenta quela wikies un poco engañoso, porque sugiere que
-c
sinp
es diferente de-c
con-p
, aunque-p
generalmente está implícito en el algoritmo anterior. La única excepción relevante es el envío de subvolúmenes que no tienen padre.
En resumen, sugiero especificar siempre explícitamente uno de los padres a través de -p
e ignorar -c
, btrfs receive
simplemente no existe el concepto de "dos padres".
En el lado receptor ( btrfs receive
)
Elbtrfs-receive
La página de manual describe el propósito del programa como:
Reciba un flujo de cambios y replique uno o más subvolúmenes que fueron generados previamente por btrfs send
<parent>
En el caso de una transferencia completa, se crea un nuevo subvolumen; en el caso de una transferencia incremental, se crea una nueva instantánea de la instantánea (equivalente en el lado receptor) . En cualquier caso, el subvolumen/instantánea recién creado se muestra inicialmenteleer escribirpuede hasta que el "flujo de cambios" que emana btrfs send
se haya aplicado con éxito, luego se crea el subvolumen/instantáneasolo lectura.
Obviamente, no hay forma de implementar dos padres, ya que, para empezar, no hay copias de copia en escritura/reflink en el "flujo de cambios". La instantánea de <parent>
simplemente proporciona la base sobre la cual se aplica el "flujo de cambios".
Pero, ¿cómo se asegura el lado receptor que su <parent>
instantánea sea idéntica a la <parent>
del lado emisor? Élnunca comprueba/compara el contenido realde las instantáneas/subvolúmenes, sino que utilizaUUIDmetadatos en relación con elinmutabilidadsuposición para la instantánea principal.
btrfs subvolume show <subvolume>
proporciona resultados como:
/mnt/btrfs/subvolume
Name: subvolume
UUID: 5e076a14-4e42-254d-ac8e-55bebea982d1
Parent UUID: -
Received UUID: -
Creation time: 2018-01-01 12:34:56 +0000
Subvolume ID: 79
Generation: 2844
Gen at creation: 2844
Parent ID: 5
Top level ID: 5
Flags: -
Snapshot(s):
Cada subvolumen/instantánea tiene tres ranuras UUID, de las cuales dos pueden estar vacías. Cada instantánea creada por btrfs subvolume snapshot
siempre tiene una Parent UUID
que identifica claramente a su padre y cada instantánea creada por btrfs receive
siempre tiene una Received UUID
entrada. Si fue una transferencia completa no tendrá ninguna Parent UUID
entrada, si fue una transferencia incremental tendrá tanto una Received UUID
entrada como una Parent UUID
entrada. El usuario no puede cambiar manualmente las entradas de UUID.
Estos ID son suficientes para btrfs receive
establecer si posee una <parent>
instantánea del "lado receptor" quedeberíaser completamente idéntica a la <parent>
instantánea del "lado emisor", porque Received UUID
debe ser equivalente al UUID del lado emisor, garantizando así que se creó a partir de él, y el estado de solo lectura de todas las instantáneas involucradas significa que nono debeMientras tanto se han producido cambios.
(Nota al margen: si bien solo un lado de los dos volúmenes principales contiene la entrada UUID recibido, btrfs send/receive parece ser lo suficientemente inteligente como para proporcionar estos metadatos en el "flujo de cambios", por lo que ambos lados/sistemas de archivos pueden actuar potencialmente como el lado "enviador" o "receptor", según las necesidades del usuario)
Cómo fusionar dos subvolúmenes/instantáneas (<v5.14.2)
Como hemos visto, la fusión es imposible con solo btrfs send/receive
pero es bastante fácil de hacer manualmente, suponiendo que uno quiera combinar movies
y music
bajo un nuevo subvolumen unified
y asumiendo que movies
y music
también están completamente reflejados en el lado receptor:
- Cree un nuevo subvolumen (vacío) en el lado emisor:
btrfs subvolume create unified
- Cámbielo a solo lectura:
btrfs property set unified ro true
- Envíalo a la copia de seguridad:
btrfs send /path/to/unified | btrfs receive /receiving/side/
- Desactivar solo lecturaa ambos lados, por ejemplo,
btrfs property set /path/to/unified ro false
para el lado emisor - Manualmente
--reflink
el contenido demusic
ymovies
aunified
a ambos ladoscp -a --reflink /path/to/music /path/to/movies /path/to/unified/
- Colocarambos ladosLas
unified
instantáneas vuelven a ser de solo lectura.btrfs property set /path/to/unified ro true
- Cree una nueva instantánea de lectura y escritura
unified
para interactuar,unified
actuará como padre para futuras transferencias incrementales enambos lados.
En lugar de crear un subvolumen nuevo/vacío y enviarlo, también se podría haber comenzado en el paso 4 a partir de una instantánea music
o preexistente movies
. Desde el punto de vista de btrfs, lo único que importa es que los padres (futuros) de las dos partes estén conectados a través de un lado Received UUID
que apunta al otro y que ambos se lean solo en el momento de futuras transferencias.
Qué hacer para >= v5.14.2
Elsolución menos malaEs probable que siga el enfoque de la sección anterior pero, además, restablezca manualmente el Received UUID
valor a través depython-btrfs
después de que fue desarmado por btrfs-properties
.
No haybiensolución utilizando sólo las btrfs-progs
herramientas estándar. Lo más parecido a "una" solución puede ser explotar lahechoque la instantánea creada durante btrfs receive
se pueda leer y escribir hasta que finalice la transferencia e intentar hacer nuestras --reflink
copias antes de que la instantánea se configure como de solo lectura btrfs-receive
. En otras palabras, explotar uncondición de carreraActualmente es la única forma de hacer esto solo con herramientas estándar btrfs-progs >=5.14.2.
Obviamente, lo que realmente se necesita es que alguien haga una solicitud de función con el proyecto btrfs para al menos permitir la fusión como era posible antes de 5.14.2 para las personas que saben lo que están haciendo.
De todos modos, una explotación de la condición de carrera probablemente se vería así: dado que todavía podemos cambiar el estado de solo lectura de una instantánea en el lado emisor, podríamos alterar dicha instantánea, por ejemplo
use movies
y vuelva a vincular la copia music
en él:
btrfs property set -f movies ro false
cp -a --reflink /path/to/music /path/to/movies/
btrfs property set -f /path/to/movies ro true
btrfs subvolume snapshot /path/to/movies /path/to/unified_prep
Si es necesario, ahora podemos movernos por directorios y archivos internos unified_prep
(pero dejar el directorio de música en paz), y cuando estémos listos:
btrfs subvolume snapshot -r /path/to/unified_prep /path/to/unified
btrfs send -p /path/to/movies /path/to/unified | btrfs receive /path/to/backups/
btrfs send
y btrfs receive
deberíanoseleccione el directorio de música adicional porque está presente tanto en movies
(en el lado de envío) como unified
(también en el lado del cliente). Ahora, IFF lo logramos cp -a --reflink /bkp/to/music /bkp/to/unified/
en el lado receptor (!) mientras la nueva unified
instantánea aún se está transfiriendo y, por lo tanto, se puede leer y escribir, entonces tanto el unified
subvolumen del lado emisor como su instantánea del lado receptor deben ser idénticos y hemos fusionado exitosamente los subvolúmenes.