sisoputnfrba / foro

Foro de consultas para el trabajo práctico
151 stars 7 forks source link

Iniciar Proceso en Filesystem #3318

Closed diegohcanetti closed 11 months ago

diegohcanetti commented 11 months ago

Nostros definimos una estructura de bloque que solamente tiene la data definida como un char. Esto lo hicimos ya que en el enunciado se hace mención a que cada bloque se inicializa con un \0. Sin embargo, no estamos seguros si tratarlo como un char o como un void? Ya que los bloques pueden tener cualquier data y capaz una implementación correcta sería con un void.

📔 Citas del enunciado/videos

Al momento de reservar un bloque, el mismo deberá rellenarse con '\0', el algoritmo y las estructuras necesarias para la gestión de estos bloques serán definidas por el grupo.

iago64 commented 11 months ago

Buenas! Cómo va?

Algo super importante de C es que el tipo de dato la mayoría de las veces es algo anecdótico, uds pueden tener algo definido como void* y usarlo despues como char* y viceversa, por lo que, en principio, los bloques de SWAP si, los tienen que rellenar con '\0' o pueden usar mmap() y grabarle el valor 0, es indistinto, la idea es que al momento de asignar una página limpia de SWAP a un proceso, la misma no tenga basura de una ejecución anterior.

Saludos.-

diegohcanetti commented 11 months ago

Aaa bueno, me fijo entonces en el hilo de como se usa correctamente mmap, pero en principio hariamos un write() con 0 y utilizamos mmap sobre el espacio de swap?

diegohcanetti commented 11 months ago

image

Así me quedó inicializado el archivo de bloques (sin páginas asignadas) es correcto? Cómo se si está bien implementado?

iago64 commented 11 months ago

Buenas!

En principio lo que debería pasarte es que todo el archivo este lleno de 0. Ahi en la imagen que pasas el archivo tiene pinta de ser más grande de lo que hace falta, porque veo que hasta la dirección 401f0, está lleno de 0 y después empieza a tener otros caracteres.

Saludos.-

diegohcanetti commented 11 months ago

Así tiene más sentido Dami? image

diegohcanetti commented 11 months ago

Hola buenas estuve leyendo más acerca del mmap y quería mapear una parte con un vector de swap o otro para un vector de FAT, para ello hice las siguientes cuentas: espacio_de_swap = (cant_bloques_swap tam_bloque) - 1; espacio_de_FAT = sizeof(uint32_t) (cant_bloques_total - cant_bloques_swap);

Con esto mapee el swap: char* swap_mapeado = mmap(0, espacio_de_swap, PROT_WRITE, MAP_SHARED, fd_bloques, 0);

Y el FAT: char* fat_mapeado = mmap(0, espacio_de_FAT, PROT_WRITE, MAP_SHARED, fd_bloques, espacio_de_swap);

Pero al intentar rellenarlo:

// Inicializo la memoria mapeada de la partición de SWAP 
    for (int i = 0; i < espacio_de_swap; i++) {
        swap_mapeado[i] = '\0';
    } 

Obtengo este error, que según estuve bien es cuando tomas una cantidad de espacio de memoria errónea, sin embargo me parece que hice las cuentas correctas: ./exec: line 6: 5288 Bus error (core dumped) ./$FILE

Valgrind

==5538== Process terminating with default action of signal 7 (SIGBUS)
==5538==  Non-existent physical address at address 0x485B000
==5538==    at 0x10AC5F: levantar_archivo_bloque (filesystem_bitmap.c:42)
==5538==    by 0x10ADFE: main (filesystem.c:42)
LeandroCarbajales commented 11 months ago

Buenas! Veo varias consideraciones para marcar. espacio_de_swap = (cant_bloques_swap * tam_bloque) - 1; Por qué el "-1"?

espacio_de_FAT = sizeof(uint32_t) * (cant_bloques_total - cant_bloques_swap); Ojo que acá estás calculando el tamaño de la tabla FAT, no de la partición FAT (los bloques).

Con respecto al mmap, primero aclarar que no es necesario para operar con el archivo de bloques. Luego, el error me suena a que podría ser que el archivo sea más chico de lo que estás mapeando, están truncando el archivo al tamaño correspondiente antes de mapearlo a memoria?

diegohcanetti commented 11 months ago

No he truncado nada solo quería probar de levantarlo con 2 "particiones" de mmap el archivo_de_bloques. El -1 es pq entendí eso en este issue #3317. Aaaa la particion sería entonces CANT_BLOQUES_TOTAL * TAM_BLOQUE (tamaño de archivo de bloques) - espacio de swap?

Se que no es necesario el uso del mmap(), pero como Dami lo recomendó mucho y puede ser muy util para el acceso directo ya que según entendí puedes hacer puntero mmap[tam_leer/tam_bloque] = Bloque que hay que leer

LeandroCarbajales commented 11 months ago

No he truncado nada solo quería probar de levantarlo con 2 "particiones" de mmap el archivo_de_bloques.

El mmap() solamente mapea un archivo para que se pueda acceder como si fuera memoria, el archivo en sí ya debe existir y tener el tamaño correspondiente, lo que probablemente esté ocurriendo es que estén haciendo un mmap más grande que el tamaño del archivo, por lo cual les va a fallar al accederlo. Justamente como les respondió Dami en ese issue, CANT_BLOQUES_TOTAL * TAM_BLOQUE les va a dar el tamaño del archivo de bloques (completo), luego ustedes lo pueden operar directamente con fread() y fwrite() o mapear la parte de SWAP y de FAT por separado como están intentando hacer.

diegohcanetti commented 11 months ago

Pero el espacio de swap entonces es: espacio_de_swap = (cant_bloques_swap * tam_bloque) - 1; O es espacio_de_swap = (cant_bloques_swap * tam_bloque) ; Si no logro arreglar el mmap lo utilizo con las syscalls de archivo y fue, pero me hubiera gustado usarlo como lo tenía pensado para acceder a los bloques de la manera en sí.

LeandroCarbajales commented 11 months ago

El tamaño es sin el -1 😄 Truncando el archivo al tamaño que corresponde y arreglando los tamaños de cada mmap te debería funcionar :)

diegohcanetti commented 11 months ago

Lean se me vino otra duda actualmente mapee la tabla FAT, la partición de FAT y el SWAP. El tema es que para leer el archivo lo que estoy haciendo es voy accediento al bloque_inicial del FCB y me fijo si es UINT32_MAX(EOF), si es el bloque_final_que_leer (puntero_archivo/tam_bloque) o si es otro bloque, por lo tanto actualizo al bloque anterior. Te muestro en código (codeado por el momento pobremente) para que entiendas:

t_list* lista_de_bloques_a_leer = list_create();
        // Si es EOF
    if(tabla_fat_en_memoria[bloque_inicial] == UINT32_MAX) 
    {
        list_add(lista_de_bloques_a_leer, tabla_fat_en_memoria[bloque_inicial]);
    }
        //Un nuevo bloque
    if(tabla_fat_en_memoria[bloque_inicial] != UINT32_MAX) {
        list_add(lista_de_bloques_a_leer, tabla_fat_en_memoria[bloque_inicial]);
        uint32_t nuevo_bloque_a_leer = tabla_fat_en_memoria[bloque_inicial];
        if (tabla_fat_en_memoria[nuevo_bloque_a_leer] == UINT32_MAX) // Se vuelve recursivo
    }
        //Ultimo bloque a leer
    if(tabla_fat_en_memoria[bloque_inicial] == bloque_que_hay_que_leer) {
        list_add(lista_de_bloques_a_leer, tabla_fat_en_memoria[bloque_inicial]);
    }

Hablando con mis compañeros me surgieron 2 dudas:

  1. Yo estoy guardando los datos de los bloques (los 4 bytes) en una lista para después leer todos los bloques de corrida en la partición de swap, pero un amigo del grupo me dijo que nosotros solamente vamos a leer 1 bloque, quisiera corroborar esto.
  2. El contenido de los archivos, en la partición de swap, lo voy a obtener haciendo un particion_fat_mapeada[uint32_t] de cada uno de los bloques que obtuve en la lista_bloques_a_leer? O en la particion de FAT si recomiendas hacer un fread()?
iago64 commented 11 months ago

Buenas! Cómo va?

1.- Si, tanto para los Page Fault, como para F_READ y F_WRITE van a leer / escribir de a 1 bloque.

2.- Cuidado con mezclar las particiones, en la partición de SWAP del archivo de bloques solo deberían tener páginas de memoria y en la partición de FAT los bloques de archivos. Despues como manejen el archivo de bloques queda a criterio de cada grupo, puede ser usando fopen(), fseek(), fread() y fwrite() u open(), mmap() y memcpy()

Saludos.-

diegohcanetti commented 11 months ago

Aaaa sisisi, me equivoque escribiendo en el issue, pero eso lo tengo claro. Creo que ya me quedo todo más claro, gracias Dami y Lean :)