Sistema del Aula Informática del Laboratorio de Estructuras Fortunato Navarro Sanz fnavarro@ieeesb.etsit.upm.es Junio 1999 El sistema del Aula se compone de diez ordenadores que en adelante se denominarán "clientes" y un PC (goliat.mecanica.upm.es) que actua de servidor. Cada PC cliente está configurado para que pueda arrancar tanto con GNU/Linux como con Windows 95 a partir de un menu de arranque inicial. ------------------ MENUS DE ARRANQUE. ------------------ Para que el sistema de arranque de los clientes funcione es necesario que el servidor esté funcionando con GNU/Linux. Al encender el cliente aparece una secuencia de arranque que corresponde al programa que se encuentra instalado en la EPROM de la tarjeta de red. El programa de la EPROM vuelca a continuación un programa (programa de "preboot") del servidor y lo ejecuta. Es este programa el que contiene el menú de inicio y es capaz de arrancar los sistemas que se encuentran instalados localmente en cada cliente (GNU/Linux y Windows). Si el servidor está apagado el programa de preboot no se puede volcar y no es posible arrancar los sitemas locales. El menu de inicio ofrece cuatro opciones, que se seleccionan pulsando el número correspondiente (no es necesario pulsar enter): 1 y 2 - arrancar un sistema instalado en el disco duro del cliente (Linux/Windows) 3 y 4 - reinstalar en el disco del cliente los sistemas a partir de una imagen que se guarda en el servidor. Existe una quinta opción que no aparece en el menú y a la que se accede con el número "0". Esta opción es para mantenimiento, arranca el cliente usando un disco remoto (no se usa para nada los discos locales del cliente). Se trata de un Linux con el root filesystem por NFS. Es con esta opción con la que se puden volcar imágenes de/hacia el servidor. ----------------------- EL PROGRAMA DE PREBOOT. ----------------------- (esta sección explica el funcionamiento interno del sistema de arranque. Es algo complejo por lo que se puede omitir y pasar directamente a "VOLCADO DE IMAGENES"). El programa de preboot está contenido en el paquete de debian "netboot". En este paquete contiene: - el programa que debe instalarse en una EPROM para el arranque del cliente. Este programa ya se encuentra instalado y no es necesario recompilarlo ni hacer nada con él. - un programa (mknbi-linux) que permite "reconstruir" la imagen de un kernel (básicamente añade una cabecera) de modo que pueda ser cargado por el programa de preboot y ejecutado. - un compilador (mknbi-mgl) que permite crear el programa de preboot. La secuencia de pasos que se han seguido para instalar un cliente desde "cero" es: 1 - Grabar e instalar las EPROMs: Se creó una imagen para la EPROM que debe ir instalada en la tarjeta de red. Para ello hay que seleccionar el tipo de tarjeta adecuada y los drivers necesarios ( en concreto un ANSI driver para poder mostrar caracteres gráficos para el menu ). Tras ello se ejecuta 'makerom' y se obtiene una imagen que se puede grabar en la EPROM. (Ver documentación del paquete en /usr/doc/netboot). (Un detalle a señalar: no espero que reprogrameis las EPROM, pero por siacaso, tened en cuenta que la EPROM es bastante mayor en tamaño (128K) que la imagen que se genera (32K) por lo que después hay que rellenar el resto con "0xFF" para que el grabador funcione correctamente.) Grabar la imagen en la EPROM. El modo "ortodoxo" consiste en usar un grabador de EPROMs, que es una máquina específicamente diseñada para borrar y escribir EPROMS (es necesario hacerlo con tensiones de alimentación especiales). Actualmente es posible usar un tipo de EPROM que es borrable eléctricamente y que se denomina FlashEPROM (es la que tienen todos los PC's en sus placas madres). Existe un programa que permite grabar FlashEPROMs en la propia placa madre o en las tarjetas del PC que se denomina UNIFLASH y que se encuentra en http://ourworld.compuserve.com/homepages/pvanleeuwen/ufhome.htm. Por desgracia no funciona bien en los ordenadores del aula pero sí en fidalgo. El procedimiento que se siguió fue instalar una EPROM en una tarjeta de red, a continuación insertarla en fidalgo, arrancar con un diskette y el programa de grabado, grabar la EPROM y extraer la tarjeta y la EPROM. Esto se repitió con las diez EPROM que posteriormente se insertaron en cada una de las tarjetas de red de cada cliente. 2 - Crear el programa de preboot: Una vez instaladas las EPROM los clientes intentan en el arranque volcar el programa de preboot del servidor. Esto se realiza en dos fases: primero se intenta conseguir una dirección IP del servidor mediante el protocolo BOOTP y una serie de argumentos que indican cuál es el servidor y la imágen del programa de preboot a cargar; la segunda fase consiste en la petición de la imagen al servidor y su ejecución en el cliente. Esto significa que para que el cliente pueda ejecutar el programa de preboot hay que configurar dos aspectos: BOOTP y el compilar el programa de preboot. * BOOTP: Es un protocolo usado en máquinas que no tienen discos locales. Permite que en el arranque una máquina busque en la red un servidor que le asigne una dirección IP y otros argumentos como la imagen de arranque. El kernel de linux se puede compilar con esta opción. Si se hace así al iniciarse el kernel lo primero que hace es conseguir esa dirección IP y con ella configurar el adaptador de red (esto se ha usado en la opción "0", se explica más adelante). En este caso el cliente que hace la consulta no es un kernel sino el programa que se encuentra en la EPROM. En el servidor es necesario que exista un servidor de bootp correctamente configurado (es un demonio "bootpd", que se arranca en el momento que haya una petición de BOOTP. Ver inetd.conf). La configuración de bootp se encuentra en /etc/bootptab: # /etc/bootptab: database for bootp server (/usr/sbin/bootpd) # # Blank lines and lines beginning with '#' are ignored. # # Legend: (ver bootptab.5, es decir 'man 5 bootptab') # # Be careful about including backslashes where they're needed. Weird (bad) # things can happen when a backslash is omitted where one is intended. # Also, note that generic option data must be either a string or a # sequence of bytes where each byte is a two-digit hex value. # puesto1:hd=/usr/local/boot:\:vm=auto:ip=138.100.66.201:\ :sm=255.255.255.192:\ :ht=ethernet:ha=0x00e02928dafd:\ :bf=menu.out puesto2:hd=/usr/local/boot:vm=auto:ip=138.100.66.202:\ :sm=255.255.255.192:\ :ht=ethernet:ha=0x00e02928dbde:\ :bf=menu.out puesto3:hd=/usr/local/boot:vm=auto:ip=138.100.66.203:\ :sm=255.255.255.192:\ :ht=ethernet:ha=0x00e02928dfae:\ :bf=menu.out ... como se puede observar cada etiqueta recoge un argumento que se pasa al cliente. Hay una entrada por cliente (puesto1, puesto2...) en la que se indica la dirección IP que le corresponde. (El significado de cada campo aparece en la página de manual de bootptab). ¿Cómo sabe el cliente cuál dirección IP debe usar para hacer la consulta? Usa broadcast de modo que todos los ordenadores de la subred se enteran de la petición pero sólo el que tenga un servidor instalado la responde. ¿Cómo se sabe cuál es el cliente? Usando su dirección ethernet ("Ethernet Address" ó MAC) que es un número único que posee cada tarjeta (codificado en el hardware) y que se envia junto con la petición. Aparece en la pantalla al arrancar el cliente desde el programa de la EPROM, sólo hay que apuntarlo e incluirlo en el campo "ha" del archivo /etc/bootptab. Otro campo importante es "bf"que significa 'boot file' y es la imagen que el cliente debe cargar y ejecutar tras configurar su tarjeta de red con los campos "ip" y "sm". Este archivo NO se carga con BOOTP sino que se usa otro protocolo que se denomina TFTP (Trivial File Transfer Protocol). * TFTP: Es otro protocolo asi que eso significa que hay otro servidor (otro demonio: "tftpd", que se activa si aparece una petición; ver inetd.conf), y otro archivo de configuración (en este caso es un argumento de tftpd y que aparece en el propio inetd.conf). La entrada en inetd.conf que arranca tftpd es:tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /usr/local/boot Es decir cualquier archivo que se solicite mediante tftp (según el /etc/bootptab los clientes terminarán pidiendo "menu.out") debe encontrarse en el directorio /usr/local/boot. Si existe tftpd lo enviará al cliente que se encarga de cargarlo en memoria y ejecutarlo. Hay que hacer notar que tftp es un protocolo _extremadamente_ ineficiente, sobre todo en presencia de mucho tráfico en la red. * DHCP: Al final NO usamos BOOTP, aunque se hayan dejado los archivos de configuración en goliat bootp está cancelado en el servidor. Se ha explicado el mecanismo porque es más fácil de entender con BOOTP. Lo que se ha usado finalmente es DHCP (Dinamic Host Configuration Protocol) que es un protocolo que soporta BOOTP. DHCP también tiene estructura cliente-servidor. El servidor (en goliat) es, de nuevo, un demonio que se inicia bajo petición (entrada en inetd.conf) y cuyo archivo de configuración se encuentra en /etc/dhcpd.conf: # dhcpd.conf # # Configuration file for ISC dhcpd # # Hosts with more than one interface MUST specify a ``server-identifier'', # which should be the IP address of the server's primary network interface, # or if there is no interface that can be described that way, at least an # interface whose address isn't likely to change. server-identifier goliat.mecanica.upm.es; # option definitions common to all supported networks... option domain-name "mecanica.upm.es"; option domain-name-servers filemon.mecanica.upm.es; # Shared network declaration is used to group subnets which share the same # physical network together. The name is specified so that the shared # network can be referred to in log messages - it serves no other function. shared-network MECANICA { default-lease-time 600; max-lease-time 7200; # One of the two IP subnets that share this physical network # # Address ranges can be specified for each subnet attached to # a shared network. Since these subnets share the same physical # network, addresses are pooled together, and assignments are made # without regard to the actual subnet. If the optional dynamic-bootp # keyword is given in the address range declaration, then addresses # in that range can be assigned either with the DHCP protocol or the # BOOTP protocol; otherwise, only DHCP clients will have addresses # allocated from the address range. # # Note that each IP subnet can have its own options specific to that subnet. # options that aren't specified in the subnet are taken from the shared # network (if any) and then from the global option list. subnet 138.100.66.192 netmask 255.255.255.192 { option broadcast-address 138.100.66.255; range 138.100.66.211 138.100.66.239; option domain-name "mecanica.upm.es"; option routers 138.100.66.193; } } host puesto1 { hardware ethernet 00:e0:29:28:da:fd; option host-name "puesto1" ; option domain-name "mecanica.upm.es"; fixed-address 138.100.66.201; filename "/usr/local/boot/menu.out"; } # :ht=ethernet:ha=0x00e02928dbde:\ host puesto2 { hardware ethernet 00:e0:29:28:db:de; option domain-name "mecanica.upm.es"; option host-name "puesto2" ; fixed-address 138.100.66.202; filename "/usr/local/boot/menu.out"; } # :ht=ethernet:ha=0x00e02928dfae:\ ... Para entender la sintaxis del archivo ver la página de manual y _también_ la documentación en /usr/doc/dhcp-beta y el mini-HOWTO de DHCP. Básicamente es el mismo tipo de archivo que bootptab, pero además sirve para configurar todo DHCP (no solo BOOTP). La principal diferencia es la capacidad de DHCP de asignar dinámicamente (no solo en el arranque) direcciones IP. En esta fase del arranque sólo se usa el soporte de BOOTP, pero más adelante se usa la asignación dinámica (con los clientes ejecutando Windows, por ejemplo), por lo que tenemos que usar DHCP desde el principio. * Preboot: Con todo lo anterior "sólo" hemos configurado el servidor y el cliente para que en el arranque se vuelque la imagen, todavía queda crearla. Para ello se usan los programas que vienen en el paquete "netboot". Existe un programa en el paquete (mknbi-mgl) que genera una imagen a partir de un programa que tiene una sintaxis similar a pascal. Dentro del paquete (en /usr/doc/netboot/examples ) viene un ejemplo de programa. Las fuentes del que se está usando para el aula están en /usr/local/boot/boot/menu_aula.mgl El lenguage se describe en la página de manual de mknbi-mgl y en los archivos de documentacion (cualquiera que toque cosas del sistema de arranque del aula DEBE leerlos) del paquete en /usr/doc/netboot. Si ya tenemos el código fuente de nuestro programa de preboot lo compilamos con : mknbi-mgl --opt386 menu_aula.mgl menu.out que genera directamente la imagen a volcar por el cliente. Para que no sea todo un lio existe un script con la linea anterior (makemenu) que compila el código fuente y deja la imagen precisamente en /usr/local/boot/menu.out que es dónde tftpd espera encontrarla cuando se lo solicite el cliente. 3 - Ejecución del programa de preboot. ¡Ya tenemos el programa de preboot, lo carga el cliente y lo ejecuta!, Ahora, ¿qué? Ahora todo depende de lo que hayamos programado en el código fuente del programa de preboot que hemos compilado con mknbi-mgl. En el aula el preboot consiste en la presentación de un menú que llega a las cuatro opciones que se indican al principio. Este es el lugar de explicarlas con más detalle: item 0: print black_bg ; cls; load root + "/bootImage-admin" from "goliat"; item 1: cls; load "/dev/hda1"; item 2: print low + black_bg ; cls; load "/dev/hda2"; item 3: cls ; print "Reloading Windows95" at [0,19]; gotoxy [0,21]; load root + "/bootImage-win95" from "goliat"; item 4: cls ; print "Reloading Debian GNU/Linux 2.0" at [0,19]; gotoxy [0,21]; load root + "/bootImage-deb21" from "goliat"; Cada entrada "item" describe las acciones de esa opción. Las opciones 1 y 2 está claro que indican al preboot que carge el programa de arranque que se encuentra en las particiones /dev/hda1 ó /dev/hda2 (exactamente igual que si arrancásemos con LILO, por ejemplo). Las opciones 3 y 4 hacen algo distinto: cargan una imágen cuyo nombre se indica explícitamente en el código ("root" es una variable que en otro lugar del código se inicializa como "/usr/local/boot", y la suma en este lenguage de programación tiene el sentido de concatenación para las cadenas de caracteres). En este caso también se carga una imagen y se ejecuta sólo que su nombre _no_ nos lo indica el servidor como se hacia en el arranque sino que _lo indicamos nosotros_ porque sabemos que la hemos puesto precisamente ahí. ¿Qué es esta imagen? Es un kernel de linux que al arrancarse montará el root filesystem por NFS de modo que no se usen los discos locales (y por tanto se puedan hacer volcados de los mismos de una manera "limpia"). Por esta razón hemos llamado a las imágenes "bootImagen-", dónde algo indica que se va a hacer con la imagen. Como se puede observar las opciones 0, 3 y 4 hacen exactamente lo mismo salvo que con imágenes distintas. Una vez se entra por uno de estos caminos el programa de preboot carga la imagen en memoria, la ejecuta y termina. A partir de ese momento el control del cliente lo tiene el programa que acabamos de volcar del servidor. 4 - Las imágenes de arranque ("bootImages"). ¿Qué tienen? Tienen un kernel... y algo más. Son en concreto, imágenes de ramdisk, es decir, contienen tanto una imagen de un kernel como una imagen de un diskette de arranque. Ambas se encuentran en un solo archivo (el bootImage) que se construye con el programa mknbi-linux de netboot. El procedimiento para crearlas es el siguiente: supongamos que tenemos un kernel en "zImage" (que hemos compilado como un kernel normal con soporte para BOOTP, ramdisk y rootfilesystem por NFS) y la imagen de un root filesystem (la que estamos usando es la que viene con Debian en /debian/dists/hamm/main/disks-i386/current/root.bin). Para crear el bootImage hay que hacer: mknbi-linux -d /usr/local/boot -r root.bin zImage bootImage-Winchoff Esto crea el bootImage-Winchoff que contiene el kernel zImage y la imagen de ramdisk "root.bin". El directorio /usr/local/boot/ es el que se montará como rootfilesystem por NFS. De nuevo he hecho un script que ayuda a hacer estas cosas, "makerest", que toma un argumento ( el del bootImage que queremos hacer). Para hacerlo funcionar habría que hacer, en /usr/local/boot/boot/images: ./makerest deb21 que modifica el contenido del ramdisk y compila el bootImage. 5 - El arranque del bootImage: ¿Que hay en ese misterioso ramdisk? Una imagen de un diskette con un root filesystem, tal cual. Lo único que realmente importa de esa imagen es el contenido del script /linuxrc. Cuando arranque el kernel, antes de montar ningún filesystem lo que hace es ejecutar lo que se encuentre en linuxrc (tambien es necesario el resto del ramdisk, claro, porque sino no tenemos "bash" para ejecutar el script). "linuxrc" simplemente copia el contenido de /root/rest_ a /root/restore. Posteriormente en el NFS root filesystem el inittab tiene una entrada que ejecuta _siempre_ /root/restore. Una vez se ha ejecutado linuxrc el kernel solicita una dirección mediante BOOTP (ver el punto 2) y monta el root filesystem por NFS. Tras montar "/" se ejecuta /root/restore (a través del inittab). ¿Por qué tanta complicación? Porque el root filesystem que se monta con NFS es el mismo (goliat:/usr/local/boot) para las dos bootimágenes asi que si queremos que hagan cosas distintas es necesario que _antes_ de montar el root filesystem dejen un "rastro" distinto. ¿Qué aparece en el /etc/inittab (=goliat:/usr/local/boot/etc/inittab) que se ejecuta al arrancar con root fs por NFS? : # Format: # ::: 1:2345:once:/bin/bash /root/restore /dev/tty1 2>&1 2:2345:respawn:/sbin/getty 38400 tty2 en efecto se ejecuta /root/restore. ¿Qué hay en /root/restore?: test -x /initrd/root/restore || exit 0 source /initrd/root/restore que ejecuta (!) /initrd/root/restore. ¿Por qué? porque el root filesystem que habia en el ramdisk, al montar de nuevo el root fs por NFS pasa estar colgando de /initrd. Es aquí (/initrd) dónde se encuentra el "rastro" que deja cada imagen y que permite que hagan cosas distintas, aunque usen el mismo root fs. y ¿qué hay en /initrd/root/restore?: #!/bin/bash whiptail --backtitle "Aula Informatica del Laboratorio de Estructuras" \ --infobox "Reinstalando Debian GNU/Linux 2.1..." 5 40 sleep 90 zcat /boot/deb21/hdimage.bin | dd of=/dev/hda2 reboot que es el script que vuelca la imagen del servidor y rebota la máquina. Este script sería el rest_deb21 que copiamos a /root/restore (ahora en /initrd/root/restore) y que podría haber sido rest_win95 en cuyo caso el script es: #!/bin/bash whiptail --backtitle "Aula Informatica del Laboratorio de Estructuras"\ --infobox "Reinstalando Windows 95..." 5 30 sleep 90 zcat /boot/win95/hdimage.bin | dd of=/dev/hda1 mount -t vfat /dev/hda1 /mnt cp /initrd/root/cfgname/`hostname -i` /mnt/cfgname.reg mount /mnt reboot y para el bootImage de administración es: #!/bin/bash whiptail --backtitle "Aula Informatica del Laboratorio de Estructuras" \ --msgbox "Sistema de administración remoto..." 7 44 --nocancel whiptail --backtitle "Aula Informatica del Laboratorio de Estructuras" \ --msgbox "Pulsar para consola de trabajo." 7 44 --nocancel Los "whiptail" son sólo comandos para pintar ventanitas en modo texto. 6 - Hacer los bootImages: Sería demasiado complicado hacerlo a mano asi que hay un script que se encarga de "crear" (se modifica una imagen vacia en root.fl) el ramdisk con el rest_ adecuado y de compilarla junto con la imagen de un kernel en un bootImage. El funcionamiento del script ya se ha comentado más arriba asi que voy a presentar la organización de directorios: /usr/local/boot -- TODO cuelga de aquí y es, además el directorio raiz que se exporta por NFS. /usr/local/boot/bootImage- -- las bootImages /usr/local/boot/menu.out -- la imagen del programa de preboot obviamente el argumento con el que se arranca tftpd debe ser /usr/local/boot. /usr/local/boot/boot/ -- de aquí cuelgan los scripts e imágenes de kernel y ramdisk a partir de los cuales se construyen los bootImages. /usr/local/boot/boot/win95 /usr/local/boot/boot/deb21 -- en estos directorios hay: * restore : el script "rastro" que se encarga de volcar la imagen adecuada en cada caso. * hdimage.bin : LA IMAGEN DEL DISCO DURO que corresponde al sistema que se quiere restaurar. * cfgname : sólo en win95, contiene archivos necesarios para configurar la direccion IP en windows. /usr/local/boot/boot/images -- contiene el script que genera los bootImages (debe ejecutarse en este directorio) y las imágenes de kernel y ramdisk base. /usr/local/boot/boot/menus -- el código fuente del programa de preboot y el script para compilarlo. NOTA: puesto que /usr/local/boot es el directorio que se exporta por NFS y que los clientes (en las opciones 0:administración y 3,4:restaurado de imágenes) montan como raiz, desde éstos el directorio será simplemente "/". Por ejemplo: /usr/local/boot/boot/win95/hdimage.bin en el servidor es /boot/win95/hdimage.bin en el cliente. ------------------- VOLCADO DE IMAGENES ------------------- Las órdenes que se encargan de volcar la imagen del servidor a una partición del disco local del cliente son: zcat /boot/deb21/hdimage.bin | dd of=/dev/hda2 zcat /boot/win95/hdimage.bin | dd of=/dev/hda1 El "zcat" simplemente hace una descompresión de la imagen y la pasa, a través de la salida estandar, al comando dd (disk dump). "dd" copia byte a byte la entrada estandard a la partición correspondiente. En la imagen por tanto una copia exacta de lo que debe existir físicamente en el disco para que el sistema funcione. Por esta razón también funciona el sector de arranque y el programa de arranque (LILO en Linux y el bootloader de Windows). Al hacerlo así necesitamos que la imagen del disco se encuentre accesible para el sistema que hace el "zcat" y que es un Linux con root fs por NFS. Esa es la razón por la que todos los directorios que contienen las imágenes se encuentran dentro del directorio que goliat exporta por NFS a los clientes. * Volcar imágenes del cliente al servidor. Puede interesar actualizar la imagen de la partición de un sistema que posee el servidor. La idea es usar esta actualización para instalar el software en un sólo cliente y "clonarlo" al resto. El procedimiento es: 1 - Restaurar la imagen del disco local de un cliente con la opcion correspondiente del menu de arranque (3 ó 4). Puesto que vamos a actualizar la imagen del servidor nos conviene partir de una instalación "limpia". 2 - Instalar el software que corresponda, teniendo en cuenta que la instalación que se haga será _idéntica_ en todos los PC's una vez se realice la actualización de todos los clientes. 3 - Rebotar el sistema y arrancar con la opción "0". 4 - En la opción "0" se arranca un Linux con root fs por NFS. Esto quiere decir que no se están usando las particiones locales y se puede realizar el volcado sin preocuparse porque se modifican mientras dure el mismo. El comando para realizar la actualización es: dd if=/dev/hda1 | gzip -cf9 > /boot/win95/hdimage.bin dd if=/dev/hda2 | gzip -cf9 > /boot/deb21/hdimage.bin para cada sistema. "dd" lee el contenido de la partición (sin que haya que montarla, de hecho NO debe estar montada) y lo saca por la salida estandar que pasa, a través del pipe, a gzip. Las opciones de gzip son: c - que la salida llegue a la salida estandar f - forzar la compresion para la salida estandar (ver página de manual de gzip) 9 - nivel de compresión. Es importante que haya cierto nivel de compresión (quizás 9 es excesivo) para que la parte de disco que esté vacia no ocupe demasiado espacio en la imagen que se guarda en el servidor. Al final se redirige la salida estandar al archivo que va a guardar la imagen. Es imprudente hacer la copia directamente sobre la imagen antigua, si algo falla se pierde la imagen original y puede que nos convenga conservarla. Es mas razonable (si hay sitio en el disco del servidor) hacer el volcado a una imagen temporal (por ejemplo en /boot/admin/hdimage_tmp.bin) y después probar si funciona al volcarla a un cliente. Una vez se haya hecho varias veces se puede realizar directamente el volcado con más confianza. Este paso es el más largo, debido a la compresión se puede tardar más de 40 minutos en completarse el volcado (los algoritmos de compresión son de cierto peso computacional y los deben hacer los clientes, que son los menos adecuados). Esta es una de las razones por la que convendría tener espacio en el servidor para guardar las imágenes sin comprimir. Otra razón es que se podrían montar esas imágenes en el servidor y modificarlas sin tener que pasar por el volcado a un cliente. Al menos para la imagen del sistema GNU/Linux es posible y permitiría instalar el nuevo software EN el servidor con algo como: mount -o loop /usr/local/boot/boot/deb21/hdimage.bin /mnt dpkg -i .deb --root=/mnt umount /mnt cosa que actualmente no se puede hacer ya que no se pueden montar imágenes comprimidas. 5 - Finalizado el volcado, se puede arrancar otro PC cliente y volcar la nueva imagen actualizada con la opción correspondiente. En esta ocasion el volcado es mucho más rápido (unos 10-15 minutos) y se puede hacer en varios ordenadores a la vez. 6 - Se comprueba que la nueva imagen tiene el software correctamente instalado. Si no es así sería necesario corregir el fallo en alguno de los clientes con la nueva imagen y actualizar la del servidor. * Cuidados en los volcados múltiples de imágenes. El volcado se hace con NFS lo que es cierta ventaja (otros sistemas con programas de preboot mas complejos lo hacen con TFTP). TFTP es _muy_ ineficiente por dos razones: - El tamaño de los bloques que se transfieren es muy pequeño. - La transferencia no es concurrente, no se pueden satisfacer peticiones de múltiples clientes a un tiempo. Sin embargo para llegar a usar NFS hay que pasar por el volcado del programa de preboot y de la bootImage (kernel+ramdisk, ver sección anterior) que sí se hace con TFTP. Para agravar la situación en los clientes no hay una capa de red parecida a la de un sistema operativo multitarea sino una pila TCP/IP que está implementada en los drivers del programa cargado en la EPROM de las tarjetas de red. Esto implica que algún paquete en las transferencias se puede perder (la CPU del cliente funciona en modo real y debe vigilar todo lo que pasa por la tarjeta, es posible que mientras decide si un paquete es para él o no pierda el que sí va enviado para ese cliente), la imagen corromperse y el arranque no funcionar. Como conclusión: no conviene arrancar todos los ordenadores a un tiempo, las transferencias con TFTP se enlentecen muchísimo y puede que sea necesario rebotar alguna máquina porque no arranque bien. Es conveniente arrancar un ordenador y esperar 5-10 segundos a arrancar el siguiente. En los scripts de volcado se ha incluido un tiempo de espera (90 segundos) antes de comenzar los volcados en la esperanza de que sea suficiente para que cuando el primer ordenador empiece el volcado los demás ya hayan finalizado todo el proceso de arranque. --------------------- LOS SISTEMAS LOCALES. --------------------- Los sistemas locales en los clientes deben cumplir ciertas restricciones. Hay que pensar que toda la instalación (en los diez puestos) es un "clon", es decir, lo que hay en el disco es, bit a bit, idéntico en los diez puestos. Se debe instalar el software teniendo en mente esta situación. Surgen entondes la pregunta, ¿Cómo saben las máquinas cuál es su dirección IP y su nombre (distinta para cada una)?: Mediante el uso de DHCP. En Windows DHCP es algo 'natural', basta con elegir esa opción en la configuración de la red. Por DHCP también pueden obtener valores para el gateway (pasarela ó 'puerta de enlace' según la nomenclatura de Microsoft) y DNS si se dejan esos campos vacios. Funciona TODO con DHCP excepto, precisamente, la obtención del nombre de la máquina. La única solución es, tras el volcado de la imagen de la partición, modificar algún archivo en el que se especifique el nombre del cliente. Por desgracia no existe ninguno. La solución por la que se ha optado (quizás exista alguna mejor) es dejar un archivo CFGNAME.REG que contiene cómo hay que modificar el registro de Windows en el arranque (usando REGEDIT en el AUTOEXEC.BAT) de modo que se especifique el nombre del cliente. Por supuesto debe ser un nombre distinto para cada máquina asi que es necesario que la bootImage genere un CFGNAME.REG distinto. El aspecto de CFGNAME.REG es: REGEDIT4 [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\VNETSUP] "ComputerName"="PUESTO1" [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP] "HostName"="puesto1" [HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\ComputerName\ComputerName] "ComputerName"="PUESTO1" cada uno de los CFGNAME.REG de los clientes se encuentran en goliat:/usr/local/boot/boot/win95/cfgname/138.100.66.20? que se copia en el propio ramdisk del sistema de restaurado. En el Linux con root fs por NFS tras el arranque con el ramdisk esto se ve en /initrd/root/cfgname/138.100.66.20?. Esto ha complicado mucho las cosas porque el script que se ejecuta para el volcado: #!/bin/bash whiptail --backtitle "Aula Informatica del Laboratorio de Estructuras"\ --infobox "Reinstalando Windows 95..." 5 30 sleep 90 zcat /boot/win95/hdimage.bin | dd of=/dev/hda1 mount -t vfat /dev/hda1 /mnt cp /initrd/root/cfgname/`hostname -i` /mnt/cfgname.reg umount /mnt reboot necesita conocer la dirección IP del ordenador que va a usar el cliente en el que se está instalando la imagen ('hostname -i'), cosa que en principio no es necesaria. Por esta razón (y sólo por esta!) es necesario que el kernel que se vuelca con la bootImage tenga soporte de BOOTP y consiga una dirección IP en el arranque (en la segunda sección se explica como se consigue esto usando también DHCP). Con la instalación de GNU/Linux todo es mucho más fácil. Existen clientes de DHCP que son capaces de adquirir toda la información del servidor, incluyendo el nombre de la máquina. En el peor de los casos bastaría con tener en los clientes un /etc/hostname particular para cada máquina usando un método parecido al de Windows. NOTA: El cliente de DHCP para linux (paquete dhcp-beta de debian) tiene un bug. Desactiva el interfaz _antes_ de adquirir la nueva dirección IP con lo que nunca llega a conseguirla. He tocado el script que se encarga de esta parte (creo que es /etc/dhcpconfig o algo así), no recuerdo muy bien cómo pero en cualquier caso está comentado en el propio script. ------------- CONCLUSIONES. ------------- El sistema es _demasiado_ complejo de administrar, quizás porque he optado por una opción enteramente libre. Existen alternativas propietarias mejor terminadas y que facilitan bastante más la administración de un sistema de este estilo. Otra documentación a visitar es: http://www.han.de/~gero/ -- la página del paquete netboot. http://www.slug.org.au/etherboot -- la página de etherboot, otro sistema de preboot libre (de BSD). /usr/doc/HOWTO/mini/Remote-Boot.gz -- una solución propietaria, hace referencia a su página en la que se explica cómo funciona un sistema del estilo del aula. http://ourworld.compuserve.com/homepages/pvanleeuwen/ufhome.htm -- la página del grabador de EPROMs. Otros documentos que pueden ayudar a entender el tema del arranque con NFS para el root fs y el uso del ramdisk e /initrd: /usr/src/linux/Documentation/ramdisk.txt -- explica el proceso de arranque con ramdisk /usr/doc/HOWTO/NFS-Root.gz /NFS-Root-Client.gz /Diskless.gz -- como funciona un sistema con root fs por NFS.