09 noviembre 2006

Programa en C para reventar discos duros

Test de rendimiento

Supongo que nadie quiere destrozar (o intentarlo) su disco duro, pero en mi trabajo es importante comprobar su fiabilidad. Por eso he escrito un programa en C (que ejecuto en Windows, aunque tengo que compilarlo en Linux y supongo que con pequeñas variaciones estará listo) con este fin, comprobar si los discos son realmente duros.

Este programa genera ficheros de 1 GB y los copia en el disco duro hasta llegar al tope de Gigabytes indicados. Este proceso se repite desde 1 hasta infinitas veces, según deseemos.

¿Por qué lo pongo aquí? Por que con el he reventado 2 discos duros Seagate ST3160211AS. Con HD Tach 2.61, una aplicación para comprobar la tasa de transferencia en lectura y escritura, al llegar a los 65 GB aproximadamente la escritura baja a niveles irrisorios (ver línea verde de la gráfica), síntoma de que algo falla. Obviamente la prueba con HD Tach antes de pasar el test que he creado fue correcta.

Os dejo el código por si lo quereis utilizar. Perdonad si no sale tabulado.

-------------------

/*********************************************************************
El programa copia bloques de 1GB en el disco duro hasta que llegue
a GB. En este punto borra todos los bloques y
continua iteraciones.

Si es 0 realizará infinitas iteraciones hasta que el
programa sea cortado con Control-C
*********************************************************************/

#include
#include

using namespace std;

void informacion_entrada()
{
printf("\nError: no introdujo los parametros correctos\n\n");
printf("\n \n\n");
printf(" -> Por ejemplo, c:, d:,...\n");
printf(" -> GigaBytes maximos a copiar (por ejemplo 100, 110,...)\n");
printf(" -> Iteraciones a realizar, 0 para infinito\n\n");
printf("Ejemplo de ejecucion: h: 110 5\n");
}

/**************************************************************************
Envejecimiento con n iteraciones
**************************************************************************/
void envejecimiento_n(char* filename,int maximo_a_copiar,int iteraciones)
{
FILE *destino;
double total_copiados_iteracion=0.0,total_copiados=0.0;
unsigned long bytes_copiados=0;
char nombre_fichero[5];
char* numero=(char*)malloc(sizeof(char)*2);
int ficheros;

printf("\nEnvejecimiento de unidad %s, se moveran %d GB aproximadamente\n",filename,maximo_a_copiar*iteraciones);
printf("--------------------------------------------------------------\n");

for(int iter=0;iter!=iteraciones;iter++)
{
total_copiados_iteracion=0.0;
ficheros=0;
do
{
strcpy (nombre_fichero,filename);
numero=itoa(ficheros++,numero,10);
strcat (nombre_fichero,numero);

if (!(destino=fopen(nombre_fichero,"w")))
printf("No pude abrir el fichero de destino.\n");

do
{
fputs("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij",destino);
bytes_copiados+=100;
}
while (bytes_copiados!=1000000000);

fflush(destino);
fclose(destino);

total_copiados_iteracion+=0.931322;
total_copiados+=0.931322;
bytes_copiados=0;

printf("%f GB copiados\n",total_copiados);
}
while ((total_copiados_iteracion+0.931322)
//BORRA FICHEROS
for (--ficheros;ficheros>=0;ficheros--)
{
strcpy (nombre_fichero,filename);
numero=itoa(ficheros,numero,10);
strcat (nombre_fichero,numero);

destino=fopen(nombre_fichero,"w");
fputs("",destino);
fclose(destino);
}
}
}

/**************************************************************************
Envejecimiento infinito
**************************************************************************/
void envejecimiento_infinito(char* filename,int maximo_a_copiar)
{
FILE *destino;
double total_copiados_iteracion=0.0,total_copiados=0.0;
unsigned long bytes_copiados=0;
char nombre_fichero[5];
char* numero=(char*)malloc(sizeof(char)*2);
int ficheros;

printf("\nEnvejecimiento infinito de unidad %s, finalice con Control-C\n",filename);
printf("----------------------------------------------------------------\n");
while (true)
{
total_copiados_iteracion=0.0;
ficheros=0;
do
{
strcpy (nombre_fichero,filename);
numero=itoa(ficheros++,numero,10);
strcat (nombre_fichero,numero);

if (!(destino=fopen(nombre_fichero,"w")))
printf("No pude abrir el fichero de destino.\n");

do
{
fputs("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij",destino);
bytes_copiados+=100;
}
while (bytes_copiados!=1000000000);

fflush(destino);
fclose(destino);

total_copiados_iteracion+=0.931322;
total_copiados+=0.931322;
bytes_copiados=0;

printf("%f GB copiados\n",total_copiados);
}
while ((total_copiados_iteracion+0.931322) //BORRA FICHEROS
for (--ficheros;ficheros>=0;ficheros--)
{
strcpy (nombre_fichero,filename);
numero=itoa(ficheros,numero,10);
strcat (nombre_fichero,numero);

destino=fopen(nombre_fichero,"w");
fputs("",destino);
fclose(destino);
}
}
}

/************************************************************************
Main
************************************************************************/
int main(int argc, char *argv[])
{

char unidad[4],iteraciones[4],capacidad[4];

printf("\nBurn Storage Devide 1.0\n\n");

printf("Introduzca la unidad a verificar (por ejemplo, c: ) --->");
scanf("%s",unidad);
printf("Introduzca las iteraciones, 0 para infinitas ) --->");
scanf("%s",iteraciones);
printf("Introduzca la capacidad maxima de la unidad en GB (por ejemplo, 100 ) --->");
scanf("%s",capacidad);

if (atoi(iteraciones)!=0) envejecimiento_n(unidad,atoi(capacidad),atoi(iteraciones));
else envejecimiento_infinito(unidad,atoi(capacidad));

system("PAUSE");
return EXIT_SUCCESS;
}

2 comentarios:

Anónimo dijo...

Pues el primer virus que programé fue precisamente un gusano, es lo más sencillo de hacer. Aunque no me lié tanto como tú (es que no sé programar xD), sencillamente abría un fichero y lo llenaba de bytes mientras se cumplía la condición del while (que nunca se negaba, a saber, while 5 > 4). Por supuesto, el tuyo es más profesional, aunque no creo que lo pruebe con mi disco duro ;-)

PD No sé si blogger te permite introducir etiquetas HTML, pero si quieres que un texto salga tabulado igual que lo habías escrito, enciérralo entre etiquetas pre :-)

Joaquín dijo...

No te recomiendo que ejecutes el programa a menos que tengas un disco duro de alta calidad, le mete mucha caña!

Cuando quieras hacer un ciclo infinito bata con poner while (true).

Gracias por el apunte de las etiquetas, lo probaré.