Páginas

miércoles, 29 de septiembre de 2010

[0.2.2] El log de Schindler

Hoy debido a la huelga he decidido quedarme en casa, no por apoyarla y no ir a trabajar, sino que ayer me hice una copia de seguridad y he trabajado desde aquí debido al miedo que tenia a los piquetes (no estoy de acuerdo con las reformas, pero tampoco con los sindicatos como la mayoría de la población).

Al final ha sido mas ruido que otra cosa y podría haber ido sin problemas, pero el caso es que como he terminado pronto me he puesto a darle un empujón al sistema de archivos y bueno... hemos alcanzado otro checkpoint :-D Ahora modulo de log esta operativo, he limpiado el modulo de symlinks (ya no hay funciones mapeadas, todas son lanzadas por eventos gracias a louie :-) ) y empieza a discernirse un borrador de como implementar el sistema de plugins. Esto ultimo es debido a que en el modulo de log no tenia manera de tener una referencia para acceder a la base de datos, ya que antes accedía a través del objeto del sistema de archivos (como se puede ver en symlinks, aunque lo voy a cambiar en breve para unificarlo) y ahora al tener el objeto otra estructura perdía toda referencia a ella, y guardarlo en una variable global me decía el bicho que nanai. ¿Como hacerlo? Pues construyendo una clase. Era reacio a hacerlo a pesar de mi gusto por la orientación a objetos porque entonces ya no bastaría con cargar el modulo para tenerlo habilitado, sino que ademas tendría que meterme dentro, leer la clase y crear un objeto, y eso ya es mucho engorro. Por el momento lo he solucionado con la chapuza de crear una instancia del objeto al final del modulo (niños, no miréis :-P ) pero la ventaja de usar orientación a objetos es que mi idea de en un futuro implementar un sistema de dependencias entre plugins (inspirado en APT para mas señas... ;-) ) va a ser mucho mas sencillo :-)

En fin, en cualquier caso el modulo de logs ya esta listo, aunque tendré que diseñar algún método para agrupar los eventos y así poder discernir cuales son validos para loggear y cuales no, porque cuando ya estaba operativo con solo hacer un ls me ha salido todo esto...


[piranna@Tontodelculo:~/Proyectos/FUSE/PirannaFS/test]
> sqlite3 db.sqlite
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from log;
|__init__|DB|2010-09-29 18:34:31||{'self': , 'db_name': '../test/db.sqlite'}||
|readlink|FileSystem|2010-09-29 18:34:32||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:32||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:32||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:33||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:33||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:33||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:33||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:33||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:33||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:34||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:34||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:34||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:34||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:34||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:34||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:34||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:35||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:35||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:35||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:35||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:35||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:35||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:35||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:36||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:36||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:36||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:36||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:36||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:36||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:36||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:37||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:37||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:37||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:37||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:37||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:37||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:37||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:38||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:38||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:38||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:38||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:38||{'path': '/nano_link.txt', 'self': }||
|readlink|FileSystem|2010-09-29 18:34:39||{'path': '/nano_link.txt', 'self': }||
sqlite>


Si, efectivamente, FUSE hace muchas llamadas al sistema... ;-)


P.D.: entrada libre de faltas de "hortográfia" ;-) dedicada a Pau y su muy buen consejo :-)

sábado, 25 de septiembre de 2010

[0.2.1] Symlinks, Plugins y cintas de video

Aunque he tardado algun tiempo en actualizar cosas debido a lo saturada que tengo la agenda este año entre el trabajo y la carrera (aunque segun he visto en los blogs de los demas no soy el unico, bien por nosotros :-) ) al fin ha llegado el viernes tarde y para desconectar de una semana demasiado corta en tiempo (se me ha pasado volando sin darme cuenta, con lo que me jode...) y demasiado larga en estress en la que incluso he perdido mi maravilloso Android (snif...) me he puesto a darle un pequeño empujon al proyecto y a falta de uno hay dos: primero, ya tenemos links simbolicos, y segundo, ya tenemos una plataforma seria de plugins, aunque por ironico que parezca no por culpa del codigo para generar los links simbolicos, sino por culpa de la creacion de su tabla.

En primer lugar, los links simbolicos tienen sus propias funciones dentro de FUSE (symlink para crearlos y readlink para parsearlos), los cuales hasta ahora no las habia implementado porque no eran necesarias para el nucleo del sistema de archivos, asi que como primera aproximacion al sistema de plugins decidi mapearlas directamente dentro de la clase, al igual que he hecho con sus equivalentes en la base de datos.

Sin embargo para la creacion de la tabla no podia mapear ninguna funcion sino que tenia que ejecutarse cuando terminara de hacerse la base de datos entera, asi que buscando algun ejemplo de como hacer un sistema de notificacion de eventos en python (podia hacermelo yo y los ejemplos que encontre eran muy parecidos, pero queria ver si ya habia algo bien hecho y probado que poder reutilizar. Al menos esa es una de las ventajas del software libre, que si ya hay algo bien hecho no hay porque duplicar esfuerzos, ¿no?) y entre todo lo que encontre el que mas se parecia a lo que necesitaba para el sistema de plugins fue este codigo. Sin embargo aparte de que no me gustaba mucho como tenia implementado el sistema de carga de plugins (¿un archivo de configuracion? Por favor... con lo comodo y practico que es tener un directorio desde donde cargarlos al igual que se hacia con las extensiones del sistema del MacOS Classic...) tambien hacia referencia a PyDispatcher, el cual tambien hacia referencia a Louie. ¿Cual escoger? Al final como muchas otras veces en que tengo alternativas de codigo y me da igual uno que otro, deje que Ubuntu eligiera por mi para ver cual era el metodo mas estandar, y como Louie era el unico que tenia paquetes dentro de los repositorios oficiales, pues me decante por el :-)

Asi que aunque ha sido por algo completamente accidental, ahora tenemos un sistema de notificacion de eventos bastante avanzado. Puede que sea un problema con vistas a una futura implementacion como sistema de ficheros nativo (mas librerias externas, mas problemas de integracion), pero como apenas todavia estamos en las primeras fases de desarrollo todavia hay tiempo de modificarlo mas adelante si hace falta. De momento en cualquier caso hara falta una plataforma de plugins mas solida que la que tengo actualmente de mapear las funciones directamente, asi que a lo mejor con suerte incluso consigo matar dos pajaros de un tiro y consigo desarrollar un sistema de plugins lo suficientemente bueno como para que me lo incluyan en la libreria estandar de python (y eso si que seria un puntazo... ;-) ).

Proximo paso, aprender un poco mas como funciona Louie y desarrollar el plugin de log :-D

domingo, 19 de septiembre de 2010

Una pequeña idea...

Como puse en mi anterior entrada, PirannaFS empece a hacerlo entre otras razones porque queria experimentar con FUSE. Si, cuando quiero probar una nueva tecnologia no me leo un manual y hago el famoso Hola Mundo, me saco mi propio libro :-P y es por eso por lo que debido a todos los problemas que estoy teniendo para desarrollar PirannaFS y lo escueta, ofuscada y desfasada que es la documentacion que se puede encontrar en la pagina de FUSE por lo que estoy escribiendo mi propio tutorial de desarrollo de sistemas de archivos usando python y FUSE.

Mi idea en un principio era utilizar PirannaFS directamente como codigo de ejemplo del tutorial y es por eso por lo que he intentado que el codigo fuese lo mas claro y limpio posible, pero lo cierto es que el proyecto se ha convertido en algo realmente grande y complejo, aparte de por las optimizaciones que le he hecho para la escritura de los archivos como sobretodo por el usar una base de datos (y eso ya si que no es normal) asi que decidi empezar de cero otro sistema de archivos, este ya con mas complejo de Hola Mundo ;-)

PyRamFs es un sistema de archivos que usa objetos en memoria para guardar los datos: los archivos son strings y los directorios son diccionarios. Mas simple, imposible :-D Lo bueno del caso es que lo he estado escribiendo en orden de importancia a la hora de realizar un sistema de archivos, y es por eso por lo que empece con los archivos antes que con los directorios con lo que hasta ahora es un sistema de archivos de un unico nivel como el de CP/M y similares. Realmente me esta quedando bastante simple y minimalista, en parte por la simpleza del diseño y en parte porque ya no me pilla de nuevas, y es por eso que pense: si este sistema es tan simple porque (por ahora) no tiene subdirectorios... ¿se podran sacar tambien los subdirectorios del nucleo de PirannaFS para que sea aun mas simple e implementarlos como un modulo externo al igual que ha pasado con los links simbolicos?

Asi que nada, me fui al diagrama en el que tengo organizadas las tablas de la base de datos a echar un vistazo :-D

(Lo que esta en el recuadro azul son las tablas del core, las que estan alrededor son modulos "de ampliacion" ya que sus primary keys coinciden con las de las tablas del core y amplian su funcionalidad, y las dos tablas de abajo son de modulos auxiliares en los que su primary key no es dependiente de ningun elemento almacenado en el core)

Como podeis ver, dentro del core estan bastante separadas las tablas relativas a los directorios de las relativas puramente a los archivos, por lo que si no fuera por el nombre y por la fecha de creacion de la tabla links no seria complicado el sacar los directorios fuera y que el core funcione con un unico directorio aunque sin lugar a dudas donde se complicaria mas el tema seria con las consultas de acceso a los datos, que tendria que volver a cambiarlas (¿otra vez a cambiar la estructura de la base de datos? no, por favor...).

Sin embargo, la idea me gusta. No se si sera mejor desarrollarlo tambien como otro modulo externo y que el usuario elija uno u otro, o si ver la posibilidad de sacar los campos de nombre y creacion de la tabla links a una tabla aparte que sea la que se mantuviese dentro de la estructura minima para poder acceder a los archivos, pero en cualquier caso viendo el diagrama me he dado cuenta que aunque no tuviera nombres de archivo tampoco seria mucho problema, ya que si llego a implementar los modulos de metadatos (como el ejemplo que tengo puesto de mp3) se podria acceder directamente a traves de las bibliotecas de musica, fotos o lo que sea puramente a traves de los metadatos y entonces eso si que seria algo revolucionario: un sistema de archivos sin archivos :-P

Ahora bien, en caso de que llegara a implementarlo, ¿como lo hariais vosotros? ¿que el usuario tenga que decidir entre los dos modulos (un solo nivel o sistema jerarquico), o dividir la tabla links y que el mono-nivel este por defecto? ¿la tabla directories tendria algun sentido entonces (esta puesta para forzar luego en las consultas que links.parent_dir sea efectivamente un directorio valido)? ¿lo tiene ahora?

Yo, de momento, ya he alineado dir_entries con files y chunks en el diagrama por si sigo adelante con la idea... ;-)

jueves, 16 de septiembre de 2010

Comenzando...

Quizas la razon por la que no me gustan los blogs sea la misma por la que de pequeño no me gustaba tener un diario secreto, pero lo cierto es que con la cantidad de veces que me he estampado la cabeza desarrollando el sistema de archivos creo que el hecho de que tengamos que mostrar nuestras inquietudes y nuestros miedos en el concurso es una buena idea, asi que aqui esta: el famoso y siempre infravalorado primer post de un blog :-D

Y despues del comentario ironico para romper el hielo, la charla. PirannaFS es un sistema de archivos de ambito general con la idea de ser ampliamente modular, ampliable y flexible y que incorpore todas las novedades que traen los sistemas de ficheros modernos pero desde una perspectiva distinta. Hasta ahora, en el State-of-Art todos los grandes sistemas de archivos modernos como son NTFS, Ext3/4, HFS+, el fallecido WinFS o mi siempre idolatrado ZFS han estado implementando funcionalidades de motores de bases de datos como demuestra el hecho de que cuando se abandono el desarrollo de WinFS se utilizo su codigo para mejorar el motor de Microsoft SQL.

Y dije yo, ¿para que hacer un sistema de archivos que funcione como el motor de una base de datos cuando se puede usar el motor de una base de datos directamente? Llevaba bastante tiempo queriendo probar como funcionaba la libreria FUSE (Filesystem in USErspace) y debido a mis ultimos proyectos con python he estado usando bastante SQLite, asi que cuando llegue al ultimo capitulo del libro de Tanembaum (respecto a la lectura me parezco un poco a Hermione y su "lectura ligera" :-P ) me di cuenta no solo que eran bastante sencillos de implementar sino que ademas habia mucho terreno donde innovar, asi que la inspiracion para empezar a desarrollar PirannaFS fue casi instantanea: desarrollar una prueba de concepto de un sistema de archivos cuya administracion este gestionada enteramente por un motor de base de datos y aprovechar todas sus ventajas, como journaling de datos, poder personalizar las estructuras de las tablas segun se necesite...

Sin embargo despues empece a recordar los comentarios/criticas/quejas/sugerencias/ideas que habia leido al respecto de que con los discos duros externos y los pendrives tan grandes que hay hoy dia un sistema como FAT32 se hace ineficiente, y las alternativas que hay o bien no son practicas para un sistema portatil (NTFS o Ext3 o HFS+ tienen problemas con la portabilidad, y mas importante aun, con los permisos de lectura/escritura que lo unico que hacen en un pendrive es incordiar) o bien estan sujetos a durisimas patentes como es ExFAT, la evolucion de Fat32 a los 64 bits y a los Exabytes que estan por venir, encontrandonos con que no hay ningun sistema de ficheros apto para las necesidades de hoy dia.

Por todo esto, cambie las expectativas de PirannaFS a otras mucho mas ambiciosas: desarrollar un sistema de archivos factor comun y minimalista hasta el absurdo delegando toda la funcionalidad extra a modulos externos (el sistema base ni siquiera tiene soporte para links simbolicos :-) ) permitiendo ser usado alla donde no haga falta mas, pero preparado para poder ser ampliado y personalizado a traves de modulos externos que funcionen alla donde esten habilitados segun las necesidades del usuario: versionado de archivos, logging de actividad, ACLs, checksum de los datos, busqueda por metadatos, soporte de varios volumenes de disco simultaneamente...

Y aunque todavia falte mucho para ello y quizas tenga que cambiar de python a C y embeber el motor de SQLite dentro de la aplicacion, espero que algun dia en lugar de estar la base de datos separada de los datos propiamente dichos llegue a ser autocontenido y pueda llegar a arrancar linux desde el :-D