viernes, 4 de agosto de 2017

Los sectores defectuosos a la fuga

Para que se entienda lo que viene a continuación primero es necesaria una brevísima introducción a los sectores defectuosos.

¿Qué es un sector defectuoso? Forzosamente debo responder primero ¿qué es un sector?

Los dispositivos de almacenamiento, donde de forma persistente almacenamos nuestra preciosa información, deben organizar esa información de alguna manera, todavía no llegamos a los sistemas de archivo, vamos a hablar de algo que está por debajo del sistema de archivos.

En discos duros, cada sector está compuesto por la cabecera, el área de datos y el código de corrección de errores (ECC, del inglés error-correcting code). El tamaño de cada sector es fijo y está dado de fábrica. Tradicionalmente los sectores tenían 512 Bytes (y estos 512 no incluyen ni la cabecera ni el ECC, son 512 bytes para los datos de usuario).

Esto aplica a los discos de 512 de tamaño de sector. Ahora, cualquier disco fabricado hace unos años tendrá 4K de tamaño de sector

 

Actualización 14/03/2023:

El comando dd para blanquear toda la superficie del disco duro, como se muestra más abajo, forzará la reasignación de sectores defectuoso ya conocidos. Pero no encontrará sectores nuevos. De ahí la necesidad de hacer una exploración de superficie.

Una forma, independiente del fabricante del disco duro, de hacer algo así es con el comando badblocks de Linux:

 

Modo no destructivo, actualizará el conteo de sectores defectuosos pero no los reasignará ni modificará la información de los sectores del disco:

badblocks -b 4096 -c 1024 -s /dev/sdX

 

Modo destructivo, esto lo hacemos cuando ya hemos respaldado la información relevante y podemos permitirnos ya hacer la reasignación.

badblocks -b 4096 -c 1024 -w -s /dev/sdX

Pueden jugar con el parámetro -c, según los recursos de su máquina, para acelerar el proceso más o menos. Creo haber puesto un número coherente en el ejemplo.

Para ambos comandos, sdX se debe reemplazar por el disco con el que queremos trabajar. Se usa el disco entero, no sólo una partición.

Los diferentes fabricantes de discos duros suelen tener algún tipo de herramienta (de software) que permite ver la salud de sus discos y realizar exploración de superficie. Pero encuentro mucho más conveniente contar con un método que funcione igual con cualquier fabricante que tener que estar buscando la herramietna de cada uno, descargarlar, flashear un pendrive con ella, etc.

Si no queda claro por qué haríamos esto, es para que no nos salten sectores defectuosos nuevos mientras trabajamos. Es mejor encontrarlos por adelantado, antes de decidir confiarle nuestra iformación a un disco duro.

Si hemos adquirido un disco de segunda mano, como esos que venden en Amazon, se supone que el vendedor ha hecho la exploración de superficie y que también ha blanqueado el disco duro para proteger la privacidad de su dueño anterior. Dicho de otro modo, que el vendedor es un buen ciudadano. Pero... ¿cómo estar seguros? Además, el disco duro pudo haberse dañado durante el transporte, esto el vendedor no lo puede controlar.

Toda esta entrada aplica a discos magnéticos. Este tipo de cosas, en discos de estado sólido (SSD), suele resultar en el agotamiento de la vida útil del dispositivo.

Luego de ejecutar badblocks, examinamos los atributos SMART del disco, usando los comandos que se muestran durante esta entrada, para ver cómo evolucionaron con respecto a cómo estaban antes de ejecutar el comando. Es bueno prestar atención a todos los atributos, no sólo a pending y reallocated. Un ejemplo es Uncorrectable Sector Count o Contador de sectores incorregibles. Si tenemos un incremento demasiado contrastado en cualquiera de estos contadores, o si los contadores ya estaban altos en un principio, lamentablemente habrá que cambiar el disco duro.

En Internet encontrarán artículos diciendo que cambien sus discos al primer sector defectuosos. Bien, yo no estoy de acuerdo. Todo dependerá de la relevancia (para nosotros) de los datos almacenados en el disco duro en cuestión.

El disco duro usado para los ejemplos de esta entrada, escrita en 04/08/2017, todavía está en uso hoy. Lo tengo montado en un servidor de archivos junto a muchos otros discos duros. Su contador de sectores defectuosos sigue igual a como lo dejé al final de la entrada original del 2017.

Ejemplo: si se trata de un disco que usan a modo de caché de cosas que pueden volver a conseguir (descargar...), o generar proceduralmente, pero que almacenan para ahorrar tiempo la próxima vez que lo necesiten. Entonces la tolerancia será mayor. Y unos pocos sectores defectuosos no serán motivo de pánico. A fin de cuentas, el dinero no crece en los árboles.

Pero la cosa cambia si se trata de sus proyectos (del tipo que sea), o cosas que no son fáciles, o bien son imposibles, de reemplazar si se llegan a perder.

Y... la cosa cambia de nuevo si tienen la información importante replicada en algún lado, como todos deberíamos hacer. Pero claro, el dinero no crece en los árboles, por lo que no todos lo hacen. En ese caso pueden apostar más duro con el disco que no está perfecto, sabiendo que de todas formas su fallo no supondrá un contratiempo del que no nos podamos recuperar.

 

Actualmente existen los llamados discos duros de formato avanzado, que aumentan el tamaño de sector a 4 KiB que equivale a 4096 Bytes.

También están los discos de transición, que son aquellos que internamente operan con 4 KiB de tamaño de sector pero se reportan al sistema operativo como de 512 B, más sobre esto luego.

No necesitamos entrevistar a un experto en discos duros para razonar que sería absurdo tener una cabecera y código ECC por cada Byte, pues ocuparíamos más de la superficie del disco en representar la información extra de los sectores que la que ocuparíamos con la información misma. Es necesario decidir un tamaño para esta estructura que haga su manejo posible y conveniente. Con el tamaño de los discos actuales 512 B le debe quedar ya chico a los fabricantes y les debe resultar ineficiente.

Creo que hasta aquí ya ganamos la intuición necesaria para continuar con esta entrada, si quieren profundizar más pueden seguir aquí.

Ahora pasemos a los sectores defectuosos.

El firmware de un disco duro tiene la capacidad de identificar sectores que ya no son confiables. Por ejemplo, gracias al código ECC, es posible saber que la información recuperada de un sector no es la misma que fue escrita (hay corrupción de información).

El firmware también tiene una serie de estrategias para lidiar con el problema. Los discos duros actuales vienen con cierta cantidad de sectores de repuesto, para en caso de tener que dejar de usar un sector por no poder confiar en él, poder hacer una reasignación, relocalización o "re-mapeo". De manera que si en el futuro se trata de escribir en, digamos, el sector 12439, y este fue remapeado a uno de los de repuesto, en realidad la información que debería ir en el sector 12439 irá a uno de los sectores de repuesto, probablemente más allá del último sector de la capacidad reportada por nuestro disco duro. Y la próxima vez que queramos leer el sector 12439, en realidad estaremos leyendo del sector de repuesto.

La idea detrás de esto, es que sería inconveniente pedirle al sistema operativo que estuviera diseñado para lidiar con discos con "agujeros". Así que estos "agujeros" en el arreglo de sectores son considerados "asuntos internos" del disco duro. Hasta donde el sistema operativo sabe, el disco sigue siendo un arreglo ininterrumpido de sectores.

Ahora bien. El remapeo de sectores, si bien es automático, sólo puede ocurrir de forma silenciosa si se dan ciertas condiciones. Recordemos que los discos duros están hechos para ser confiables y respetar los preciosos datos de los usuarios. El disco duro no puede decidir que una información no es importante.

Si un sector defectuoso es descubierto durante una operación de escritura, mientras el disco duro todavía tiene en su memoria electrónica la información en cuestión, puede, de forma totalmente silenciosa y sin que se entere el sistema operativo, hacer el remapeo en ese mismo momento y escribir la información en un sector sano. Hasta donde sabe el sistema operativo, la información fue escrita en la posición donde él pidió que se escribiera, y usando el mismo número LBA que usó para escribir será capaz de recuperarla después.

Pero también puede darse el caso, que cuando la información fue escrita, el sector se comportara correctamente. Pero luego, digamos unos meses después, cuando el disco finalmente necesita leer de ese sector, ocurre que ya no es capaz de recuperar la misma información.

Es posible que este caso también se resuelva de manera silenciosa. Si el ECC es suficiente para recrear la información original, y el disco está seguro de haber reconstruido la misma información, ya hará el remapeo y la escribirá en un sector de repuesto. El sistema operativo recibirá la información que pidió y ni se enterará de lo que ocurrió.

Pero este caso tiene una segunda variante, es cuando no se consigue leer la información correcta sin importar cuánto se lo intente. En este caso el disco duro romperá el silencio y reportará un error. El sistema operativo no recibirá la información que pidió.

Si lo que se corrompió era un archivo de usuario, el que recibirá el golpe será el usuario, cuando le salga el diálogo de "Error de Entrada/Salida", pero para el sistema operativo serán buenas noticias, ha salido ileso. En cambio, si el daño está en un archivo de sistema, una librería esencial por ejemplo, puede ocurrir cualquier cosa, como un sistema que no consigue llegar al escritorio. Otro día hablamos de las estrategias que los sistemas operativos tienen para lidiar con estos casos.

El número de sectores defectuosos se puede ver en los registros SMART del disco duro. Más sobre esto luego. Windows, si se topó con uno de esos casos en que el disco duro no guardó silencio al respecto, reportará el error en el visor de eventos, con cruz roja en la categoría "Sistema", y además marcará el sector, o mejor dicho el cluster, para no intentar escribir en él nuevamente. También es posible que muestre un diálogo de error, si el error de entrada/salida ocurre, por ejemplo, durante una copia de archivos con el Explorador de Windows. Conque marcará el sector me refiero a que Windows lleva su propio registro de sectores defectuosos, independiente del que lleva el mismo disco duro para su uso interno. Para que el sistema operativo llegue a notar un sector defectuoso, debe ocurrir que el disco duro no lo consigue resolver de forma silenciosa como ya se explicó.

Claro, que el sistema operativo se entere que ocurrió un error de entrada/salida y que decida alertar al usuario con un mensaje son dos cosas diferentes. Es un buen hábito leer el visor de eventos cada tanto.

Las personas acostumbradas a lidiar con discos duros ya tienen sus estándares para decidir si seguir confiando o no en el disco duro que ha presentado alguna vez sectores defectuosos.

Si el disco se está degradando, esto es que aparecen sectores defectuosos nuevos de forma continua. Habrá que comprar un disco duro nuevo y pasar los datos, y en lo posible no volver a usarlo hasta entonces para no arriesgarnos a que después no se puedan ya leer los datos.

Si el número de sectores defectuosos se mantiene, entonces se miden los riesgos, en base a información recolectada de la Internet o a experiencias pasadas, también en base al estado de nuestras finanzas, si nos arriesgamos a seguir confiando en el disco duro. Ejemplo, yo diría que 3 sectores defectuosos en un disco duro de más de 10 años no da para cambiarlo, mientras el disco no de signos de seguir degradándose.

Los sectores de repuesto son un recurso limitado. Si un disco duro se queda sin ellos, y aún sigue detectando errores al escribir o leer, ya no permanecerá silencioso, el sistema operativo empezará a ver los errores, y el humano al teclado también.

Un síntoma de que se han agotado los sectores de repuesto es que los errores de entrada y salida ocurren durante escrituras. Como ya se dijo, al intentar escribir, no importa la cantidad de Bytes de que se trate, si se detecta error, al menos esa operación de escritura debería ser relocalizada a un sector de repuesto de forma automática y silenciosa. Si esto no ocurre es síntoma de que ya no hay sectores de repuesto.

Ahora viene lo divertido, la obligada anécdota.

Actualmente tengo un disco de 1 TB y otro de 500 GB. El de 1 TB está perfecto así que lo dejaremos afuera de esto, mientras que el de 500 GB, por primera vez en su larga vida, me presentó sectores defectuosos.

Algunas curiosidades: los sectores defectuosos fueron 22. Todos estaban dentro de los límites de la partición de Ubuntu 16.04, a mi Windows no le tocó ninguno, y a mi partición de datos compartida tampoco.

Cuando Linux intentó leer de alguno de estos sectores, el sistema se volvía irresponsivo, ya que no podía continuar hasta obtener la información o darse por vencido. Por la terminal de texto, así como por el log del sistema, se apreciaban mensajes como estos:

 Jul 29 09:36:34 desktop kernel: [  364.231171] ata1.00: exception Emask 0x0 SAct 0x40000001 SErr 0x0 action 0x0
 Jul 29 09:36:34 desktop kernel: [  364.231173] ata1.00: irq_stat 0x40000008
 Jul 29 09:36:34 desktop kernel: [  364.231176] ata1.00: failed command: READ FPDMA QUEUED
 Jul 29 09:36:34 desktop kernel: [  364.231178] ata1.00: cmd 60/00:f0:e0:9c:bd/01:00:0c:00:00/40 tag 30 ncq 131072 in
 Jul 29 09:36:34 desktop kernel: [  364.231178]          res 41/40:00:95:9d:bd/00:00:0c:00:00/40 Emask 0x409 (media error) 
 Jul 29 09:36:34 desktop kernel: [  364.231179] ata1.00: status: { DRDY ERR }
 Jul 29 09:36:34 desktop kernel: [  364.231180] ata1.00: error: { UNC }
 Jul 29 09:36:34 desktop kernel: [  364.233198] ata1.00: configured for UDMA/133
 Jul 29 09:36:34 desktop kernel: [  364.233208] sd 0:0:0:0: [sda] tag#30 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
 Jul 29 09:36:34 desktop kernel: [  364.233210] sd 0:0:0:0: [sda] tag#30 Sense Key : Medium Error [current] [descriptor] 
 Jul 29 09:36:34 desktop kernel: [  364.233212] sd 0:0:0:0: [sda] tag#30 Add. Sense: Unrecovered read error - auto reallocate failed
 Jul 29 09:36:34 desktop kernel: [  364.233214] sd 0:0:0:0: [sda] tag#30 CDB: Read(10) 28 00 0c bd 9c e0 00 01 00 00
 Jul 29 09:36:34 desktop kernel: [  364.233215] blk_update_request: I/O error, dev sda, sector 213753237
 Jul 29 09:36:34 desktop kernel: [  364.233223] ata1: EH complete
 Jul 29 09:36:36 desktop kernel: [  366.919842] ata1.00: exception Emask 0x0 SAct 0x1000 SErr 0x0 action 0x0
 Jul 29 09:36:36 desktop kernel: [  366.919850] ata1.00: irq_stat 0x40000008
 Jul 29 09:36:36 desktop kernel: [  366.919856] ata1.00: failed command: READ FPDMA QUEUED
 Jul 29 09:36:36 desktop kernel: [  366.919865] ata1.00: cmd 60/08:60:90:9d:bd/00:00:0c:00:00/40 tag 12 ncq 4096 in
 Jul 29 09:36:36 desktop kernel: [  366.919865]          res 41/40:00:95:9d:bd/00:00:0c:00:00/40 Emask 0x409 (media error) 
 Jul 29 09:36:36 desktop kernel: [  366.919870] ata1.00: status: { DRDY ERR }
 Jul 29 09:36:36 desktop kernel: [  366.919873] ata1.00: error: { UNC }
 Jul 29 09:36:36 desktop kernel: [  366.922281] ata1.00: configured for UDMA/133
 Jul 29 09:36:36 desktop kernel: [  366.922308] sd 0:0:0:0: [sda] tag#12 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
 Jul 29 09:36:36 desktop kernel: [  366.922319] sd 0:0:0:0: [sda] tag#12 Sense Key : Medium Error [current] [descriptor] 
 Jul 29 09:36:36 desktop kernel: [  366.922327] sd 0:0:0:0: [sda] tag#12 Add. Sense: Unrecovered read error - auto reallocate failed
 Jul 29 09:36:36 desktop kernel: [  366.922333] sd 0:0:0:0: [sda] tag#12 CDB: Read(10) 28 00 0c bd 9d 90 00 00 08 00
 Jul 29 09:36:36 desktop kernel: [  366.922337] blk_update_request: I/O error, dev sda, sector 213753237
 Jul 29 09:36:36 desktop kernel: [  366.922357] ata1: EH complete
 Jul 29 09:35:52 desktop colord[1147]: (colord:1147): Cd-WARNING ****: failed to get session [pid 2203]: No existe el dispositivo o la dirección

No hay nada más aterrador que un disco duro que amenaza fallar. Tranquilos, que lo de verdad importante está en la nube y mi partición /home está en el disco de 1 TB .

Las primeras veces, fue durante el arranque del sistema, quedando sin poder alcanzar nunca el escritorio, y al reiniciar con el botón de reset, como el sistema de archivos quedaba marcado como con errores, el siguiente inicio me dejaba en el modo de recuperación.

Allí mandaba un fsck /dev/sda2 -y, que reportaba que había corregido errores. Después podía llegar al escritorio, pero pasaban unos días y nuevamente en la misma situación.

Confiando en el disco duro, culpé a los cables SATA tanto de datos como de corriente. La fuente tiene bien las tensiones así que reemplacé el cable de datos, por uno de calidad, con seguro. Sólo por precaución, decidí cambiar también el de corriente, aunque la fuente era la misma, cambie a una línea de mólex que no tenía uso.

Parecía que esto había hecho el truco, hasta que un día llegaba hasta la pantalla de inicio de sesión, pero al intentar ingresar, jamás conseguía llegar al escritorio. Era hora de aceptarlo, algo le pasaba al disco duro.

Demás está decir, que al cambiarme a una terminal de texto con [CTRL]+[ALT]+[FX] veía los "aterradores" errores relacionados con el primer disco duro.

Es evidente que fsck no estaba haciendo mucho con el tema de los sectores defectuosos. Era necesario identificar todos los sectores defectuosos en vez de esperar a irlos descubriendo sobre la marcha.

Para esto utilicé el comando badblocks.

badblocks tiene un modo destructivo, que escribe en los sectores defectuosos para dar al disco duro la oportunidad de realizar la relocalización, pero no podía arriesgarme a usar este modo sin conocer qué archivos serían reescritos.

Al terminar de procesar el disco completo, encontró un total de 22 sectores defectuosos. Esto también implicaba que el disco duro ya tenía identificado esos sectores. Sólo para estar seguros, había que consultar los registros SMART del disco.

El comando:

 sudo smartctl -a /dev/sda | grep -i reallocated

Arrojaba algo muy diferente de lo esperado, pues el número de sectores defectuosos encontrados por badblocks no coincidía con los sectores relocalizados que reportaba el SMART del disco duro.

Hay otro registro SMART que nos interesa en este caso en particular, y es el de los sectores pendientes (de relocalización). Si nuestros sectores defectuosos en fuga no están en reallocated deben estar en pending.

 sudo smartctl -a /dev/sda | grep -i pending

Y efectivamente, allí estaban.

 197 Current_Pending_Sector  0x0032   200   200   000    Old_age    Always      -
        22

Como ya dije antes, el disco duro jamás decidirá qué información es valiosa. Él sabe que esos sectores necesitan ser relocalizados pero no puede hacerlo porque hay información en ellos.

Sólo existe una forma de decirle al disco duro que estamos dispuestos a sacrificar esa información y que puede realizar la relocalización. Y es escribir el sector completo.

Esto es interesante. No basta con escribir parte de un sector, deberemos escribir todo el sector, o el sector defectuoso seguirá como "pendiente" y no será "relocalizado". En un rato se verá la comprobación científica de que esto es así.

Decidí que no podía seguir sin que esos sectores fueran relocalizados, o seguiría teniendo problemas para llegar a mi escritorio.

Tengo un protocolo definido para cuando hago una instalación limpia de Ubuntu.

Instalo en limpio en caso de actualización de distro, ya que no suelo actualizar la distro con el comando apt dist-upgrade o sus equivalentes más de 1 vez seguidas. Creo que una vez alcancé la cuenta de 2. La razón es que siempre es un lío combinar archivos de configuración y me da la sensación de que el rendimiento es mejor con una instalación limpia. También es una oportunidad para empezar de nuevo con la instalación de paquetes de terceros y tener la oportunidad de tomar mejores decisiones.

El mismo protocolo vale para cuando hay problemas con el sistema, pero eso me pasó sólo una vez que recuerde, y fue causado por la instalación de un paquete de terceros de fuera de los repositorios, ya les contaré esa anécdota algún día.

En resumen, mi protocolo consiste en:

  • Respaldar el directorio /etc que contiene todos los archivos de configuración. Aunque los respaldo todos, después suelo restaurar sólo /etc/apache2 y /etc/samba. Hay que revisar siempre que el formato no haya cambiado entre versiones de esos servidores, cuando cambia toca adaptar las opciones.
  • Respaldar todas las bases de datos de mysql con el comando mysqldump -u root -p --all-databases > alldb.sql
  • Bootear con el Live CD de CloneZilla y crear un respaldo comprimido en gzip de toda la partición de Ubuntu en otra partición (esto es por si me olvido de respaldar algo y necesito recuperar la instalación original, ya sea a su partición original o a una máquina virtual para recuperar lo que me haya podido olvidar. Una vez me olvide de la base de datos y tuve que restaurar la imagen en una máquina virtual para recuperarla. También puede ocurrir que algo sea incompatible con la nueva distro, como la impresora. Borro esta imagen después de unos meses).
  • Bootear con el Live CD de Ubuntu, montar la partición /home y renombrar todos los directorios de los usuarios agregándoles un .bak, por ejemplo mi usuario quedaría jh.bak.
  • Finalmente, instalar Ubuntu. Eligiendo siempre tener control total de lo que ocurre con las particiones pues las decisiones que toma el instalador nunca me dejaron conforme. Suelo formatear la partición de Ubuntu y volver a montar /home, swap, y otras particiones no estándar que tengo sin formatearlas.
  • Una vez en el escritorio del nuevo Ubuntu, recreo a los usuarios del equipo teniendo cuidado de que a cada uno le toque el mismo UID. Si no hiciera esto, después es un lío con los permisos de los directorios que renombré antes, aunque se pueden arreglar recursivamente con el comando chown, es más prolijo si lo consideramos desde ahora.
  • Luego viene la parte de reinstalar el software que sé que vamos a querer. Finalmente, elimino el directorio de cada usuario y le quito el .bak a los que antes había renombrado. Antes de hacer esto, me detengo a pensar si algún archivo de configuración podría no ser compatible con la nueva distro, o directamente lo intento y veo qué ocurre. Lo correcto sería copiar estas carpetas en vez de renombrarlas, hasta estar seguro que ningún archivo de configuración por usuario dará problemas, pero el problema es el espacio que requeriría duplicar cada carpeta. Es bastante seguro hacer esto si se reinstala la misma versión de Ubuntu, pero al pasar a una más actual, sería mejor mover todos los directorios con punto, como .config, a algún otro lado y luego ir probando de a uno, o restaurar sólo los que nos interesan como los perfiles de Thunderbird y Firefox, que nunca me ocurrió que una versión más actual no me quisiera los de una anterior. Normalmente, sólo una minoría de programas los querremos exactamente igual que antes, la mayoría, que de todos modos pueden tener cambios entre versiones, sería mejor empezar de cero otra vez. Esto sería lo correcto pero lleva mucho tiempo, en este caso era seguro restaurarlos todos sin ser selectivo.
  • Restauro /etc/apache2 y /etc/samba.
  • Restauro la base de datos con: mysql -u root -p < alldb.sql

Bien, esta vez hice una modificación a este protocolo. Cuando estaba en el Live CD de Ubuntu, ya habiendo hecho su trabajo el CloneZilla, después de respaldar /etc y la base de datos, decido usar dd para poner a cero todos los sectores de la partición de Ubuntu, para así asegurarme de que se haga la relocalización de los sectores defectuosos.

Creo que no necesito decirlo, pero por las dudas. Esto destruye todos los datos de la partición.

Lo que sigue es interesante.

Mi disco de 500 GB es de 4 KiB de tamaño de sector, pero en ese momento yo no estaba seguro. Así que mi primer intento de dd fue sin especificar el tamaño de sector.

 dd if=/dev/zero of=/dev/sda2
    

Y esto falló con el mensaje:

 dd: error al escribir en '/dev/sda2': Error de entrada/salida
 5636113+0 registros leídos
 5636112+0 registros escritos
 2885689344 bytes (2,9 GB, 2,7 GiB) copied, 89,5995 s, 32,2 MB/s
 

Yo pensé, repasando nuestro conocimiendo de cómo ocurre la relocalización de sectores defectuosos, que tal vez en un segundo intento no se detendría en el mismo punto, sino que pasaría de largo ese y el error daría en el siguiente sector. Mal, y ya explico por qué.

Intenté el mismo comando nuevamente y obtuve el mismo error en exactamente el mismo punto, 5636112+0 registros escritos.

Luego pensé, que para que funcionara como yo esperaba necesitaba especificar el tamaño de sector, pues hay que escribir todo el sector para que el disco duro haga la relocalización silenciosamente. Pero en ese momento no me acordaba si ese disco era de 4 KiB de 512 B de tamaño de sector. Por el tamaño debería ser de 4 KiB, no sé si hayan discos de 500 GB con 512 B de sector, pero de todos modos probemos.

 dd bs=512 if=/dev/zero of=/dev/sda2

Exactamente el mismo error, no pasaba de 5636112+0 registros escritos.

Bien, será con 4 KiB entonces.

 dd bs=4096 if=/dev/zero of=/dev/sda2

¡Bingo! Este fue el mensaje:

 dd: error al escribir en '/dev/sda2': No queda espacio en el dispositivo
 24414465+0 registros leídos
 24414464+0 registros escritos
 1000011644544 bytes (100 GB, 93 GiB) copied, 1107,27 s, 90,3 MB/s

No mal interpreten la aparición de la palabra "error", en realidad obtuvimos exacto lo que buscábamos. Que dd siguiera escribiendo ceros hasta alcanzar el final de la partición. Antes no lo alcanzaba porque ocurría un error de entrada/salida, este error no ocurrió al usar 4096. ¿Por qué? Por lo que explicábamos más arriba, acerca de qué condiciones se tienen que cumplir para que el disco duro realice la relocalización de forma silenciosa.

También noten que la velocidad de escritura fue mayor al usar el tamaño correcto que coincide con el tamaño de sector del disco.

En ese entonces no se me ocurrió que 4 KiB es múltiplo de 512 B y que usando 4096 hubiera funcionado a la primera. Pero si lo hubiera hecho así no habríamos tenido la comprobación científica de que los discos necesitan que se escriba el sector entero para relocalizarlos.

Ahora usemos smartctl para ver qué pasó con los contadores de reallocated y pending.

 197 Current_Pending_Sector  0x0032   200   200   000    Old_age    Always      -
        0
       

pending está en cero, el 22 ha desaparecido, por lo tanto se fueron a reallocated.

Hemos hecho por este viejo disco duro lo que hemos podido. Si vuelve a dar problemas tocará buscar la manera de reemplazarlo por uno igual o más grande.

Mi actual instalación de Ubuntu tiene muy buen rendimiento y ya no veo los errores ata cuando miro los Sucesos del sistema.

¿Por qué no usar DBAN?

Lo he usado. Por ejemplo, si alguien dona a una ONG o regala un disco duro, yo siempre les comento que sería recomendable poner el disco a cero, incluso hacer un borrado seguro. DBAN es ideal para eso.

Pero aquí intentamos hacer una intervención "quirúrjica", arreglar el órgano dañado sin tocar el resto del organismo. Yo sabía que sólo la partición de Ubuntu presentaba sectores defectuosos, y por lo tanto quería poner a cero esa partición, no quería tener que reinstalar también Windows o tener que copiar todo el disco a otro disco más grande para así poder pasar DBAN al disco entero.

¿Qué hacer con discos de transición?

La verdad, no lo sé. Creo que lo correcto es usar 4 KiB. De todos modos, de la experiencia que describo, se deduce que probar con dd el tamaño de sector incorrecto no tiene ninguna consecuencia catastrófica. Prueben con 4 KiB y si no funciona vuelvan a probar con 512 B. Lo malo es que si sus sectores defectuosos están al final de la partición van a tener que esperar bastante por los resultados de la prueba.

Por otro lado, 4 KiB es múltiplo de 512 B, por lo que funcionaría a la primera usando 4 KiB.

Hasta donde sé, no hay riesgo de que dd escriba más allá del límite de la partición siempre y cuando hayamos escrito lo correcto en el parámetro of. Pero con esto es mejor ser paranoico, así que quizá quieran probar primero con el tamaño de sector más pequeño.

¿Cómo accedo a los datos SMART de mi disco duro?

Primero que nada, se debe verificar en la BIOS que SMART esté habilitado. No puedo decirles cómo, cada fabricante de cada placa base tendrá su manera. Les dejo, a modo de ejemplo, un vídeo para una placa ASUS y les doy la siguiente pista: suele estar en la misma página donde se detectan los discos duros y las unidades ópticas y la página suele llamarse Standard o Standar BIOS Setup en BIOS AMI. Recuerdo BIOS Phoenix que ponen los discos duros ya en la primera página, sin necesitar entrar dentro de una categoría.

En Linux, puedes consultar las estadísticas de tus discos con:

Con interfaz gráfica, está el "GNOME Disks", nada más escriban "discos" en el dashboard.

Desde una terminal de texto, smartctl.

En Windows, Piriform Speccy es gratuito y organiza la información obtenida del SMART en forma de tabla, por lo que es fácil de navegar. También ayuda a su interpretación al marcar con colores el estado de cada registro. Por ejemplo si tienes algunos sectores defectuosos pondrá "Good" en verde y si son muchos pondrá "Bad" en rojo.

En los casos que el disco duro detecta el sector defectuoso durante una operación de lectura y no se atreve a realizar la relocalización de forma automática. ¿Por qué no se atreve, si el sector ya está perdido?

No es difícil de razonar, pero hay que simular algunos casos para entenderlo.

El sector puede contener todo o parte de un archivo importante de sistema. A lo que podrían preguntarme ¿Y, si ya está perdido? Pero supongamos que el sector contiene parte del registro de Windows, en concreto el hive de HKLM. Devolver ceros o una secuencia aleatoria al leer de ese sector podría tener concecuencias impredecibles, es mejor romper el silencio y que se produzca un error de entrada/salida para que el sistema operativo tenga la oportunidad de hacer algo al respecto.

Y no alcanza con romper el silencio una sola vez y luego hacer la relocalización. Porque no hay garantías de que el sistema se acordará después de que esa información no es confiable, es mejor seguir fallando siempre que se intente leer ese sector. Después de todo, el disco no sabe con qué sistema operativo está interactuando.

El disco sólo opta por el silencio cuando sabe que es inofensivo hacerlo.

Supongamos que hemos almacenado en una clave del registro la velocidad de giro de un fan (un fan ficticio que hemos imaginado para el ejemplo, no tiene por qué ser el del procesador, y además nuestro fan ficticio es controlado por software). Si esa información no es confiable, definitivamente el sistema operativo quiere saberlo. Entonces puede establer la velocidad de giro a su valor por defecto, en vez de establecerla a cero o un número aleatorio cualquiera, lo que podría resultar en daños para el hardware.

Otro ejemplo, un archivo BMP. Al menos que esté dañada la cabecera del archivo, que es la parte del archivo donde está indicado las dimensiones de la imagen así como su profundidad de bits, casi cualquier secuencia de Bytes es válida para el cuerpo del archivo. A veces el daño será detectable para el humano al teclado, a veces ni eso, ya que si el humano no conoce la imagen original podría no saber que esa línea gris en el cuarto inferior de la imagen o ese cuadro negro a la derecha no estaban en la imagen original. En este caso también es mejor romper el silencio y que el usuario reciba un mensaje.

Se pierde mucho tiempo revisando el syslog todos los días

Automaticemos la tarea entonces. El siguiente script lo pueden agregar al inicio del sistema o de su sesión. Yo opté por agregarlo en "Aplicaciones al inicio", con el comando: sh -c "cd /home/jh/scripts/check_ata_errors; python check_ata_errors.py"

    #!/usr/bin/env python

    from subprocess import call
    import signal
    import time

    must_exit = False

    def exit_gracefully (signum, frame):
        exit()
        # global must_exit
        # must_exit = True

    signal.signal(signal.SIGINT, exit_gracefully)
    signal.signal(signal.SIGTERM, exit_gracefully)

    while must_exit == False:
        logf = open("/var/log/syslog", "r")
        outf = open("log.txt", "a")
        warning = False
        
        line = logf.readline()
        keys = ['I/O error', 'failed command: READ FPDMA QUEUED', 'status: { DRDY ERR }', 'error: { UNC }']
        
        count = 0
        max_count = 1000
        while (line != ''):
            for key in keys:
                if line.find(key) > -1:
                    outf.write(line) 
                    warning = True
            line = logf.readline() 
            count += 1
            if count >= max_count:
                break
        
        outf.flush()
        outf.close()
        logf.close()
        
        if warning == True:
            call(["zenity", "--error", "--text=Se encontraron errores relacionados con el disco duro."])
            call(["xdg-open", "log.txt"])
        
        time.sleep(30 * 60) # 30 minutos

El script buscará algunas cadenas de texto que yo considero que si llegan a aparecer en syslog alguna vez necesitan que un humano les "heche un ojo". Cuando inicio sesión, si se detecta una línea en syslog con alguna de esas cadenas de texto clave, aparecerá un diálogo de error diciendo que se encontraron errores relacionados con el disco duro, y al aceptar ese diálogo se abrirá el editor de texto (gráfico) por defecto, gedit en mi caso, con las líneas en cuestión. Si quiero profundizar más, puedo ir a "Sucesos del sistema" y buscar las líneas, ya que algunos mensajes ocupan más de una línea pero mi script, hecho a las apuradas, sólo guarda la primera línea de cada mensaje.

Se podría revisar también los registros de días anteriores, por lo que puedo ver en /etc/logrotate.conf Ubuntu está guardando 1 semana de logs. Por ejemplo, el log del día anterior está en /var/log/syslog.1. El script podría revisar también éstos, pero tiene más sentido tenerlo siempre en ejecución y cada 30 minutos volver a comprobar el log del día.

Ojo con copiar y pegar, las tabulaciones son importantes para garantizar que time.sleep() ocurra dentro del bucle while.

Actualización: este script no es perfecto, está pensado para reportar cualquier cosa que diga "I/O", por lo que también puede saltar en situaciones que no tienen que ver con errores del disco duro. Por ejemplo: el otro día conecté un J2 Prime a un puerto USB de este equipo y Ubuntu no consiguió montarlo, produciendo errores como estos: "Error 02ff: PTP: I/O error", no tiene nada que ver con el disco duro pero como dice "I/O error" saltó el diálogo. Inicialmente me preocupé, pero luego vi que había sido causado por el celular.

0 comentarios:

Publicar un comentario