wiki:SyncronizeBtrfs

Sincronización de imágenes con Btrfs o ext4

Introducción

Hasta ahora Opengnsys permite crear un archivo imagen de una partición completa que luego puede clonarse en otra. Estas imágenes hay que tratarlas como un todo y no permiten ver su contenido.

Con la sincronización de imágenes pretendemos:

  • comparar la imagen con el contenido de la partición y sólo copiar o borrar los archivos que difieran.
  • comparar la imagen con el contenido de la partición y crear una imagen diferencial con los archivos que difieran y la información de los archivos que sobran, de forma que al restaurar primero la imagen completa y luego la diferencial la partición destino quede como la del equipo modelo.

La sincronización de imágenes se introducirá en la versión 1.0.5 en modo de prueba. Tenemos dos aproximaciones diferentes que denominamos "tipo directorio" y "tipo archivo" la diferencia principal es que la versión 1ª guarda los datos de las imágenes en un directorio del servidor y la versión 2ª lo empaqueta en un archivo que contiene un sistema de ficheros, según el kernel del cliente de OpenGnsys será ext4 o btrfs.

Estos sistemas de ficheros son de lectura y escritura, por lo que nos permite modificar la imagen una vez creada. Además el btrfs permite montarlo en modo comprimido, de forma que la compresión y descompresión se realiza de modo transparente para el usuario.

En esta página vamos a documentar los procedimientos que se utilizan en la versión tipo archivo, con los comandos del sistema operativo. Si se van a hacer pruebas es mejor instalar la versión 1.0.5 o 1.0.6 para utilizar las funciones y los script del proyecto.

Procedimiento

Creamos imágenes (en cache o repo).

  • Creamos un archivo vacío, lo montamos en modo loop y creamos dentro de él un sistema de ficheros.
  • Montamos el sistema de fichero y clonamos dentro con los datos de la partición sincronizándolos con rsync.
  • Para windows crearemos un backup de las ACL con ntfs-3g.secaudit

Restauramos imágenes.

  • Montamos la imagen (en cache o repo)
  • Utilizaremos rsync para sincronizar la partición.
  • Para windows restauraremos las ACL con ntfs-3g.secaudit

La partición puede estar vacía o haber sido restaurada y luego modificada por el uso.

En el servidor puedo montar la imagen y modificar, borrar o añadir los archivos que queramos.

Problemas conocidos.

Al crear la imagen en el servidor hay veces que no se monta bien, la sincronización se realiza sobre el directorio de montaje y la imagen queda vacía. Al restaurar se monta la imagen sobre el directorio y no tiene datos. Es muy importante comprobar el contenido de la imagen.

Al restaurar la cache no se pueden mostrar log, si ponemos esta opción a rsync se cuelga el equipo. Esto pasaba con las imágenes en squash, no se ha vuelto a probar con las que son en ext4 o btrfs.

Al crear la imagen se hace una estimación del tamaño de los datos para crear el archivo vacío inicial, al terminar se reduce hasta el tamaño real que ocupan los datos. Esto funciona bien en ext4, pero en btrfs no se puede hacer porque el comando que trae la distribución da error muy a menudo.

La transferencia de la imagen con formato ext4 y btrfs a través de la red ha ido bien con multicast, unicast y rsync. No se ha probado con torrent.

Crear una imagen tipo ext4 o btrfs

La imagen será un archivo con un sistema de fichero que contenga los datos de la partición.

Creamos el archivo vacío

Podemos utilizar los comandos dd o truncate, dd tarda bastante y truncate es inmediato:

dd if=/dev/zero of=$IMGFILE bs=1024 count=$SIZEREQUIRED

o:

truncate --size=">$SIZEREQUIRED"k "$IMGFILE"

IMGFILE: nombre archivo imagen.
SIZEREQUIRED: tamaño de la imagen en kilobytes.

Creamos el sistema de ficheros

Detectamos cual es el kernel del cliente para elegir el sistema de ficheros a utilizar. Si es menor que 3.7 usamos ext4, si es mayor o igual btrfs:

KERNEL=$(file $BASEDIR/tftpboot/ogclient/ogvmlinuz |awk -F . '{print $2}')
[ $KERNEL -lt 7 ] && IMGFS="EXT4" || IMGFS="BTRFS"

Utilizamos el comando mkfs del fs elegido:

LOOPDEVICE=$(losetup -f)
if [ "$IMGFS" == "EXT4" ]; then
      mkfs.ext4 -i 4096  -b 4096 -L "${2##*\/}" $LOOPDEVICE 2>&1 |tee -a $OGLOGCOMMAND
else
      mkfs.btrfs  -L "${2##*\/}" $LOOPDEVICE 2>&1 | tee -a $OGLOGCOMMAND
fi

Para guardar la información de la imagen (como tenemos en partclone: tipo de sistema operativo, tamaño, archivos de que contiene, ...) necesitaremos incluir uno o varios archivos en el sistema de fichero original antes de realizar la creación.

Sincronización imagen

Montamos la imagen y la partición que queremos clonar y sincronizamos tomando como origen la partición.

1) Montamos la imagen. En el servidor:

LOOPDEVICE=$(losetup -f)
if [ $IMGFS == "EXT4" ]; then
     mount $OPTMOUNT -t ext4 $1 $2
else
     mount $OPTMOUNT -o compress=lzo  "$1" "$2"
fi

OPTMOUNT: ro cuando restauramos, vacío al crearla, ya que por defecto es de lectura y escritura.

2) Montamos la partición, en el cliente:

ogMount 1 X

3) Creamos la lista del contenido.

mkdir /tmp/vacio
rsync -aHvn --delete /mnt/sdaX/ /tmp/vacio > /tmp/ogimg.lista

4) Sólo para windows: creamos la lista de acl:

# Desmontamos la particion
ogUnmount 1 X 
# Guardamos las ACL:
ntfs-3g.secaudit -b /dev/sdaX / > /tmp/ogimg.acl
# Montamos la partición para seguir el proceso.
ogMount 1 X

5) Sincronizamos la imagen desde la partición.

rsync -aHAX$OPTRSYNC --inplace --delete  /mnt/sdaX/ "$DIRMOUNT"

# Guardamos la lista del contenido y las acl si existen:
rsync -aHAX$OPTRSYNC --inplace /tmp/ogimg.* "$DIRMOUNT"

6) Desmontamos la imagen. En el servidor:

umount /opt/opengnsys/images/mount/$IMGNAME

Importante: Es mejor utilizar el servicio de rsync en el servidor ya que cuando utilizamos rsync sobre samba va peor, la transferencia es más lenta. Este tema excede el objeto de está documentación.

Redimensionar imagen

Cuando se crea una imagen por segunda vez puede ser necesario que el tamaño sea mayor. Se creará exactamente como la primera vez salvo que en vez de crear el archivo de imagen y su sistema de fichero los redimensiono.

1) Redimiensiono el archivo

truncate --size=">$NEWSIZEREQUIRED"k "$IMGFILE"

2) Redimiensiono el sistema de ficheros

LOOPDEVICE=$(losetup -f)
if [ $IMGFS == "EXT4" ]; then
      losetup $LOOPDEVICE "$IMGNAME.img"
      resize2fs -f $LOOPDEVICE &> $REPOLOG
else
      mount -o compress=lzo  "$IMGNAME.img" "$DIRMOUNT"
      btrfs filesystem resize max "$DIRMOUNT"  2>&1 > $REPOLOG
fi

Restaurar - Sincronizar una imagen tipo ext4 o btrfs

La imagen puede estar en la cache o en repo.

1) Montamos la imagen, por ejemplo en el servidor

# Creamos el punto de montaje:
mkdir /opt/opengnsy/images/mount/$IMGNAME

# Montamos la imagen:
if [ $IMGFS == "EXT4" ]; then
     mount -o ro -t ext4 $IMGNAME.img /opt/opengnsy/images/mount/$IMGNAME
else
     mount -o ro,compress=lzo  "$IMGNAME.img" "/opt/opengnsy/images/mount/$IMGNAME"
fi

2) Montamos la partición, en el cliente

ogMount 1 X

3) Sincronizamos la partición tomando como origen la imagen

La partición puede estar vacía o haber sido restaurada con anterioridad y sólo hay que restaurar las modificaciones que haya hecho por el uso.

rsync -aHAXq$OPTRSYNC --password-file=/passrsync  opengnsys@$REPOIP::ogimages/mount/$IMGNAME /mnt/sdaX

4) Sólo para windows restauramos las ACL

# Copiamos las acl a /tmp
cp //mnt/sdaX/ogimg.acl /tmp

# Desmontamos la partición:
ogUnmount 1 X

# Restauramos las acl:
ntfs-3g.secaudit -se /dev/sdaX /tmp/ogimg.acl

5) Desmontamos la imagen

{
umount /opt/opengnsys/images/mount/$IMGNAME

Opciones rsync

/ la barra en el directorio de origen hace que transfiera el contenido del directorio al directorio destino (si no la ponemos copia también el directorio)

-a, --archive modo archivo: igual que -rlptgoD (no -H,-A,-X) conserva los enlaces simbólicos, dispositivos, permisos y propietario.

-q –quiet: no muestra mensajes que no sean errores. Si no se pone a veces se cuelga el equipo.

--delete Borra los ficheros que no existían en el original. Si no lo ponemos actualizará los existentes en el origen y no tocará los nuevos.

-A preserva ACLs

-X preserva atributos extendidos (como los de Selinux)

-H preserva enlaces “duros”

-n realiza la prueba pero no hace cambios, nos sirve para crear el listado.

-z, --compress Comprime el fichero en la transferencia. Puede convenir o no dependiendo de dos factores: la capacidad de cálculo de ambos equipos para comprimir/descomprimir y el ancho de banda de la red (opcional).

No utilizamos:

-v, --verbose : Muestra todos los archivos que se van copiando) → cuelga el equipo.

--progress: muestra los archivos y el progreso → cuelga el equipo.

-g preserva grupo (incluido en a)

-o preserva propietario (incluido en a)

Crear una imagen diferencial

Definición de imagen diferencial:

Supongamos que tenemos una imagen completa y la hemos restaurado en un equipo que hará de modelo. Instalamos una serie de programas.

Llamaremos imagen diferencial de una completa a la que contengan los archivos nuevos y la información de los archivos que sobran, de forma que al restaurar primero la imagen completa y luego la diferencial la partición destino quede como la del equipo modelo.

Procedimiento

Se monta la imagen completa y se compara el contenido de la partición con la imagen: se crea la lista de las diferencias con rsync

# Montamos imagen completa (con la que vamos a comparar)
if [ $IMGFS == "EXT4" ]; then
     mount -o ro -t ext4 $IMGNAME.img /opt/opengnsy/images/mount/$IMGNAME
else
     mount -o ro,compress=lzo  "$IMGNAME.img" "/opt/opengnsy/images/mount/$IMGNAME"
fi

# Creamos las diferencias 
rsync -aHvn --delete /mnt/sda2/ /opt/opengnsy/images/mount/$IMGNAME > /tmp/ogimg.lista

Se trata la lista de diferencias: se separan los archivos a copiar, a borrar y los enlaces (simbólicos o no), ya que se tendrán que procesar de forma diferente al restaurar

# Eliminamos comentarios de rsync y el directorio raíz.
sed -i -e s/"^sent.*.bytes\/sec"//g -e s/^total.*.speedup.*.$//g -e s/"sending.*.list"//g /tmp/ogimg.lista
sed -i  '/^\.\//d' $IMGINFO

grep -e '\->' -e  '\=>' lista_img > /tmp/ogimg.ln 
grep -e  ^deleting  lista_img | sed s/^deleting\ //g > /tmp/ogimg.rm 
grep -v -e '\->' -e  '\=>'  -e ^deleting -e ^created lista_img > /tmp/ogimg.info 

En caso de windows se genera el fichero de acl de la partición y se extraen las que corresponden a los ficheros que contiene la diferencial. Es un proceso que tarda mucho pero que nos ahorra tiempo cuando restauramos.

Creamos la lista de acl completa:

# Desmontamos la particion 
ogUnmount 1 X 
# Guardamos las ACL: 
ntfs-3g.secaudit -b /dev/sdaX / > /tmp/ogimg.acl 

Filtramos la lista de acl, extrayendo las de los ficheros que contiene la diferencial:

# Al fichero le quitamos las líneas sobrantes: comentarios y lineas vacías.
sed -e s/"^#.*$"//g /tmp/ogimg.info > $FILES
sed -i '/^$/d'  $FILES

touch $ACLTMP

# Recorremos el listado y extraemos la acl correspondiente al fichero o directorio.
while read LINE; do
    read END INI <<< "$(grep -n  -e "File" -e "Directory" $IMGACL| grep -A 1 "$LINE"| awk -F :  '!(NR%2){print $1" "p}{p=$1}' )"
    let NUM=$END-$INI-1
    # Si algún archivo no se encuentra, el error lo mandamos a /dev/null
    sed -n -e $INI,+"$NUM"p  /tmp/ogimg.acl  2>/dev/null | tee -a $ACLTMP > $OGLOGCOMMAND
done < $FILES

cp $ACLTMP /tmp/ogimg.acl 

Se crea el archivo de imagen diferencial vacío conteniendo un sistema de archivos (igual que en la completa)

# Creamos archivo vacio.
dd if=/dev/zero of=$IMGFILE bs=1024 count=$SIZEREQUIRED

#Detectamos cual es el kernel del cliente para elegir el sistema de ficheros a utilizar.
KERNEL=$(file $BASEDIR/tftpboot/ogclient/ogvmlinuz |awk -F . '{print $2}')
[ $KERNEL -lt 7 ] && IMGFS="EXT4" || IMGFS="BTRFS"

# Creamos el sistema de ficheros:
LOOPDEVICE=$(losetup -f)
if [ $IMGFS == "EXT4" ]; then
      losetup $LOOPDEVICE "$IMGNAME.img"
      resize2fs -f $LOOPDEVICE &> $REPOLOG
else
      mount -o compress=lzo  "$IMGNAME.img" "$DIRMOUNT"
      btrfs filesystem resize max "$DIRMOUNT"  2>&1 > $REPOLOG
fi

Se sincroniza de la partición a la imagen diferencial pasando a rsync la lista de archivo que debe copiar.

# Se monta la imagen diferencial (si es btrfs ya está montada en el paso anterior.)
[ $IMGFS == "EXT4" ] && mount $OPTMOUNT -t ext4 "$IMGNAME.img.diff" "$DIRMOUNT" 

# Se sincroniza. 
rsync -aHq --files-from=/tmp/ogimg.info  /mnt/sda2/ "$DIRMOUNT"

# Se guardan los ficheros de información en la imagen.
rsync -aHAX$OPTRSYNC --inplace /tmp/ogimg.* "$DIRMOUNT"

Restaurar - Sincronizar una imagen diferencial

Tras restaurar la imagen completa, la restauración de la imagen diferencial hará lo siguiente:

Montará la partición destino y la imagen diferencial

ogMount 1 X
mount $OGCAC$OGIM/$IMGNAME.img.diff "$DIRMOUNT"

Con rsync copiará los archivos incluidos en la lista de la diferencial (Es más rápido que si se le permite que compare el contenido de la imagen con la partición).

# Copiamos los archivos de información a la partición destino:
rm /tmp/ogimg.* $DEST
cp $DIRMOUNT/ogimg.* $DEST

rsync -aHq –files-from=$DEST/ogimg.info  "$DIRMOUNT"/ /mnt/sdaX 

Borrará los archivos sobrantes, con la información de la lista para borrar:

# "Diferencial: creando enlaces y borrando"
cd /mnt/sdaX 
cat "$DIRMOUNT/ogimg.rm" 2>/dev/null | xargs rm -rf

Creará o modificamos los enlaces, con la información de la lista de enlaces

# La imagen diferencial tiene ogimg.ln 
# para la completa lo generamos con los enlaces que contengan  /mnt/
[ -r "$DEST/ogimg.ln" ] || grep -e "->" -e "=>" "$DEST/ogimg.info"|grep "/mnt/" > "$DEST/ogimg.ln "
if [ $(wc -l "$DEST/ogimg.ln"|cut -f1 -d" ") -ne 0 ]; then
   while read LINEA
   do
        ORIGLN="${LINEA#*> }"
        # Si origen hace referencia a la particion lo modificamos
        echo $ORIGLN|grep "/mnt/"> /dev/null && ORIGLN="$DEST/${ORIGLN#/mnt/*/}"
        # rsync marca - los enlaces simbolicos y = enlaces "duros"
        LINEA="${LINEA%>*}"
        TYPELN="${LINEA##* }"
        DESTLN="${LINEA% *}"

        if [ "$TYPELN" == "-" ]
        then
           OPTLN='-s'
        else
           OPTLN=''
        fi
        cd "$DEST/$(dirname "$DESTLN")"
        rm "$(basename "$DESTLN")"
        ln $OPTLN "$ORIGLN" "$(basename "$DESTLN")"
        echo -n "."
   done < "$DEST/ogimg.ln"  2>/dev/null
   echo ""

fi

En caso de windows restauramos las acl, exactamente igual que en la completa:

# Copiamos las acl a /tmp
cp /mnt/sdaX/ogimg.acl /tmp

# Desmontamos la partición:
ogUnmount 1 X

# Restauramos las acl:
ntfs-3g.secaudit -se /dev/sdaX /tmp/ogimg.acl

Transformando una imagen de partclone en sqfs

Partimos de una imagen de partclone comprimida, la transformamos en una que se pueda montar.

Se restaura la imagen en un fichero (dos opciones según el compresor):

cat Imagen.img.gz | gzip -d -c | partclone.restore -C -s - -O imgMontable.img

lzop -dc Ubuntu11.img | partclone.restore -C -s - -O ubuntu11Montar.img

Montando la imagen del partclone:

mkdir montar 
mount -o loop ubuntuMontar.img montar/ 
mount.ntfs-3g -o loop w7BasicaMontar.img montar/

Para la imagen sincronizable creamos el archivo de la imagen vacio y generamos dentro un sistema de ficheros:

# Creamos archivo vacío.
dd if=/dev/zero of=$IMGFILE bs=1024 count=$SIZEREQUIRED

#Detectamos cual es el kernel del cliente para elegir el sistema de ficheros a utilizar.
KERNEL=$(file $BASEDIR/tftpboot/ogclient/ogvmlinuz |awk -F . '{print $2}')
[ $KERNEL -lt 7 ] && IMGFS="EXT4" || IMGFS="BTRFS"

# Creamos el sistema de ficheros y lo montamos:
LOOPDEVICE=$(losetup -f)
if [ $IMGFS == "EXT4" ]; then
      losetup $LOOPDEVICE "$IMGNAME.img"
      resize2fs -f $LOOPDEVICE &> $REPOLOG
      mount -o ro -t ext4 $IMGNAME.img "$DIRMOUNT"
else
      mount -o compress=lzo  "$IMGNAME.img" "$DIRMOUNT"
      btrfs filesystem resize max "$DIRMOUNT"  2>&1 > $REPOLOG
fi

Sincronizamos la imagen nueva desde la del partclone

rsync -aHAX   montar/ "$DIRMOUNT"
Last modified 2 months ago Last modified on Jul 14, 2017, 1:07:08 PM