A veces es interesante disponer de un entorno de pruebas en el que poder experimentar alegremente sin miedo a romper nada. En este ámbito puede ser bastante útil tener un entorno chroot en el que hacer cosas, separado del sistema operativo principal de esa máquina. Por supuesto, también se puede optar por usar una máquina virtual, pero esta opción tiene también sus pros y sus contras. En este texto quiero comentar brevemente como crear un entorno chroot de pruebas desde Debian de una forma sencilla.
En primer lugar, se puede usar el comando debootstrap o cdebootstrap para crear el árbol de directorios principal del chroot: “cdebootstrap (o debootstrap) SUITE TARGET [MIRROR]“, donde SUITE es cualquiera de las ya conocidas en Debian: sid, testing, stable, oldstable; TARGET representa el directorio donde queremos crear el chroot, y MIRROR es el repositorio del que obtendremos los paquetes para la instalación.
El segundo paso consiste en copiar dentro de este entorno chroot algunos archivos de configuración de nuestro sistema principal, como /etc/passwd, /etc/group, /etc/shadow, /etc/hosts, /etc/fstab y /etc/resolv.conf. Es importante además crear un archivo /etc/apt/sources.list con los repositorios fuentes que usaremos para actualizar nuestro sistema. Se puede crear además un archivo /etc/debian_chroot para que se muestre claramente en la línea de comandos que estamos dentro del entorno chroot.
El siguiente paso será hacer que ciertos directorios de nuestro entorno chroot sean los mismos que los de nuestro sistema principal: /home, /dev y tal vez también /tmp. También montaremos en su sitio los directorios especiales: /dev/pts (devpts), /sys (sysfs), /proc (proc) y /proc/bus/usb (usbfs).
A continuación entramos en el entorno chroot recién creado y añadimos y quitamos los paquetes que deseemos. Por ejemplo podemos añadir locales, xorg, xfce4 y xdm, y sustituir exim4 por esmtp-run.
Ya tenemos el entorno chroot creado. Para entrar en él no tenemos nada más que, como root, usar el comando chroot. Si queremos abrir un segundo servidor de X, dentro del chroot, lo haremos con “startx — :1″. Tal vez sea necesario reconfigurar éste. Si ese es el caso, lo mejor es, desde una consola (no desde las X), ejecutar dentro del chroot: “dpkg-reconfigure xserver-xorg“, y seguir los pasos.
Podemos hacer aún algo más, iniciar directamente el chroot desde una nueva consola virtual, por ejemplo la 9, añadiendo la línea “9:23:respawn:/usr/sbin/chroot /chroot_dir /sbin/getty 38400 tty9″ al archivo de configuración /etc/inittab de nuestro sistema principal (es decir, fuera del chroot), y reiniciando con “init q”. También podemos hacer que nos abra directamente el servidor de X en otra consola virtual, por ejemplo la 10, ejecutando el script de inicio de xdm (o similar: wdm, gdm, kdm) dentro del chroot, habiendo ajustado previamente su configuración en /etc/X11/xdm/Xservers
He creado un script con todos los pasos, para poder analizarlo con calma. Si alguien lo quiere se lo puede descargar de aquí.
In 2006, Edward A. Lee wrote The Problem With Threads (PDF), in which he observes that threads remove determinism and open the door to subtle yet deadly bugs. While the problems are maybe manageable on single core systems, threads on multicore systems are likely to magnify the problems out of control.
According to Wikipedia, coroutines are “program components that generalize subroutines to allow multiple entry points and suspending and resuming of execution at certain locations”. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, iterators, infinite lists, and pipes. Coroutines are more generic than subroutines. The start of a coroutine is the first point of entry, and places within a coroutine following returns (yields) are subsequent points of entry. Coroutines are also a lot faster than processes or threads switch, since there is no OS kernel involvement for the operation.
Even though coroutines are supported in some high-level languages, there doesn’t seem to be an standard implementation of them in C or C++. The first time I heard about coroutines were in Lua. Since then, I’ve been trying to find a good solution for using them in C. Simon Tatham proposes a way of implementing them with a combination of subroutines and macros, but I think that, even creative and clean, this is a dirty approach for real code. What about handling with errors in the code? I still have nightmares when I have some problem to debug in STL-based code. Cryptic, the least.
Due to the limitations of standard C libraries, some authors have written their own libraries for coroutines:
- Libtask: a Coroutine Library for C and Unix. It uses the context functions if they are provided by the native C library; otherwise it provides its own implementations for ARM, PowerPC, Sparc, and x86.
- Portable Coroutine Library (PCL): Easily portable on almost every Unix system and on Windows. It can use either the ucontext.h functionalities ( getcontext()/makecontest()/swapcontext() ) or the standard longjmp()/setjmp().
- libCoroutine (a small, portable coroutine implementation): For FreeBSD, Linux, OS X PPC and x86, SunOS, Symbian and others.
I’ll try to summarize the problems I usually encounter when packaging a game for Debian:
- Game data is not DFSG-Free: There are lots of games in which this problem seem to appear, including some of the most famous ones, maybe because of the influence these might have in new game developers. Many games have a free engine, and then decide to restrict game contents, mostly not allowing commercial use of these, or not granting the rights to modify them. This usually includes game maps, models, textures, sounds, fonts and so on. Sometimes those rights are granted under a Creative Commons license, which I hope will be DFSG-compliant sometime.
- Some game data might not be redistributable, even in non-free: It seems that many game developers don’t really understand copyright laws, or not care much about them, and pick images, models, textures or even fonts from random places without crediting their authors or even telling under which license they can be used. Thus, many games include data which might be not legal to redistribute. Not having a license means that no rights are granted at all.
- Game developers seem not to be very careful especially about fonts. Many of the fonts included with game data must be replaced by free ones.
- Releases seem to be quite atypical. Usually there’s a binary release including the game data and another different release just with the source code, but without any data file, you need both to make the game go. That means that repackaging is often needed. Game developers also tend to include in the same package whatever binary libraries are needed to run the game, mostly for Windoze.
- Build chain for data files often doesn’t exist. Some game developers even use their own packaging format to include all the data in a single file, and distribute only those packaged stuff with the game.
- Games tend to be very difficult to internacionalize. Many times texts are written graphically in screens. Some other times they use their own translation system, which might be relatively difficult to handle.
- Many games use relative directories to store their data, sometimes needing writing permissions too. As this doesn’t conform to Linux and Debian standards, the code must often be adjusted to use standard Linux paths and home directories to store whatever the program needs to save.
- Some games also need writing permissions in global files, for example for storing “hall of fame” lists. This is usually solved in Linux world by making a games group with permission to write on those files, but it’s quite a dirty hack in my opinion.
- There’s often not a clear documentation on which copyright and license applies to each file. Especially for non-code stuff, it’s hard to find out if it has been created by the game developers, where it comes from, or which license applies to it. I guess there’s a misunderstanding in that, when no license is explicitly said, all restrictions apply, and not the reverse as many people seem to think. No license means no rights at all.
I’m sure I’m leaving lots of points out of this list, it doesn’t mean to be exhaustive in any way. Maybe I’ll remember more things later.
There’s a huge problem with the educational system as we know it. It doesn’t teach people how to think, to be creative, or even to improve their knowledge. When a kid goes to school, the first thing they learn is that the answers they must give are not what they consider to be truth, but what they think the teachers want to hear. When you’re in high school, or at university, you have the inner feeling that you must behave, or else. I had personal problems with a teacher at university, and learnt that you’re helpless in that situation. The motto would be that if you want to finish university, you should take care about getting on with the teachers. The result are submissive citizens that won’t face authority even if they know they’re right, in order to avoid problems.
One of the best things in Debian is that is revolutionary, belief-guided. People do what they feel they should do, according to their own beliefs, and mostly don’t care about having trouble with the “authority”. That’s something I really like a lot, and respect. Of course that is also the source of multiple fights and disagreements, but usually the result of those is a better solution that whatever could be achieved by an authority imposition from the power-handling people. I like the revolutionary face of Debian as much as I like the technical one, and wouldn’t like losing it.
The NM process is Debian’s “university”. It’s the process in which new generations of developers will enter the project. Therefore, whatever is done with it will highly influence middle-term evolution of Debian. Of course, the NM process must assure that people becoming developers have enough technical skills, and also that they’re ideologically aligned with the Social Contract. Otherwise it wouldn’t make sense. What should be taken care about is that the NM process don’t filter side thinking, creativeness, confrontation with authority or the will to make a better world. I wouldn’t like an NM process that promoted the same submissive values that the educational system does.
Defining a grammatical structure for configuration files is a bit of a headache. The most easy way to get something to work is probably using INI files, but they’re somehow very limited for setting up configurations that are not quite trivial. The next obvious file format to look at are probably XML files, which are extremelly powerful for defining data structures, and are really fashion. While this might probably be the best choice when programming in certain languages, like Java or C#, especially if you use editors that are XML-oriented, it might not be the best for me. I’ve also seen that some projects read their configuration from script-languages files, such as lua. This might be quite interesting if you also allow embedded functions in that language in your code, for defining event responses, macros, or conditional configurations. Some other projects define their own grammar, maybe using Flex lexical analyser and GNU bison.
I plan to use json-c from C. Lets see what comes out from there.