13 de agosto de 2010

Usando LVM para migrar particiones en Linux

Una de las ventajas que tienen los discos duros modernos es que tiene incorporada funciones para predecir un mal funcionamiento, de modo que los datos importantes se puedan salvaguardar.

Hace algunas semanas recibo varias notificaciones que afirmaban que el disco de sistema tenia errores de lectura persistentes. Como esta computadora tiene instalado varios servicios, con sus configuraciones personalizadas, la sola idea de pasar varios días reinstalando servidores no parecía muy atractiva y decidí buscar alternativas para minimizar el downtime.

Primero usando la guia de smartmontools (Bad block HOWTO for smartmontools), intente cuantificar los daños y ver si se podía reparar de alguna forma el disco. Afortunadamente los sectores con errores no correspondían a ninguna partición con datos, pero desafortunadamente los sectores eran irrecuperables. De modo que para evitar cualquier pérdida la mejor opción era reemplazar el disco y migrar los datos antes de que el daño se extienda.

Desde hace varios años que uso LVM para realizar mis instalaciones de sistemas Linux. Una de las ventajas que tiene LVM es que permite cambiar el tamaño de las particiones dinámicamente sin tener que mover los datos; además algunos sistemas de archivos populares, como ext3, xfs, ext4, permiten realizar esta operación aun cuando están siendo usados.

Una de las primeras cosas que pensé es crear una imagen espejo del disco de sistema original y luego copiarla sobre el nuevo disco. Una de las desventajas de esta solución es que necesito que el disco de sistema no este siendo utilizado. Otra es que el disco está dañado y hacer una imagen no esta tan simple.

Buscando enctre una mejor alternativa, usar las herramientas provistas por LVM (pvmove) para migrar las particiones a un nuevo disco (Removing an Old Disk).

Como root primero creamos una volumen físico
# pvcreate /dev/sdd2
Luego agregamos la partición al grupo de volúmenes
# vgextend vg /dev/sdd2
Ahora movemos todos los dato de la antigua partición a la nueva
# pvmove /dev/sda2 /dev/sdd2
Borramos la partición dañada del grupo
# vgreduce vg /dev/sda2
El primer error que cometí es ejecutar pvmove mientras estaba corriendo mi desktop manager. Aparentemente pvmove bloquea las escrituras a las particiones afectadas mientras esta realizando la copia, lo que pareció no gustarle a mi desktop manager. La solución fue ejecutar la instrucción en modo single-user (arrancar en modo de recuperación, o si nos logueamos por consola podemos usar telinit 1 para pasar a modo single-user).

Luego de algun tiempo, que supongo proporcional al tamaño de los datos a copiar, pvmove termina de ejecutar y tenemos los datos en el nuevo disco.

Aquí cometí el segundo error, correctamente me di cuenta que también debía migrar la partición de arranque (que no esta dentro del volumen LVM). Pero me equivoque en el comando adecuado, update-grub solo reinstala en el arranque en la partición previamente configurada, es decir no toma en cuenta que partición esta montada en /boot. Lo correcto es usar dpkg-reconfigure grub-pc, que permite seleccionar una nueva particion como arranque.

7 de agosto de 2010

Little arithmetic tricks applied to programming

Sometimes when programing we have to resolve some simple arithmetic problems, like calculating the remainder elements from a buffer, counting the numbers of elements, etc. In these cases is easy to commit "off by one" mistakes, ie we account one element more or one less. In the better case we are lucky if the program crash in the right place, but we often end up with a bug that is really hard to find.
One trick that I find often useful in these situations is to think that the buffers are much smallers, like zero or one bytes; another option is to think a large and easy number like 1000, etc.