Sistema de archivos: Directorios

*Nota: Para los directorios podíamos usar registros de tamaño fijo o variable. Como a efectos de lo que vamos a ver nos da igual, vamos a suponer registros de tamaño fijo.

Lo primero que vamos a ver es que hay dos formas de guardar la información en un directorio. La primera forma, o forma A es guardar en cada entrada del directorio el nombre o identificador del archivo junto a sus atributos. La otra forma o forma B es guardar el nombre y una referencia a una estructura que mantiene los metadatos y que ya vamos a llamar por su nombre, inodo.

En un disco duro, donde el espacio es asignado en bloques, si elegimos la modalidad A, deberá haber siempre en todos los sistemas una cosa que vamos a llamar ‘/’ y que se corresponde con el directorio inicial, el directorio raíz del sistema que ya explicaremos más detalladamente y a partir del cuál construiremos toda la jerarquía de directorios. Este nodo raíz, dependiendo de la modalidad, en este caso la A, en cada registro tendré o un directorio o un archivo (por ahora prescindiremos de los archivos de dispositivo), en el caso de los directorios con un atributo que lo identifique como tal, y todos sus atributos, incluyendo la localización. ¿Qué serán los metadatos de ese directorio? Pues …

Sistema de archivos: Introducción

Tema 1: Implementación del sistema de archivos

  1. Introducción
  2. Implementacion
  3. Estructura de almacenamiento secundario

En la introducción, por si alguno tiene todavía la visión del usuario, intentaremos entender que un archivo realmente es una estructura de datos que tiene un sistema operativo para gestionar la información en disco.

En cuanto a la implementación, hablaremos de las distintas maneras que hay de implementar este concepto de archivo y de dos cosas que son fundamentales en el sistema de archivos, que será algo parecido a la memoria que estudiamos en SOI.
Por una parte tenemos que saber como se gestiona el espacio en disco. Pensad en la analogía de proceso-archivo. Si en un proceso teníamos una estructura del siguiente tipo:

STRUCT{
- MEMORIA:
· Asignar(paginación, segmentación)
· Gestionar (fragmentación, gestión de espacio libre)
etc…
}PROCESO

En un archivo tendremos una estructura similar, de la siguiente forma:

STRUCT{
- MEMORIA:
· Asignar espacio en disco (bloque físico de disco, similar a paginación)
- Campo1
- Campo2

- CampoN
(Aprenderemos qué hay en cada uno de estos registros)
}ARCHIVO

Esta estructura es la que hay que entender. Los campos nos permitirán gestionar u organizar los archivos mediante el sistema operativo. ¿Qué campos nos encontraremos? Lo iremos viendo a lo largo del tema. Un campo muy importante es de la memoria; volviendo a la analogía con los procesos, en el tema de la memoria vimos dos cosas muy claras: una cómo se asigna y otra cómo se gestiona. En los procesos, el campo de la memoria se encargaba de asignar un espacio en memoria principal, ya sea mediante paginación, segmentación o segmentación paginada, para que pudiera ejecutarse. En los archivos, en el campo de la memoria debemos tener igualmente alguna cosa que nos permita asignarle un espacio en disco.

En el espacio en disco, lo que varía con respecto a la memoria es que es mucho más inteligible en la organizacion porque si recordamos de SOI, la memoria estaba dividida en páginas o segmentos que conformaban el bloque de memoria; aquí en cambio, el bloque de memoria es el bloque físico, eso significa que cualquier medio de asignación de espacio en disco va a asignar espacio libremente por sectores de disco. Siempre lo asigna en unidades de bloque y podemos ver una analogía total entre bloque de disco y espacio en sistemas con paginación, porque realmente es cada una de las unidades en que se divide el espacio asignable y que tiene un tamaño fijo determinado por el sistema.

Con respecto a la asignación de espacio en disco, si hemos dicho que es totalmente análogo a la paginación, simplemente habrá que marcar, o habrá que tener una tabla de qué bloques están ocupados y qué bloques están libres.

Muchos campos se comparten con el proceso. Nomrbre, tamaño, memoria, protección…

Por último en cuanto a implementación, además de tener muy claro cómo se rellenan todos los campos, hay que tener una cosa adicional en cuenta, y es que desgraciadamente la organización de archivos se hace mediante directorios, aunque afortunadamente cada vez está más en deshuso. El directorio no es más que un tipo de archivo especial para organizar otros archivos, incluidos otros de tipo directorio.

La estructura de almacenamiento secundario no es más que una visión general para que entendamos la problemática, digamos, cómo se diseñan los algoritmos del sistema operativo teniendo en cuenta las características del dispositivo de almacenamiento. No vamos a hablar de flash ni de otra estructura de almacenamiento sino del clásico disco duro (digamos que las otras presentan menos problemas). El disco duro, si lo hemos estudiamos someramente un poco por encima veremos cómo se comportan las tasas de transferencia dentro del disco duro y cuándo se comporta mejor y peor. Intentaremos ver qué algoritmos, basándonos en esta información, podemos hacer para hacer lo más eficiente posible el acceso al a información en disco.

1. INTRODUCCIÓN:

De acuerdo con la transparencia el concepto de archivo viene definido de la siguiente forma:

  • Colección de información relacionada y almacenada en un dispositivo de almacenamiento secundario.

Empezaremos hablando de un atributo fundamental que falta en esta definición, el identificador. El nombre es tan importante que es un campo de la estructura Archivo. Ya tenemos la primera cosa relevante a rellenar. En un directorio tenemos los archivos identificados por el nombre.

  • Espacio de direcciones lógicas contiguas

Esto es muy interesante porque vuelve a ser una analogía cono lo visto en SOI. ¿Cómo separo el conjunto de direcciones lógicas del conjunto de direcciones virtuales de un proceso? En SOI vimos el conjunto de direcciones lógicas eran aquellas que podíamos colocar directamente en el contador de programa de la cpu para trabajar con ese programa. Respecto a las virtuales -> bloques <>

Para un programador de sistemas un archivo es una secuencia de bytes de tamaño N. Eso es lo que quiere decir espacio de direcciones lógicas contiguas. Y con eso podemos trabajar como nos dé la gana. Un programador de aplicaciones deberá tener en cuenta el tipo de codificación para un archivo (UTF-8,binario…) para nosotros, como programadores de sistemas, simplemente es una secuencia de bytes. Esto tiene que quedar muy claro, porque si por ejemplo hacemos un OPEN de un archivo y consideramos que el archivo se divide, por ejemplo en bloques de 4 bits, la información que extraigamos no tendrá ningún sentido. Por eso la unidad de información que usaremos será el byte.

  • Estructura interna (lógica)
    - Secuencia de bytes: El tipo de archivo determina su estructura (texto->caracteres,líneas y páginas; código fuente->secuencia de subrutinas y funciones).
    - Secuencia de registros de longitud fija.
    - Secuencia de registros de longitud variable.

Como acabamos de decir, un archivo tendrá interpretaciones diferentes para el usuario final o para el programador de aplicaciones; para nosotros simplemente es una secuencia de bytes.
Lo de secuencia de registros de longitud fija y longitud variable es análogo a lo que vimos en memoria. Lo que tenemos que tener en cuenta es qué implica que yo, como programador de aplicaciones, tenga un archivo de registros de longitud fija o archivos de registros de longitud variable: Que, al igual que en paginación y segmentación, si tenemos bloques de tamaño variable, tenemos que tener asociado a cada bloque el tamaño del mismo. Eso es lo único que nos interesa.

  • Tipos de archivos: regulares, directorios, de dispositivo

Esto sí que es interesante, porque son los tres tipos de archivos que existen para un programador de sistemas. En primer lugar, todos los archivos de cualquier tipo son regulares.
¿Qué es un directorio entonces? Es un tipo especial de archivo que lo único que contiene es organización. Sólo contiene unos registros especiales que contienen el nombre y los atributos de cada archivo (o inodos, que ya veremos más adelante). Por cierto que todos estos registros son de longitud variable, ya que así lo es la longitud de los nombres de los archivos.

El tercer tipo ya tiene que ver un poco con otra cosa, ya que eso de los archivos de dispositivo es una abstracción. Es utilizar el sistema de archivos para contar una nivel, una capa superflua con respecto a los drivers.

… en el hardware debe haber un controlador. Cuando ya entramos en la parte del sistema operativo, debe haber un driver [min 19]. Normalmente el driver implementa una interfaz independiente de dispositivo. Esto es lo que necesita el núcleo del SO para trabajar. ¿Por qué es idnependiente? [19:45]. Ejemplo con read. [21]. Los archivos son la abstracción para el programador de aplicaciones. Tú puedes hacer que determinados archivos representen un dispositivo concreto.

[extensión, inciso prácticas 26]

Atributos (metadatos):

Los atributos o metadatos son los campos que yo relleno en la estructura tipo archivo para que el sistema operativo gestione los mismos.

  • Nombre: Única información en formato legible

Aquí ya vemos lo que faltaba en la definición incial, el nombre. Tan importante es el nombre que es el único elemento que es visible para el usuario.

  • Tipo: Cuando el sistema soporte diferentes tipos

Por ejemplo, ¿qué tipos de archivos soporta linux o windows? En general los tipos regulares, que ya sabemos que son todos, o por ejemplo los tipos “acceso directo”, que todos intuitivamente sabemos lo que son. Los de dispositivo, los directorios…

  • Localización: Información sobre su localización en el dispositivo.

Esto es muy importante. … esto es lo que hablábamos de la memoria en SOI [?28] . Esto depende del tema de la asignación de espacio en disco. Es un campo tan importante como el de memoria.

  • Tamaño: Tamaño actual del archivo.

Esto está claro. Normalmente usamos “size” para referirnos a ese campo.

  • Protección: Controla quién puede leer, escribir y ejecutar.

Esto está claro. Realmente esta definición no está del todo bien pero sirve para aprender. La protección dice quién puede hacer qué operaciones. Las operaciones clásicas que se permiten hacer sobre un archivo son leer, escribir y ejecutar (r,w,x)

  • Tiempo, fecha e identificación del usuario: necesario para protección, seguridad y monitorización

Operaciones de gestión:

Llamamos operaciones de gestión a las que son típicas que yo construiría con un tipo de tipo abstracto (pila, cola…) ¿cuáles?

  • Crear

Se crea un archivo, que es una estructura, y me pongo a rellenar campos.

  • Borrar

Obviamente puedo eliminar cualquier tipo de archivo.

  • Renombrar

Esto es una operación superchorra que nos permite cambiar el nombre del archivo, simplemente

  • Copiar

Es necesario que tengamos esto claro para cuando veamos los archivos tipo enlace. Requiere encontrar un sitio nuevo, un nombre nuevo y cada uno de los bloques de disco asignados al primer archivo tendrán que estar asociados al segundo archivo. Hay que reservar un montón de bloques nuevos. … problemas de inconsistencia [35-38]

  • Establecer y obtener atributos

Esto es lo típico de los datos abstractos cuando hacemos “get” o “set”.

Operaciones de procesamiento:

Esto es más difícil, es la administración. Una cosa es crearle la estructura, cambiarle el nombre, hacer una copia. Ahora cuidado, ¿qué se hace con los archivos? Esto son operaciones generales

  • Abrir y cerrar

¿Abrir y cerrar por qué? Es simplemente una corriente entre el dispositivo de almacenamiento del archivo y la memoria RAM. Implica que una vez que he abierto un archivo, como la información está en disco tengo que traérmela a memoria. Mientras tengo el archivo abierto lo mantendré en memoria, y cuando lo cierre lo devolveré al disco duro.

  • Leer y escribir

Escribir engloba que puedes modificar, que puedes insertar, si el archivo no es de acceso secuencial no vas a poder hacerlo en cualquier sitio. Si lo pudieras hacer, para nosotros, que un archivo es una secuencia de bytes con un puntero de lectura y escritura que nosotros podemos colocar donde queramos. Esto da problemas que ya contaremos.
Leer entonces será leer alguno de los bytes del archivo y escribir será escribir alguno de los bytes de nuestro archivo.

FTC: Agrupaciones de elementos

- Resistencias:

  • Serie
  • Paralelo

- Condensadores:

  • Serie
  • Paralelo

- Fuentes de tensión en serie
- Fuentes de intensidad en paralelo

- Resistencias en serie:
Están en serie si al intensidad que pasa por ellas es la misma y las podemos sustituir por una resistencia equivalente cuyo valor es:

- Resistencias en paralelo:
Están en paralelo si tienen la misma diferencia de potencial

ISI 18-10-2007: Principios de diseño:

PRINCIPIOS DE DISEÑO:

  • Hay que tener en cuenta enfoques alternativos.
  • Debemos poder rastrear el diseño hasta el modelo del análisis.
  • No hay que reinventar lo ya inventado (patrones de diseño).
  • La separación entre dominio del problema y dominio de la solución debe ser minimizada.
  • El diseño debe ser uniforme e íntegro.
  • Se tiene que estructurar el diseño para facilitar los cambios.
  • Debe ser flexible para que pueda admitir los cambios con facilidad.
  • El diseño no es escribir código y escribir código no es diseñar.
  • La calidad de un diseño hay que evaluarla durante su realización, no una vez terminado.
  • Es importante revisar el diseño en busca de errores conceptuales (semánticos)

La I.S. tiene estos principios universales en los que basarse. Lo más destacable es que tenemos que plantearnos si el problema está ya resuelto y documentado: “no inventes lo que ya está inventado”.
Principios específicos de diseño: son cuatro (trans):

  • Modularidad
  • Abstracción
  • Independencia funcional
  • Ocultamiento de información

Hay que tratar de conseguirlos.

Modularidad:
¿Qué es la modularidad? ¿Cómo tienen que ser nuestros diseños? Nuestro diseños debe de componer de piezas y sus relaciones entre ellas.
Es necesario dividir el software, de manera lógica, en un conjunto de módulos, donde cada uno realiza una sola actividad y con una interfaz bien definida.
Estos módulos tienen una serie de características:

  • Debe de tener un nombre que lo identifique.
  • Debe tener algo que diga donde empieza y donde acaba

Lo mínimo que nos podemos encontrar con forma de módulo es una función. Una pieza un poco más grande sería una clase, ya que incluye un conjunto de funciones. Lo siguiente que nos podemos encontrar son los paquetes, que son un conjunto de clases relacionadas y en las que definimos relaciones de jerarquía. Por encima de estos están los componentes, conjuntos de paquetes que representan nuestros subsistemas.
Beneficios de la modularidad:

  • Son mas fáciles de entender y de documentar.
  • Facilitamos los cambios.
  • Reducimos la complejidad.
  • Obtenemos implementación mas sencillas.
  • Posibilitamos el desarrollo en paralelo.
  • Posibilitamos la prueba independiente.

¿Qué grado de modularidad es necesario?
Mientras más módulos tengamos, menos esfuerzo tendremos que emplear para hacer cada módulo. Sin embargo más esfuerzo tendremos que emplear en la comunicación entre tantas piezas. Esta relación la podemos ver en la siguiente gráfica.

Abstracción:
Mediante la abstracción vamos destacando los elementos importantes del sistema, para después ir detallándolos en distintos niveles de abstracción, volviendo a identificar los elementos importantes en cada nivel. Es decir, la abstracción es el mecanismo que nos permite determinar qué es relevante y qué no lo es en un nivel de detalle determinado.
Mecanismos de abstracción en el diseño:

  • Abstracción procedimental: Estructura modular basada en procedimientos. Se abstrae sobre el funcionamiento. Describimos a grandes rasgos qué hace nuestro módulo, sin decir cómo lo hace.
  • Abstracción de datos: Abstraemos el estado de nuestro módulo (atributos) y su funcionamiento. Aquí definimos por ejemplo las clases.
  • Abstracción de control: Abstrae el flujo de control de cualquier proceso en general. Por ejemplo, los iteradores son un mecanismo de abstracción de control sobre estructuras repetitivas. De hecho las mismas estructuras repetitivas son una abstracción de control
  • Refinamiento por pasos: Desarrollar un programa paso a paso partiendo de sentencias macroscópicas hasta llegar a nivel de sentencia en un lenguaje de programación

Independencia funcional:
Está referido a las piezas y a que sean lo más independientes posibles entre ellas. Que cada módulo se ocupe de una tarea específica o un conjunto de tareas relacionadas entre ellas.
¿Por qué independencia funcional?

  • Se pueden compartir las funciones.
  • Es más fácil de reutilizar.
  • Son mas fáciles de mantener y probar.
  • Se reduce la propagación de errores.
  • Se simplifican las interfaces.

La independencia funcional se mide mediante dos parámetros:

  • COHESIÓN.
  • ACOPLAMIENTO.

Ocultamiento de información:
Que a los datos privados de cada módulo sólo tenga acceso el propio módulo. Entre módulos se comunican mediante envío de mensajes, nunca dejando acceso directo a los datos privados. Es conveniente distinguir entre encapsulación y ocultamiento de de información. Encapsulación es el concepto de coger determinados elementos y agruparlos como una entidad, mientras que el oculta miento consiste en hacer que parte de esos elementos no sean accesibles desde fuera del módulo.
Ventajas del ocultamiento de información:

  • Reduce la probabilidad de “efectos colaterales”.
  • Limita el impacto global de las decisiones de diseño local.
  • Enfatiza la comunicación a través de interfaces controladas.
  • Disminuye el uso de datos globales.
  • Conduce al encapsulamiento (un atributo de diseño de alta calidad).
  • Produce software de alta calidad