LinuxParty
LPIC-1 Capítulo 5
EN ESTE CAPÍTULO SE ABARCAN LOS SIGUIENTES OBJETIVOS DEL EXAMEN:
- 101.2: Proceso de arranque del sistema (3)
- 101.3: Runlevels / Target y los sistemas de inicialización: Sysv, Upstart y systemd (3)
- 102.2: Los administradores de arranque (2)
Inicializar sistemas Linux: SysV, Upstart y systemd
FIRMWARE: BIOS y EFI (UEFI)
Antes de hablar de los cargadores de arranque es necesario hablar de dos de los firmware mas usados en equipos x86-64, estos son BIOS (Basic Input/Output System) y EFI (Extensible Firmware Interface) o su versión posterior UEFI (Unified EFI).
De una u otra forma, el firmware de su ordenador lee el cargador de arranque en memoria desde el disco duro y lo ejecuta. Por su parte, el cargador de arranque se encarga de cargar el kernel de Linux en memoria y lo empieza a ejecutar, por tanto, la configuración del cargador de arranque en el disco es clave para que el firmware pueda localizarlo y comenzar con el proceso de inicio del sistema.
Nota: Las distribuciones Linux ofrecen métodos semiautomáticos para configurar un cargador de arranque durante la instalación del sistema, aunque puede que necesite saber mas, en especial si recompila su kernel o tiene que configurar opciones avanzadas, por ejemplo para seleccionar diferentes OS.
A la secuencia completa de arranque de un sistema (es decir la delegación de BIOS en el cargador de arranque y de este en el kernel del OS) se le conoce como Bootstrapping o Bootstrap Loader.
Tabla de los 2 principales firmware y sus cargadores de arranque:
Nota: Se puede usar una tabla de particiones GPT en sistemas con firmware BIOS, en cuyo caso GRUB se almacena parcialmente en una partición especial conocida como partición de arranque BIOS.
BIOS
BIOS (Basic Input/Output System): Firmware instalado en memoria ROM (EEPROM) o memoria Flash de la placa base de un ordenador, encargado de realizar una serie de pruebas e inicios (Power-On Self-Test,POST) como la cantidad de RAM presente, los dispositivos PCI, periféricos, etc…
Existen dos tipos de arranque, el arranque en frio (el ordenador se encuentra apagado) y el arranque en caliente (tenemos el ordenador encendido). La diferencia es que si arrancamos en caliente (Ctrl+Alt+Spr, botón de reset/reinicio) la BIOS salta la tarea de POST, por el contrario el arranque en frio hace que la BIOS siga su curso de chequeo e inicialización.
Una vez realizada la tarea POST, si todo ha ido bien sonará un “bip” (en ordenadores mas antiguos, indicando que todo está OK) y la BIOS leerá desde el MBR (sector de arranque especial situado en los primeros 512 bytes del primer disco duro) la tabla de particiones.
Podemos indicar mediante el menú de BIOS que el disco de arranque sea una unidad USB, un disco flexible, una unidad de CD-ROM, uno u otro disco rígido, etc…
El MBR contiene la tabla de partición (16 bytes por cada partición, con un máximo de cuatro), un centinela (0xAA55) y el código ensamblador (Master Boot Code, de 446 bytes), leído por la BIOS para continuar con el proceso de arranque. Este código (cargador de arranque principal) busca en la tabla de particiones aquella partición que está marcada como activa, lee de su sector de arranque y ejecuta el cargador de arranque “secundario” para que continué con el inicio del sistema (fase 1). Dependiendo del tamaño del cargador de arranque, se instalará en el mismo MBR o bien en una partición de arranque (/boot), que será la partición activa. De estar instalado en el MBR se pasará a fase 2, fase en la que se delega la carga del OS al cargador de arranque principal, finalizando así el inicio mediante BIOS, por el contrario de existir un cargador de arranque “secundario” se delegará a este el arranque (fase intermedia o fase 1.5).
Nota: Tener el cargador de arranque en el MBR tiene varias desventajas por ejemplo que el tamaño es limitado, o que si instala un OS Windows después de un OS Linux, este escribirá en el MBR por lo que machacará el cargador de arranque Linux.
Si es necesario una fase intermedia o fase 1.5, es porque GRUB está dividido en 2 partes; por un lado boot.img, imagen que se instala en el MBR para aprovechar los servicios de la BIOS y que será la encargada de cargar una nueva imagen con mas funcionalidades (core.img) que se encuentra instalada en /boot.
BIOS no tiene soporte para leer filesystems por lo que boot.img necesitará saber en que sectores se encuentra la partición activa para poder leer core.img, junto a los módulos y archivos de configuración de GRUB. Con esto se permite la lectura de cilindros por encima del 1024 y unidades de tipo LBA. En fase 2 se mostrará el menú de GRUB en el que se nos permitirá iniciar desde uno u otro sistema. Ya es GRUB el encargado de localizar la partición en la que se encuentra dicho sistema.
Nota: Si tenemos un esquema como este, es decir boot.img en MBR y el resto del contenido de GRUB en una partición por ejemplo /boot, puede ocurrir que al instalar Windows después de Linux, este escriba en el MBR e invalide el arranque de Linux. Podremos solucionar esto con FDISK de DOS, marcando como activa la partición /boot, para que en el próximo arranque se nos muestre el menú de selección de los diferentes OS.
Existen distintos cargadores de arranque compatibles con BIOS. De los cargadores de arranque hablaremos una vez tengamos entendido el funcionamiento de los principales firmware, así como la compatibilidad y uso de las tabla de particiones que hacen cada uno de ellos. Algunos de los cargadores de arranque compatibles con BIOS son:
- GRUB Legacy
- GRUB
- LILO
- NeoGRUB
- SYSLINUX
Particiones de tipo MBR:
El sistema de particiones MBR está limitado a particiones de 2 tebibytes (1 TiB = 2^40 bytes), al menos si se utiliza el tamaño de sector universal de 512 bytes. MBR utiliza tres tipos de particiones: particiones primarias, partición extendida (solo puede haber una y sirve de contenedor para las particiones lógicas) y particiones lógicas (estas se incluyen dentro de la partición extendida). No existe diferencia de rendimiento entre particiones primarias y particiones lógicas.
Nota: Sistemas como DOS, Windows y FreeBSD necesitan arrancar desde una partición primaria. Linux, aunque siendo una práctica inusual, puede arrancar desde particiones lógicas.
Para las particiones principales (primarias y extendidas) la numeración va desde sda1 a sda4, mientras que para las lógicas se usa del 5 en adelante. Pueden existir huecos entre las particiones primarias pero no en las lógicas, es decir, puede existir sda1, sda3, sda5, sda6 y sda7, pero no sda1, sda4, sda5, sda8 (si existe sda8, tiene que existir sda6 y sda7
Truco: Podemos crear copias de seguridad de nuestra tabla de particiones, de una forma sencilla (aunque existes otros métodos, de momentos vamos a quedarnos con este:
# sfdisk -d /dev/sda > /ruta/donde/guardar/sda-backup.txt
Podemos guardar esta copia en un USB y a continuación restaurarlo de la siguiente manera:
# sfdisk -f /dev/sda < /ruta/del/backup/sda-backup.txt
Las particiones MBR usan números hexadecimales de dos dígitos, de uno o dos bytes, para identificarlas. Alguno de los códigos mas habituales son:
- FAT: 0x0c
- NTFS: 0x07
- Sistema de archivos Linux: 0x83
- Intercambio de Linux: 0x82
- Partición extendida: 0x0f
El MBR está siendo reemplazado por la GUID Partition Table (GPT), ya que esta no puede superar los discos de 2TiB
EFI
EFI (Extensible Firmware Interface, propiedad de Intel) o UEFI (Unified Extensible Firmware Interface, Alianza de varias compañías líderes en tecnología: AMD, HP, IBM, Intel, Dell, Apple…)
Desarrollada por Intel para reemplazar al MBR de IBM. UEFI es la versión mejorada de EFI. Algunas mejoras son el cifrado, la autenticación de red, la interfaz de usuario,etc…
EFI hereda las nuevas características avanzadas de BIOS como ACPI (Interfaz Avanzada de Configuración y Energía) y el SMBIOS (Sistema de Gestión de BIOS) además, cabe destacar la capacidad de arranque desde unidades de almacenamiento grandes, arquitectura y controladores de la CPU independientes, diseño modular, etc.
EFI permite el arranque tanto desde el MBR como desde GPT, el cual solventa las limitaciones técnicas de MBR. EFI posee su propio gestor de arranque minimalista que permite también la selección y carga directa del OS, eliminando la necesidad de recurrir a gestores de arranque externos.
El nuevo firmware EFI es mucho mas complejo que la antigua BIOS, en lugar de recurrir a código almacenado en sectores de arranque del disco duro, EFI recurre a cargadores de arranque almacenados como archivos en una partición del disco, denominada ESP (EFI System Partition) que usa el sistema de archivos FAT. En Linux el ESP se suele montar en /boot/efi. Los cargadores de arranque residen en archivos con la extensión .efi en subdirectorios que reciben el nombre del OS o del cargador de arranque (/boot/efi/EFI/ubuntu/grub.efi). Esta configuración le permite almacenar un cargador de arranque independiente para cada SO que instale en el equipo. El firmware EFI incluye su propio programa, un administrador de arranque, para que pueda seleccionar el cargador de arranque secundario con el que iniciar un determinado OS.
EFI debe de conocer los cargadores de arranque instalados en el ESP, para ello se suelen registrar los cargadores en el firmware, bien mediante una interfaz de usuario del propio firmware o con una herramienta como el programa efibootmgr de Linux.
Nota: Muchas implementaciones EFI de x86-64 usan el cargador de arranque EFI/boot/bootx64.efi del ESP como predeterminado si no hay otros registrados.
Resumen sobre firmware: Para arrancar un sistema, la BIOS accede a un dispositivo configurado para ser el primero en detectar y lee el primer sector, en dicho sector se encuentra el MBR el cual contiene la tabla de particiones y el gestor de arranque, que será el encargado de continuar el arranque del OS. Si el administrador de arranque tiene un tamaño considerable, puede que este esté instalado en una partición primaria marcada como activa (por ejemplo /boot) y en cuyo sector de arranque se encuentra este administrador, quien cargará el kernel del sistema. En cambio, EFI lee un archivo de cargador de arranque que se encuentra en una partición especial del sistema de archivos ESP (EFI System Partition, Sistema de partición EFI) formateada normalmente con FAT. EFI ofrece una amplia variedad de opciones de arranque como arrancar desde distintos dispositivos a arrancar desde determinados sectores de arranque de otros disco del equipo. Los equipos con BIOS permiten un máximo de 4 particiones primarias (o 3 primarias y una extendida en la que crear mas particiones lógicas) y EFI nos permite hasta un máximo de 128 particiones (x86_64) todas primarias.
CARGADORES DE ARRANQUE
Bootloader (cargador de arranque): El gestor de arranque o cargador de arranque es el software inicializado por la BIOS o UEFI para llevar a cabo la carga del kernel con los parámetros apropiados y la imagen RAM inicial (initramfs), antes de iniciar el proceso de arranque del OS. Se pueden utilizar diferentes gestores de arranque como GRUB o Syslinux. Algunos gestores de arranque solo admiten arrancar desde la BIOS o UEFI y otros desde ambos.
Los cargadores de arranque EFI mas populares para Linux se basan en cargadores de arranque BIOS, por lo que ofrecen funciones que no suelen necesitar, como por ejemplo, permitir la concatenación con otro cargador de arranque.
Gestores de arranque que soportan UEFI y BIOS
- GRUB (GRand Unified Bootloader): Derivado (fork) de PUPA (proyecto de investigación destinado a mejorar GRUB Legacy). GRUB necesita crear una partición /boot separada para instalarse, a menos que se utilice el sistema de archivos Btrfs (compatible con los algoritmos de compresión zlib o LZO) para la partición root. GRUB es ahora modular y ya no requiere de la fase 1.5 o fase intermedia, en consecuencia los módulos para soporte de LVM o RAID deben ser cargados desde el disco duro. Los discos duros pasan de ser /dev/sda1 (GRUB Legacy) a hd0,msdos1 (disco 1 partición 1 para sistemas MBR) o hd0,gpt1 (para los sistemas que usan GPT), en GRUB.
- SYSLINUX: Es una colección de cargadores de arranque, capaz de iniciar desde discos duros, CDs o Red (utilizando PXE). Veremos su instalación en artículos destinados a tal fin en este mismo blog (https://nebul4ck.wordpress.com). De entre todos los cargadores de arranque incluidos en SYSLINUX quizás el mas importante sea ISOLINUX, un cargador de arranque para los discos ópticos.
Nota: Syslinux no es capaz de acceder a los archivos contenidos en una partición diferente de aquella en la cual se ha instalado. Tal característica (llamada multi-fs) no está aún implementada. Para un gestor de arranque alternativo con características multi-fs use GRUB.
Gestores de arranque para BIOS
- GRUB Legacy (GRUB de legado): Es el cargador por defecto de las distribuciones de Linux mas antiguas. Este cargador de arranque quedó eclipsado por su sucesor GRUB. Veremos como configurar GRUB Legacy en el apartado de “Configurar cargadores de arranque“
- LILO: Es un gestor de arranque mas sencillo, por lo que ofrece menos posibilidades a la hora de arrancar distintos OS. LILO cayó prácticamente en desuso con la llegada de GRUB.
- NeoGRUB: Es una implementación de GRUB2DOS proporcionado por el configurador de cargador de arranque EasyBCD para Windows. NeoGRUB permite arrancar Linux desde el cargador de arranque Windows, que para hacer esto posible incorpora una implementación de GRUB Legacy dentro del propio cargador de arranque Windows. NeoGRUB soporta los siguientes sistemas de archivos: FAT16/32, MINIXfs, ext2fs, Reiserfs, JFS y XFS.
Gestores de arranque para UEFI
- EFISTUB: A partir de la versión del kernel 3.3 Linux permite arrancar con EFISTUB. Esta característica permite que el firmware EFI cargue el kernel como un ejecutable EFI. Digamos que es un gestor de arranque minimalista que permite arrancar desde el propio firmware EFI.
- rEFIt: Es un administrador de arranque (no un cargador), se puede usar en PC basados en UEFI. Dispone de una atractiva interfaz gráfica. Actualmente es un administrador de arranque obsoleto
- rEFInd: Derivado de rEFIt para PCs basados en UEFI y para ampliar sus prestaciones. Al igual que rEFIt es un administrador de arranque con una bonita interfaz, útil para equipos con EFI que ofrecen administradores de arranque incompletos. Puede utilizarse junto con EFISTUB para ejecutar las imágenes mediante su menú.
- Gummiboot: Similar a rEFInd solo que su interfaz es en modo texto y cuenta con menos opciones.
- ELILO: Se utiliza en algunas distribuciones (en especial en OpenSUSE) como cargador de arranque predeterminado para equipos basados en EFI
Referencias:
Firmware:
http://es.wikipedia.org/wiki/BIOS
https://wiki.archlinux.org/index.php/Unified_Extensible_Firmware_Interface_%28Espa%C3%B1ol%29
Tabla de partición:
https://wiki.archlinux.org/index.php/Master_Boot_Record_%28Espa%C3%B1ol%29
https://wiki.archlinux.org/index.php/GPT
Cargador de arranque:
https://wiki.archlinux.org/index.php/Boot_loaders_%28Espa%C3%B1ol%29
https://wiki.archlinux.org/index.php/Syslinux_%28Espa%C3%B1ol%29
https://wiki.archlinux.org/index.php/GRUB_%28Espa%C3%B1ol%29
https://wiki.archlinux.org/index.php/UEFI_Bootloaders
Sobre Secure Boot: Con Secure Boot un equipo basado en EFI solo iniciará un cargador de arranque si se ha firmado criptográficamente con una clave cuyo duplicado se almacena en el firmware del equipo, evitando así que programas malintencionados accedan al ordenador al inicio del arranque.
Desde Linux el problema es que el uso de Secure Boot requiere la firma de un cargador de arranque de Linux con la clave de Microsoft (ya que es la única cuya presencia se garantiza en la mayoría de los equipos). En la práctica puede que tengamos que desactivar Secure Boot o generar su propia clave para arrancar una distribución arbitraria de Linux o un kernel personalizado.
CONFIGURAR LOS CARGADORES DE ARRANQUE.
Vamos a estudiar de una forma “breve” como configurar los principales cargadores de arranque GRUB Legacy, GRUB, SYSLINUX y UEFI con la herramienta efibootmgr.
Nota: Solo GRUB Legacy y GRUB son abarcados por el examen, será por ello por los que realicemos una descripción mas exhaustiva de estos cargadores de arranque, aun así, podrás encontrar aquí una entrada en este mismo blog sobre un uso eficiente de syslinux a la hora de instalar un sistema Fedora, del cual tenemos vmlinuz e initrd y arrancando desde una unidad externa. Sobre efibootmgr daremos una breve explicación de su uso.
Configurar GRUB Legacy.
La ubicación normal para el archivo de configuración de GRUB Legacy en un equipo basado en BIOS es /boot/grub/menu.lst (o grub.conf para algunas distribuciones como RedHat, Fedora o Gentoo). GRUB utiliza (hd0) o (hd0,0) por ejemplo para señalar la primera partición del primer disco en lugar de los archivos de dispositivos Linux (/dev/hda o /dev/sda), además no distingue entre dispositivos PATA, SATA, SCSI y USB, por lo que en un sistema que solo tiene SCSI, la primera unidad de disco será igualmente (hd0).
Nota: GRUB Legacy no arrancará desde una unidad USB si utiliza un ordenador antiguo que no admita unidades USB como discos duros.
Las asignaciones de unidades de GRUB Legacy se pueden encontrar en el archivo /boot/grub/device.map
GRUB Legacy interpretará como partición raíz aquella en la que se encuentre su archivo de configuración, por lo que si existe una partición independiente (/boot) para GRUB será está la partición que tome como partición raíz y no /, algo que deberemos de tener en mente a la hora de referenciar el kernel y la RAM inicial.
Estudiaremos las opciones (globales y de imágenes) de GRUB Legacy mediante la imagen anterior.
- La opción default=0 indica que arranque por defecto (si no pulsamos ninguna tecla antes del timeout) el primer OS de la lista, en este caso Fedora (3.4.1)
- Timeout=15 indica que tenemos 15 segundos para seleccionar un OS diferente al de por defecto.
- La línea splashimage=/grub/bootimage.xpm.gz hace que aparezca una imagen de fondo en el menú de selección. Como dijimos GRUB Legacy toma como directorio raíz aquel en el que se encuentra su archivo de configuración que en este caso es /boot por lo que la imagen realmente se encuentra en /boot/grub/bootimage.xpm.gz
Nota: Si la imagen que deseamos se encuentra en otra partición podremos especificarla con (hd0,2) si por ejemplo se encontrase en la 3º partición del primer disco.
- title Fedora (3.4.1) hará que en el menú de selección aparezca un OS con este nombre (Fedora …) en nuestro caso, además será el primero que aparezca del menú ya que se encuentra en primera posición.
- root (hd0,0) como imaginaremos, referencia a la primera partición del primer disco, recordemos que para nosotros es /boot (ya que es una partición independiente marcada como activa en la tabla de particiones)
- El parámetro kernel describe la ubicación del kernel de Linux a cargar, y sus respectivos parámetros. Una vez mas, la ruta es relativa a su partición primaria, es decir el kernel se encuentra dentro de /boot/
Nota: Si tuviésemos el kernel en otra partición o incluso en otro disco podríamos especificarlo así: kernel (hd0,4) /vmlinuz…
- Utilice la opción initrd para especificar un disco RAM inicial que contiene un conjunto mínimo de controladores, herramientas y archivos de configuración, empleados por el kernel en un punto del proceso de arranque para poder montar su sistema de archivos raíz antes de que pueda acceder al disco duro. Además esto disminuye considerablemente el tamaño del archivo kernel principal.
- Con la opción rootnoverify GRUB Legacy no intentará acceder a los archivos de esta partición debido a que no puede cargar directamente por ejemplo, un kernel como el de DOS o Windows.
- Por ultimo la opción de cargar en cadena: chainloader indica a GRUB que pase el control a otro cargador de arranque. Normalmente se pasa la opción +1 para cargar el primer sector de la partición del SO de destino, que para este ejemplo es (hd0,1). La carga en cadena funciona en equipos BIOS. Una versión de GRUB Legacy compatible con EFI, puede realizar la carga en cadena, pero debe indicar a GRUB que use el ESP, indicando la partición como siempre (hd0,0) y después pasar el nombre de un archivo de cargador de arranque EFI a través de la opción chainloader, como chainloader /EFI/Microsoft/boot/bootmgfw.efi
Nota: Las opciones de las imágenes de GRUB Legacy suelen presentar sangrías tras la primera línea, pero esto es una convención y no un requisito del formato del archivo.
Para instalar GRUB Legacy usamos el comando grub-install acompañado del nombre de dispositivo en el que se encuentra el sector de arranque:
- # grub-install /dev/sda o # grub-install ‘(hd0)’
Nota: Ambos comandos instalarán el cargador de arranque en el primer sector del disco 1 (en el MBR). Si quisiéramos instalarlo en el sector de arranque de una partición concreta podríamos indicarlo de igual modo …./sda2 o ‘(hd0,1)’
En Fedora: Para instalar GRUB Legacy compatible con EFI copie el archivo grub.efi y grub.conf en /boot/efi/EFI/redhat. Si realiza una instalación con rpm grub-efi el archivo .efi se incluirá en esta ubicación de forma predeterminada. Puede que tenga que usar efibootmgr para añadir el cargador de arranque a la lista de EFI de la siguiente manera:
- # efibootmgr -c -l \\EFI\redhat\grub.efi -L GRUB
Nota: UEFI utiliza la barra invertida \
como separador de ruta (similar a las rutas de Windows), pero el paquete oficial efibootmgr proporciona soporte a las rutas de estilo unix con barras diagonales /
como separador de ruta para la opción -l
. Efibootmgr convierte internamente /
a \
antes de codificar la ruta de acceso del cargador. Hubiese valido igualmente /EFI/redhat/grub/.efi -L GRUB
Utilizar GRUB como cargador de arranque
GRUB está diseñado para funcionar en equipos basados en BIOS y EFI.
La configuración de GRUB2 es muy similar a la de GRUB Legacy, aunque difieren en varios aspectos como el nombre o ruta del archivo de configuración, la compatibilidad con módulos de carga (el comando insmod del archivo de configuración de GRUB2 permite cargar módulos), la admisión de instrucciones lógicas en la configuración, la forma en la que manipulamos el archivo de configuración, etc…
El archivo de configuración pasa a llamarse grub.cfg (y no grub.conf o menu.lst) y la ruta puede contener un 2 en grub (/boot/grub2/..) lo que permite instalar los dos cargadores de arranque (GRUB Legacy y GRUB2 o GRUB).
Un aspecto importante a tener cuenta es el cambio de nombre de algunos de sus parámetros en el archivo de configuración y la forma en la que manipulamos a este.
Por ejemplo la palabra title pasa a llamarse menuentry, el título de menú se incluye entre comillas, además tras este aparece una llave ({) y cada entrada termina con una llave de cierre (}), set precede a la palabra clave root y se usa el signo (=) para separar a root de la partición, la palabra clave rootnoverify se ha eliminado y en su lugar se utiliza root, las particiones (no lo discos) se empiezan numerando desde 1 y no desde 0, y destacar que las versiones mas recientes de GRUB también admiten un sistema de identificación de particiones para especificar el tipo de tabla de partición como (hd0,gpt2) para indicar la 2º partición del primer disco de una tabla de particiones GPT o (hd0,mbr3) para referenciar a la 3º partición del primer disco de una tabla MBR.
Como comentábamos anteriormente la forma en la que se manipula ahora el archivo de configuración de GRUB difiere de GRUB Legacy y es devido a que GRUB utiliza una serie de scripts para el mantenimiento automático del archivo de configuración. Estos scripts buscan en el sistema versiones de kernel y añaden entradas a GRUB. El objetivo de esto es que los administradores del sistema nunca tengan que editarlo de forma explícita. En su lugar se editan los archivos de /etc/grub.d y el archivo /etc/default/grub que controla los elementos predeterminados creados por los scripts de configuración. Por ejemplo si desea ajustar el tiempo de espera, podría cambiar la siguiente línea:
GRUB_TIMEOUT=10
y tras realizar los cambios, deberemos de volver a generar el archivo grub.cfg con los comandos update-grub, grub-mkconfig > /boot/grub/grub.cfg o grub-mkconfig -o /boot/grub/grub.cfg, como ya comentamos algunas instalaciones usan el 2 tras la palabra grub, habrá que tener esto presente.
Al instalar Linux por primera vez, el instalador debe configurar GRUB correctamente y usar grub-install de la misma forma que GRUB Legacy.
La recuperación de GRUB en caso de sufir daños, la dejaremos para artículos independientes de este mismo blog, pero como nota, mencionaremos la herramienta supergrubdisk (http://supergrubdisk.org), que es una imagen de disco de arranque con varias opciones para localizar y usar el archivo de configuración de GRUB en su disco duro.
Configurar UEFI con efibootmgr
Como comentamos anteriormente UEFI posee un gestor de arranque minimalista mediante el cual podremos añadir entradas de arranque en la placa base (siempre y cuando esta y sus implementaciones no lo permitan) usando el comando efibootmgr.
efibootmgr requiere que el kernel tenga soporte para acceder a las variables no volátiles de EFI ( /proc/efi/vars en kernels 2.4 y /sys/firmware/efi/vars en kernels 2.6). Podemos ayudarnos de lsmod |grep efivars y modprobe para comprobar el soporte.
Primero vamos a comprobar que el soporte para las variables de UEFI en el kernel funcionan correctamente:
# efivar -l
Si todo ha ido OK y efivar nos ha enumerado las variables, creamos la entrada de arranque:
# efibootmgr -c -d /dev/sdX -p Y -l /EFI/refind/refind_x64.efi -L "label_de_entrada"
Podemos verificar la entrada con:
# efibootmgr -v
Nos devolverá un número por cada entrada. Utilice estos números para ordenar las entradas con el comando:
# efibootmgr -o <num_entrada>,<otra_entrada>,<etc...>
Advertencia: Algunas combinaciones de kernel y efibootmgr podrían negarse a crear nuevas entradas de inicio. Esto podría ser debido a la falta de espacio libre en la memoria NVRAM. Podría tratar de eliminar cualquier archivo de volcado de EFI:
# rm /sys/firmware/efi/efivars/dump-*
Podemos encontrar documentación extra, en caso de tener problemas con los requisitos del kernel por ejemplo en:
PROCESO DE ARRANQUE
Los pasos que sigue un ordenador para arrancar un sistema operativo son los siguientes:
1. Se enciende el sistema y un circuito de hardware especial hace que la CPU busque y ejecute el firmware (BIOS o UEFI).
2. El firmware realiza tareas de comprobación del hardware, de configuración (POST) y por último si todo va bien, busca el cargador de arranque.
3. Cuando el control pasa del firmware al cargador de arranque carga un kernel o enlaza la carga de otro cargador de arranque.
kernel: Es el núcleo de un sistema operativo. Funciona en un nivel bajo (kernelspace) que interactúa entre el hardware de la máquina y los programas que utilizan los recursos del hardware para funcionar. Para hacer un uso eficiente de la CPU, el kernel utiliza un sistema de programación para arbitrar qué tareas tienen prioridad en un momento dado, creando la ilusión (para la percepción humana) de que varias tareas se están ejecutando simultáneamente.
4. Cuando el kernel de Linux toma el control, este descomprime la imagen initramfs (sistema de archivos RAM inicial), que se convierte en el sistema de ficheros root inicial, y comienza la carga de dispositivos, monta la partición raíz y por último carga y ejecuta el programa inicial de su sistema (por defecto /etc/init).
initram o RAM inicial: El propósito de initramfs es arrancar el sistema hasta el punto donde se puede acceder al sistema de archivos raíz, esto significa que los módulos que se requieren para dispositivos como IDE, SCSI, SATA, USB, etc… deben ser cargados desde initramfs si no están compilados en el kernel. Una vez que los módulos necesarios se cargan (ya sea de forma explícita a través de un programa o script, o implícitamente a través de udev), el proceso de arranque continúa.
Nota: initramfs sólo debe contener los módulos necesarios para acceder al sistema de archivos raíz, no tiene por qué contener todos los módulos que sirven al completo funcionamiento de la máquina. La mayoría de los módulos se cargarán más tarde por udev, durante la fase init.
5. El programa inicial recibe el ID de proceso 1 (PID1) que es el primer programa que se ejecuta en el sistema de arranque tradicional de Linux. /sbin/init lee el archivo /etc/inittab para determinar que otros programas ejecutar. En sistemas que utilicen Upstart o systemd, /sbin/init lee otros archivos de configuración e incluso su nombre se ve reemplazado como es el caso para systemd donde init pasa a ser systemd
init lanza las getty, una para cada terminal virtual (normalmente seis de ellas), las cuales inicializan cada tty pidiendo el nombre de usuario y contraseña. Una vez que se proporcionan el nombre de usuario y la contraseña, getty los compara con las que se encuentran en /etc/passwd, llamando a continuación al programa login, para que, una vez iniciada la sesión de usuario, lance la shell de usuario de acuerdo con lo definido en /etc/passwd. Alternativamente, getty puede iniciar directamente un gestor de pantallas si existe uno presente en el sistema, de haberlo este se ejecutará en la tty configurada, reemplazando el prompt de inicio de la getty.
Proceso de arranque:
http://es.wikipedia.org/wiki/Registro_de_arranque_principal
http://es.wikipedia.org/wiki/Proceso_de_arranque_en_Linux
http://es.wikipedia.org/wiki/Arranque_%28inform%C3%A1tica%29
Una vez que el kernel es cargado:
https://wiki.archlinux.org/index.php/Arch_boot_process_%28Espa%C3%B1ol%29#Tipos_de_firmware
Initramfs:
https://wiki.archlinux.org/index.php/Mkinitcpio_%28Espa%C3%B1ol%29
SISTEMA DE INICIALIZACIÓN SYSTEM V (SysV)
Linux se basa en modos de ejecución para determinar que funciones hay disponibles, enumerados del 0 al 6. Cada uno de ellos tiene asignado un conjunto de servicios.
Los modos de ejecución 0,1 y 6 están reservados para fines especiales; los modos de ejecución restantes están disponible para los objetivos que desee o los que decidan los proveedores de las distintas distribuciones Linux.
Nota: Puede haber modos de ejecuciones fuera del rango 0-6, pero es algo poco habitual.
Es importante saber cuales son estas funciones y cómo gestionar los modos de ejecución para poder controlar el proceso de arranque de Linux y las operaciones en curso. Para ello se debe conocer la finalidad de cada modo de ejecución, identificar los servicios activos en cada uno de ellos, gestionarlos, revisar sus modos de ejecución actuales y poder cambiarlos si fuese necesario.
Funciones de los modos de ejecución
El archivo /etc/inittab define y describe los distintos modos de ejecución.
- 0 : Se emplea para apagar el sistema. Es un modo transitorio, es decir se emplea para pasar de un estado a otro. En este caso de iniciado a cerrado. En equipos con hardware moderno el sistema se apaga por completo, no así en equipos mas antiguos donde tiene que intervenir el usuario.
- 1 : Modo monousuario, también representado por s, S o single. Se suele emplear para realizar un mantenimiento a bajo nivel, como por ejemplo el redimensionamiento de particiones, configuración del servidor X, etc…
- 2 : En Debian y sus derivados es un modo multiusuario completo con X en ejecución. Muchas otras distribuciones dejan este modo de ejecución sin definir.
- 3 : Para una gran mayoría de distribuciones como Red Hat o sus derivados, se define este modo como un modo multiusuario mediante terminal
- 4 : Disponible para configuraciones personalizadas
- 5 : En Fedora, Mandriva, Red Hat y la mayoría de las demás distribuciones tienen el mismo comportamiento que el modo 3 pero con servidor X.
- 6 : Se emplea para reiniciar el sistema. Al igual que el modo 0, este es un modo transitorio, donde el ordenador se apaga por completo y vuelve a iniciar.
Si configura su sistema con los modos 0 y 6 su sistema se apagará o reiniciará en cuanto termine el proceso de arranque. En la mayoría de distribuciones, lo normal es tener el sistema configurado para que arranque en el modo de ejecución 2,3 o 5.
Nota: Las distribuciones que usan sistemas de inicio mas moderno (Upstart o systemd) no suelen utilizar modos de ejecución de forma nativa, pero ofrecen herramientras de compatibilidad que hacen que parezca que el ordenador los usa.
Identificar los servicios de un modo de ejecución.
Existen varias maneras de identificar que programas se ejecutan cuando se pasa a un modo de ejecución concreto con SysV, como por ejemplo a través del archivo /etc/inittab o bien con la herramienta chkconfig. Con la herramienta update-rc.d podremos activar y desactivar servicios para runlevels específicos. Tenemos detallada estas dos herramientas en el apartado de comandos de este mismo capítulo.
Nota: Para identificar programas que son ejecutados en un determinado modo de ejecución, existe una forma mas rudimentaria que es localizar el directorio del modo de ejecución concreto y listar su contenido. En el listado aparecerán los enlaces simbólicos hacia scripts principales de los programas que serán ejecutados en ese modo. Esto lo veremos mas adelante cuando estudiemos los scripts de inicio SysV
Para identificar o definir programas para un cierto modo de ejecución mediante el archivo /etc/inittab, antes tendremos que conocer su estructura.
Las entradas de /etc/inittab siguen un formato sencillo:
id:modosdeejecución:acción:proceso
Donde:
- id es una secuencia de uno a cuatro caracteres que identifica su función
- modosdeejecución es una lista de los modos de ejecución para los que se aplicará la entrada. Puede definirse un solo modo (por ejemplo 3) o varios de ellos (2,3,5)
- acción indica a init cómo tratar el proceso. Por ejemplo: wait inicia el proceso una vez cuando pase a un modo de ejecución y espera a que este finalice, respawn reinicia el proceso cada vez que finalice, powerwait indica a init que apague el sistema antes una falla en el sistema eléctrico (se precisa un UPS), ctraltdel reinicia el sistema cuando el usuario presione esas teclas (podemos cambiar las funciones o anularlas), sysinit comando ejecutado cuando inicia el sistema (por ejemplo limpiar /tmp), etc… podremos conocer mas acciones a través de man inittab. Para la acción initdefault se ignora el campo proceso.
- proceso es el proceso que ejecutar para una determinada entrada, incluyendo las opciones y argumentos que sean necesarios.
Una vez entendida la estructura del archivo /etc/inittab podremos saber como introducir nuevas entradas para nuevos procesos o eliminar en caso de que no queramos que un programa sea ejecutado en un determinado modo.
Antes de comentar la segunda forma de identificar programas ejecutados en un determinado modo de ejecución vamos hablar sobre los scripts de inicio Sysv.
El script /etc/init.d/rc o /etc/rc.d/rc realiza la tarea crucial de ejecutar todos los scripts asociados con el modo de ejecución. Estos scripts se encuentran almacenados en /etc/rc.d/rc?.d, /etc/init.d/rc?.d, /etc/rc?.d o en ubicaciones similares, donde ? es el modo de ejecución. Cuando se pasa a un determinado modo de ejecución, rc le pasa el parámetro start a todos los scripts que se encuentran dentro del directorio del modo especificado cuyos nombres comienzan con S y el parámetro stop a los archivos cuyo nombre comienza con K. El programa rc ejecuta los scripts en orden numerico debido a que algunos servicios dependen de otros, es por esto que los nombres de los scripts además de empezar por S o K tienen un número. En realidad estos scripts no son mas que enlaces simbólicos a los scripts principales que se suelen almacenar en /etc/rc.d, /etc/init.d o /etc/rc.d/init.d (la ubicación depende de la distribución).
Sabiendo esto podremos determinar que servicios están activos o se pararán, en un modo de ejecución específico, buscando los scripts cuyos nombres de archivos comiencen por S o por K en el directorio de scripts de inicio SysV apropiado.
También podemos usar la herramienta chkconfig de la siguiente manera:
# chkconfig --list
O si estamos interesado en un servicio concreto:
# chkconfig --list <servicio>
Gestionar los servios de los modos de ejecución
Al igual que existen dos formas para identificar servicios en un determinado modo de ejecución (o 3 si separamos el uso de chkconfig y la búsqueda de scripts por sus directorios) podemos gestionar los programas para que sean ejecutados o parados según el modo de ejecución de la misma manera.
Mediante el archivo /etc/inittab:
Bastará con añadir o eliminar entradas del archivo
Con chkconfig:
Modificar los modos de ejecución para un determinado servicio
# chkconfig --level 235 <servicio> on|off|reset
Nota: Con reset le asignaremos su valor por defecto
Si hemos añadido un script de inicio al directorio principal de los scripts (/etc/init.d, por ejemplo) podemos hacer que chkconfig lo registre y añada los enlaces de inicio y fin apropiados en los directorios de modo de ejecución adecuados.
# chkconfig --add <servicio>
Cuando lo hagamos, chkconfig inspeccionará el script en busca de comentarios especiales para indicar los modos de ejecución por defecto. Puede que este método no funcione si el script carece de las líneas de comentario necesarias con los números de secuencia de los modos de ejecución que utiliza chkconfig.
Podemos hacer este trabajo de forma manual que sería creando nosotros mismos el enlace simbólico del script principal en los directorios de los modos de ejecucion en los que queremos que se inicie o detenga un programa concreto. Tenemos que tener en mente los nombres de archivos con S, K y los números de orden.
Importante: Podemos iniciar, detener o comprobar el estado de los servicios mediante la ejecución del comando ‘service‘:
# service samba status|start|stop
o con la ejecución del script principal
# /etc/init.d/samba status|start|stop
Existe la herramienta ntsysv la cual nos permitirá marcar aquellos servicios que queremos ejecutar durante el arranque. Es una herramienta ‘gráfica’ de línea de comandos, su uso es sencillo y puede resultar útil incluso para ver que servicios tenemos marcados en el arranque. También puede ser usada para especificar un runlevel concreto.
Comprobar y cambiar el modo de ejecución
Podemos comprobar el modo de ejecución por defecto y el modo de ejecución actual.
Para comprobar el modo de ejecución por defecto basta con desplegar el contenido del archivo /etc/inittab y localizar la entrada que contiene como acción :initdefault:, esto no suele ser válido para equipos que usen Upstart, systemd u otra herramienta de inicialización.
Si por el contrario el sistema está en funcionamiento, puede ver su modo de ejecución actual como el comando runlevel:
# runlevel N 2
El primer caracter es el modo de ejecución anterior, en este caso N, lo cual indica que el sistema no ha cambiado de modo de ejecución desde el arranque. El segundo caracter 2 es su modo de ejecución actual.
Se puede cambiar a modos de ejecución diferentes en un sistema operativo en funcionamiento con los programas init (o telinit), shutdown, halt, reboot y poweroff.
Por ejemplo para cambiar al modo monousuario o reiniciar el sistema podemos usar:
# init 1 o # init 6 (respectivamente)
init no es el comando mas lógico para reiniciar, apagar o pasar a modo monousuario, ya que lo hace de forma inmediata y podríamos molestar a otros usuarios conectados al sistema, pero si que sirve por ejemplo para que el sistema vuelva a leer el archivo /etc/inittab
El comando telinit es una variante de init, normalmente es un enlace simbólico aunque la páginas man de ambos comandos presentan una sintaxis ligeramente distinta. Si quisieramos por ejemplo que se volviese a leer el archivo /etc/inittab, podriamos usar telinit o init de la siguiente manera:
# telinit q # telinit Q
Nota: Las herramientas Upstart y systemd ofrecen los comandos init y telinit que funcionan de una forma similar.
Cuando desee reiniciar (6), apagar (0) o pasar a modo monousuario (1) en un entorno multiusuario, lo mejor será emplear el comando shutdown.
Pasar a modo monousuario de forma inmediata:
# shutdown now
Reiniciar el sistema en 5 minutos
# shutdown -r +5
Apagar el sistema a las 13:45
# shutdown -P 13:45
Suspender el equipo (no lo apaga) a las 1:30 AM avisando a los usuarios.
#shutdown -H 1:30 "A las 1:30 de la madrugada el sistema va a ser detenido"
Nota: La opción -h puede detener o apagar el equipo, aunque normalmente acaba apagándolo.
Detener el apagado de un equipo por un cambio de ultima hora (por ejemplo):
# shutdown -c "Se pospone el reinicio del sistema, se avisará nuevamente. Disculpen"
Nota: Upstart y systemd ofrecen la herramienta shutdown
Otros tres comandos útiles para detener, reiniciar o apagar el sistema respectivamente tanto en SysV, Upstart como con systemd son: halt, reboot y poweroff
SISTEMA DE INICIALIZACIÓN UPSTART
Básicamente, Upstart hace lo mismo que las secuencias de comandos Sysvinit (SysV) pero está mejor diseñado para admitir el hardware actual y su continuo dinamismo, lo que permite conectarlo y desconectarlo de un ordenador en ejecución. Mientras SysV trabaja de una forma síncrona, el modelo basado en eventos de Upstart le permite responder a los eventos de una forma asíncrona cuando estos son generado, resolviendo así alguno de los problemas que presenta SysV, como el bloqueo de futuras tareas hasta que la actual se haya completado.
Para sistemas con Upstart el PID 1 sigue siendo para init, padre de todos los procesos en el sistema (incluso de los procesos huérfanos) y responsable de iniciar el resto de procesos.
Upstart ofrece funciones compatibles con SysV, no obstante también cuenta con sus propios scripts y difiere en algunos aspectos importantes, en concreto Upstart ignora el archivo /etc/inittab, en su lugar proporciona un conjunto integrado de scripts de arranque que en principio pueden reemplazar totalmente a /etc/inittab y a los scripts de arranque específico del modo de ejecución de SysV, que en vez de encontrarse bajo directorios como /etc/init.d/rc?.d, /etc/rc.d/rc?.d o /etc/rc?.d se encuentran en el directorio /etc/init, con nombre ‘servicio’.conf, donde servicio es el programa que init tratará como un job. Los scripts de Upstart ofrecen mas acciones que los de SysV, por ejemplo iniciar un servicio siempre que se conecte un determinado dispositivo de hardware.
Al igual que usábamos el comando #service <servicio> start|stop|status para iniciar un script SysV, en Upstart tenemos la opción de utilizar el comando initctl con el que podremos iniciar, parar, ver el estado, etc… de los servicios del sistema o directamente usar start y stop
$sudo initctl stop smbd o $sudo stop smbd
Nota: Para ver un listado de estos servicios podemos listar el contenido de /etc/init donde se encuentran como ya sabemos todos archivos de configuración de servicios Upstart, por lo que el nombre del servicio es igual a los del directorio pero sin .conf
El comando service podremos seguir usándolo para servicios SysV instalados en el sistema. Anteriormente hemos comentado que los scripts de Upstart sustituyen de forma completa a los scripts de SysV y a su archivo /etc/inittab, pero esto no es del todo cierto ya que Upstart concede en cierto modo la compatibilidad con SysV. Upstart continua ejecutando scripts de SysV (ubicados en los mismos directorios como si de un sistema SysV se tratase) debido a que existen programas que aún no incluyen los scripts de configuración Upstart y necesitan ser arrancado de forma habitual.
Si ha instalado utilidades como chkconfig en sistemas que inicializan con Upstart deberá poder usarla para gestionar sus servicios SysV. No obstante chkconfig y estos servicios que aun se mantienen en SysV acabarán desapareciendo debido a que el progreso apunta a Upstart y systemd.
Gracias a la API inotify no será necesaria la recarga de un archivo de configuración (archivo con el que se configura un servicio por ejemplo smb.conf) para un determinado servicio, ya que esta proporciona un mecanismo para el seguimiento de eventos del sistema de archivos, lo cual supervisa tanto archivos individuales como directorios, por lo que si se diera el caso de que un archivo a sido modificado este será recargado automáticamente
Para cambiar los modos de ejecución en los que se ejecuta un servicio concreto, tendrá que editar su archivo de configuración Upstart (/etc/init/’servicio’.conf), localice el script del servicio que quieres modificar, ábrelo para editar, y encuentre las líneas que contengan el texto start on y stop on.
Estos archivos suelen tener un formato similar al siguiente:
Vemos la cadena start on y stop on runlevel, seguidas de [2345] y [!2345], en este caso se indica que el servicio ssh se inicie en los modos 2345 y sea detenido para cualquier modo distinto (!) de los indicados, también 2345.
Podemos ver cadenas de start on mas complejas en las que se hace uso de mountall, es un demonio propio de Debian y Ubuntu que se encarga de montar los sistemas de ficheros que se especifican en /etc/fstab y /lib/init/fstab, y que además emite una serie de eventos útiles cuando estos son o no montados como por ejemplo:
- mounting: Emitido cuando un sistema de archivos en particular está a punto de ser montado.
- mounted: Emitido cuando un sistema de archivos en particular ha sido montado correctamente.
- all-swaps: Se emite cuando se montan todos los dispositivos de intercambio
- filesystem: Una vez que todos los sistemas de archivos han sido montados (o intentado)
- virtual-filesystem: Emitida después de que se haya montado el último sistema de archivos virtual
- local-filesystem y remote-filesystem: Cuando el último sistema de archivos local o remoto (respectivamente) hayan sido montado
Por lo tanto podemos encontrar entradas como esta:
Existen situaciones en las que nos interesa que un proceso se restaure automáticamente como por ejemplo en casos de fallos y cierres inesperados del servicio, para ello Upstart (al igual que SysV) ofrece el comando respawn con el que además podemos especificar límites como en el caso de la imagen (respawn 10 5) que viene a significar que si el proceso se reinicia mas de 10 veces en 5 segundos, finalice definitivamente.
Nota: Para un proceso, un ‘cierre inesperado’ será siempre que no se detenga con la orden stop, mientras que para una tarea es cuando el código de retorno sea diferente a 0.
Se pueden seleccionar secciones del archivo .conf, como por ejemplo en nuestro caso aparece pre-start script que indica que los siguientes comandos sean ejecutados antes de que el servicio sea arrancado
Podemos habilitar los trabajos de usuarios para permitir que los usuarios tengan acceso a los métodos y propiedades de Upstart, el archivo para esto es /etc/dbus-1/system.d/Upstart.conf, los trabajos de usuario se encuentran en ~/.init
Para ver los comandos que podemos utilizar dentro de un archivo .conf viste la web: http://upstart.ubuntu.com/wiki/Stanzas
Para mas información podemos acudir a la siguiente página, donde aprenderemos incluso a crear nuestros propios archivos de configuración de servicios: http://upstart.ubuntu.com/cookbook/
SISTEMA DE INICIALIZACIÓN SYSTEMD
Sobre systemd
systemd ha sido creado para ofrecer un inicio mas rápido y flexible que SysV, permitiendo el arranque paralelo de servicios y su inicio basado en la detección de conexión de nueva unidad externa.
Nota: Hasta ahora el PID1 era para el programa init, cosa que ha cambiado en systemd a favor de /usr/lib/systemd/systemd y además systemd al igual que Upstart deja de utilizar el archivo /etc/inittab
Algunas de las mejoras que ofrece systemd:
- Se ha mejorado sustancialmente la velocidad de inicialización del sistema
- systemd asume que cualquier dispositivo puede ser conectado o desconectado en cualquier momento (hotplug)
- systemd utiliza la activación de daemons por medio de sockets, aportando capacidades de paralelización
- Una de sus características es el registro (journal) mediante cgroups de todos los servicios y procesos iniciados
- systemd es modular, esto quiere decir que se han elaborado una seríe de “paquetes” en los que varios servicios son administrados de forma conjunta
Según definición oficial systemd es: Un sistema y administrador de servicios para Linux, compatible con scripts de inicio (init) SysV y LSB. systemd proporciona capacidades de paralelización agresiva, utiliza socket y activación D-Bus para iniciar los servicios, ofrece la puesta en marcha de demonios bajo demanda, realiza el seguimiento de procesos utilizando Linux cgroups, soporta copia instantánea de volumen y la restauración de estado del sistema, mantiene puntos de montaje y automontaje e implementa un elaborado servicio lógico de control transaccional basado en la dependencia.
Vamos a desglosar un poco esta definición:
- Capacidades de paralelización agresiva usando socket: systemd crea de una misma vez todos los sockets para todos los demonios acelerando así el arranque completo e iniciar más procesos en paralelo. En un segundo paso systemd ejecutará a la vez todos los demonios.
- Activación D-Bus para iniciar servicios: Utilizando la activación D-Bus, un servicio puede ser iniciado la primera vez que es accedido.
- Seguimiento de procesos utilizando Linux cgroups: cgroup también llamados grupos de control, es una característica del kernel para crear límites, políticas e incluso explicar el uso de los recursos de ciertos grupos de procesos. cgroup asocia un conjunto de tareas con un conjunto de parámetros, para uno o más subsistemas, proporcionando un control de servicios y tareas, así como todos sus futuros ‘hijos’ en grupos jerárquico. Un subsistema es un módulo resultado de la agrupación de diversas tareas con el fin de mantener un mejor control sobre estas de forma particular.
Nota: La herramienta systemd-cgls nos muestra recursivamente el contenido del árbol de jerarquías de un determinado grupo de control de Linux.
- Mantiene puntos de montaje y automontaje: Puede utilizarse para montar o desmontar los puntos de montaje, quedando /etc/fstab como una fuente de configuración adicional a la que podremos llamar para su supervisión con la opción “comment=” de fstab para marcar las entradas controladas por systemd.
Unidades de servicios (units)
systemd inicia y supervisa todo el sistema y se basa en la noción de unidades, compuestas de un nombre (el nombre del demonio) y una extensión. Será la extensión la que indique de que tipo de unidad se trata. Además cada unidad tiene su correspondiente archivo de configuración cuyo nombre es idéntico. Un ejemplo sería el servicio httpd.service cuyo archivo de configuración sería httpd.service. Los archivos de unidades disponibles en nuestro sistema podemos encontrarlos en /usr/lib/systemd/system/ y /etc/systemd/system/
Nota: Los archivos bajo el directorio /etc/systemd/system/ prevalecerán en caso de duplicados.
Existen siete tipos diferentes de unidades:
- service: Demonios que pueden ser iniciados, detenidos, reiniciados o recargados.
- socket: Esta unidad encapsula un socket en el sistema de archivos o en Internet. Cada unidad socket tiene una unidad de servicio correspondiente.
- device: Esta unidad encapsula un dispositivo en el árbol de dispositivos de Linux.
- mount: Esta unidad encapsula un punto de montaje en la jerarquía del sistema de archivos.
- automount: Encapsula un punto de montaje automático. Cada unidad automount tiene una unidad mount correspondiente, que se inicia al acceder al directorio de automontaje.
- target: Utilizada para la agrupación lógica de unidades. Referencia a otras unidades, que pueden ser controladas conjuntamente, un ejemplo sería multi-user.target, que básicamente desempeña el papel de nivel de ejecución 3 en el sistema clásico SysV.
- snapshot: Similar a las unidades target.
Entonces los archivos de configuración tendrán los nombres: programa.service, socket.socket, dispositivo.device, puntodemontaje.mount, etc…
Nota: La unidad default.target activa servicios y otras unidades dependientes, durante el arranque de systemd. Esto lo comentaremos en el apartado target
Compatibilidad de systemd con SysV
systemd al igual que Upstart ofrece compatibilidad con SysV (comando service y chkconfig) para aquellos servicios que aun soportan o funcionan únicamente con scripts de inicio SysV (actualmente en 2015, son pocos los servicios que corren bajo SysV). Upstart pese a mantener compatibilidad con los comandos service y chkconfig de SysV implementó su propia utilidad para la administración de servicios, de igual modo systemd lo hace con su herramienta systemctl
#systemctl stop nombreservicio.service
En SysV habilitábamos servicios con chkconfig (o reproducíamos listas de estos para ver cual de ellos se ejecutaba al arranque), algo que ahora bajo systemd podemos hacer con los siguientes comandos:
Habilitar el servicio httpd al arranque del sistema (chkconfig httpd on , para SysV):
#systemctl enabled httpd.service
Listar todas las unidades de servicios instaladas (algo parecido a chkconfig –list)
#systemctl list-unit-files
O solo aquellas que se encuentran en activadas:
#systemctl list-units o #systemctl
Podemos apreciar que a la hora de pasar el nombre del servicio lo hacemos con el nombre completo, es decir incluyendo su sufijo, pero existen una serie de atajos:
- Si no se especifica el sufijo, systemctl asumirá que es .service. Por ejemplo, netcfg y netcfg.service se consideran equivalentes.
- Los puntos de montaje se traducirán automáticamente en la correspondiente unidad .mount. Por ejemplo, si especifica /home será equivalente a home.mount.
- Similar a los puntos de montaje, los dispositivos se traducen automáticamente en la correspondiente unidad .device, por lo tanto, la especificación /dev/sda2 es equivalente a dev-sda2.device.
Nota: Consulte man systemd.unit para más detalles.
Uso de systemctl
La utilidad de administración de las unit de systemd es systemctl, la cual combina las herramientas service y chkconfig de SysV, por lo tanto podremos arrancar, parar, recargar servicios, activar o desactivar servicios en el arranque, listar los estados de los servicios,etc…
Creo que con la siguiente tabla veremos el uso básico de systemctl además de sus “iguales” en SysV.
1* Puede que un servicio este “enable” pero no tiene porqué estar activo cuando iniciemos sesión ya que puede que ese servicio este configurado para ejecutarse solo en determinados runlevels (o target en nuestro caso), a diferencia de chkconfig –list de SysV que mostraba todos los servicios con todos los runlevels posibles y para cada uno indicaba si estaba on o off. Para conseguir algo parecido en systemd, tendríamos que listar los target disponibles y veríamos que servicios se ubican dentro de estos, así sabremos con que target (o runlevel) un servicio será iniciado. Podemos emplear el siguiente listado
#ls /etc/systemd/system/*.wants/httpd.service /etc/systemd/system/multi-user.target.wants/httpd.service
Este comando nos devuelve que el servicio httpd se encuentra bajo multi-user.target lo que viene siendo el runlevel 3 de SysV. En los siguientes apartados conoceremos los distintos target que de algún modo tienen similitud con los runlevels de SysV
Nota: Podríamos haber omitido el subdirectorio /httpd.service para conocer la lista completa de targets y sus unit (mount, service, socket…)
Podemos hacerlo de una forma inversa (para lo cual hay que conocer el target), es decir ver que servicios están ejecutándose para un target concreto:
#systemctl show -p “Wants” multi-user.target
Además de los comandos de la tabla también podemos ver las units de servicios que tenemos cargados en el sistema con el comando:
#systemctl -t service list-units –all
Con este comando veremos que servicios están cargados y además si están activos o muertos a parte de una pequeña descripción.
Nota: Podemos cambiar service por mount, socket, device… para listar otros tipos (-t) de units.
Si en vez de ver las units cargadas queremos ver cuantas hay instaladas (es decir aquellas que tienen archivos de configuración instalados en nuestro sistema y por lo tanto están disponibles):
#systemctl -t service list-unit-files –all
Nota: Podemos cambiar el tipo de unit o directamente omitir el parámetro -t y listar todas.
Aprenderemos mas sobre el comando systemctl en el apartado de comandos para este tema (Tema-5)
Sugerencia: Puede utilizar las siguientes órdenes systemctl con el parámetro -H usario@host para controlar una instancia de systemd en una máquina remota. Esto utilizará SSH para conectarse a la instancia systemd remota.
Target
systemd utiliza target en vez de runlevels (0123456) que reciben un nombre (en vez de un número) para identificar un propósito específico, con la posibilidad de realizar más de una acción al mismo tiempo. Algunos targets pueden heredar todos los servicios de otro target e implementarse con servicios adicionales. La siguiente tabla muestra la similitud entre algunos de los target con los runlevels de SysV:
Nota: Actualmente no existen target similares a los runlevels 2 y 4 de SysV, pero podríamos definirlos nosotros mismos.
Existen otros target que podremos ver con el comando:
#systemctl list-units –type=target
Podemos cambiar de target (o modo de ejecución) actual con el comando:
# systemctl isolate graphical.target
Nota: Esto podría ser equivalente a la orden #telinit 5 de SysV
systemd también nos permite cambiar el target predeterminado e incluso añadir nuevos servicios a otros target, pero antes de esto, es importante dejar claro algunos de los directorios de los que hace uso systemd:
- Los archivos unit (archivos de configuración de service, mount, device…) se encuentran en: /usr/lib/systemd/system/ o /etc/systemd/system/
- Los target (runlevels) igualmente pueden situarse en ambos directorios
- Los directorios *.wants (ubicados igualmente en ambos directorios) contienen los enlaces simbólicos que apuntan a determinados servicios, serán estos servicios los que se ejecuten con el target al que corresponde dicho directorio wants, recordar que si un target precisa de otro, también serán cargados los servicios de este otro target.
Nota: Los archivos unit de /etc/systemd/system tienen una mayor precedencia sobre archivos unidad de /lib/systemd/system
El target /etc/systemd/system/default.target es el target predeterminado de arranque, es un enlace simbólico que por defecto apunta a /lib/systemd/system/graphical.target por lo que para cambiar de target de arranque, bastará con eliminar dicho link y crear uno nuevo apuntando al nuevo target.
Si quisiéramos podríamos crear un target desde 0 a nuestro gusto y darle un nombre (mylevel.target) y a continuación habilitarlo:
# systemctl enable mylevel.target
El efecto de esta orden crea un enlace simbólico (/etc/systemd/system/default.target) que apunta a nuestro mylevel.target. Esto solo funciona si hemos añadido la etiqueta [Install] al archivo, de la siguiente manera:
[Install]
Alias=default.target
También podemos añadir o quitar nuevos servicios a un target determinado, bastará con crear nuevos enlaces simbólicos dentro del directorio *.wants del target de arranque (o de algunos de los que dependa) apuntando a los servicios deseados.
Otra forma de modificar el target de inicio es a través de los parámetros que le pasamos al kernel en el archivo de configuración del gestor de arranque añadiendo por ejemplo systemd.unit=multi-user.target para arrancar en nivel3
Journal
journal es un componente mas de systemd, que capta los mensajes syslog, los mensajes de registro del kernel, los del disco RAM inicial y los mensajes de arranque iniciales, así como mensajes escritos en stdout y stderr de todos los servicios, haciendo que estén disponible para el usuario. Se puede utilizar en paralelo, o en lugar de un demonio syslog tradicional, como rsyslog o syslog-ng.
Hasta Fedora 18 (e inclusive a día de hoy, Enero del 2015, en Centos7) el registro de journal se almacena de forma volátil en /run/log/journal por lo que será eliminado tras un reinicio. La intención es que venga configurado por defecto de manera que sea un registro persistente y con directorio principal /var/log/journal (que no venga por defecto no quiere decir que no lo podamos configurar de tal modo).
Una de las razones por las que syslog comenzaba a quedarse “anticuado” es la necesidad por ejemplo de mostrar las últimas líneas del registro de un determinado servicio en el momento de preguntar por su estado (con systemctl), esto necesita que archivos de registro sean descomprimido en tiempo real y a la vez mostrado, algo que con syslog se hacía casi imposible y además, ineficiente y poco seguro.
Nota: Estudiaremos mas sobre los log de registros (syslog, rsyslog, syslog-ng, y journal) en el tema dedicado a tal fin de este mismo libro.
Hasta ahora nos haremos la idea de que journal es el sustituto de syslog, el cual nos permite filtrar la salida del registro por campos, dejar el registro de forma volátil o volverlo persistente mediante su archivo de configuración (/etc/systemd/journald.conf), darle un tamaño máximo al fichero de registro, permite la compatibilidad con el antiguo syslog mediante el socket /run/systemd/journal/syslog (tendremos que asociar syslog a este socket y no a /dev/log, el paquete syslog-ng proporciona automáticamente la configuración necesaria), reenviar la salida del registro a una terminal, etc…
Solucionar problemas
Este apartado lo podemos encontrar igualmente en: https://wiki.archlinux.org/index.php/Systemd_%28Espa%C3%B1ol%29 (Solución de problemas), he creído conveniente introducirlo en el tema para que sirva como ejemplo práctico.
Nota: Intenté cambiarlo por un error personal, pero el comando systemctl –state=failed en mi Centos7 solo me proporcionaba el error:
rngd.service loaded failed failed Hardware RNG Entropy Gatherer Daemon
RGN es un Generador de números aleatorios a partir de un componente hardware, en vez de crearlos mediante software. Al no usar este tipo de software pues evidentamente me da error. (Mira si a alguno de ustedes le ocurre lo mismo, ya llevan 2 problemas solucionados, este y el que se explica a continuación, jeje)
Podría haber creado mi propio problema, pero creo que el ejemplo de la wiki de arch puede ahorrarme un maravilloso tiempo.
- Lo primero es comprobar si existen servicios que están fallando en el incio:
$systemctl –state=failed
systemd-modules-load.service loaded failed failed Load Kernel Modules - Vamos a indagar sobre este error. Miraremos su estado.
$systemctl status systemd-modules-load
systemd-modules-load.service – Load Kernel Modules
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
Active: failed (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
Docs: man:systemd-modules-load.service(8).
man:modules-load.d(5)
Process: 15630 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE) - Tenemos el PID, investiguemos sobre este:
$journalctl -b _PID=15630– Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. –
Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module ‘blacklist usblp’
Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module ‘install usblp /bin/false’ - Este mensaje -> Failed to find module ‘blacklist usblp’ <- la palabra module y blacklist juntas mmmm, vamos a revisar si por casualidad tuviesemos una blacklist configurada…
$ ls -Al /etc/modules-load.d/
…
-rw-r–r– 1 root root 79 1. Ene 2015 blacklist.conf
-rw-r–r– 1 root root 1 2. Mar 2014 encrypt.conf
-rw-r–r– 1 root root 3 5. Dic 2014 printing.conf
… - Al abrir el archivo blacklist, encontramos precisamente las líneas ‘blacklist usblp’ y ‘install usblp /bin/false’, por lo que vamos a comentarlas (añadiendo # delante de cada una de ellas) para que no las tenga en cuenta y reiniciaremos el servicio a ver que tal.
- Si no hay señales de error en el prompt vamos a comprobar cual es su estado:
$ systemctl status systemd-modules-load
systemd-modules-load.service – Load Kernel Modules
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
Active: active (exited) since So 2013-08-25 12:22:31 CEST; 34s ago
Docs: man:systemd-modules-load.service(8)
man:modules-load.d(5)
Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
Aug 25 12:22:31 mypc systemd[1]: Started Load Kernel Modules.
Otra forma de detectar arranques en el inicio es mediante su depuración, para lo que tendremos que añadir los parámetros systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M a la línea del kernel en el gestor de arranque
NOTAS:
Podremos descargar systemd desde la siguiente página oficial: http://www.freedesktop.org/software/systemd/ o bien consultar su documentación oficial http://freedesktop.org/wiki/Software/systemd/
Puedes ampliar la información aquí dada, e incluso conocer otras funcionalidades o aspectos de systemd como:
- Características de systemd (ampliadas)
- Línea de comandos de arranque del Kernel
- Cambiar el número de gettys por defecto
- Personalizar un archivo unidad o agregar uno personalizado
- Inicio de sesión automático en una terminal
- Implementación readahead (lectura anticipada)
- Escribir archivos .service personalizados
- Archivos temporales y temporizadores
a través de algunos sitios:
https://fedoraproject.org/wiki/Systemd/es
https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet/es
https://wiki.archlinux.org/index.php/Systemd_%28Espa%C3%B1ol%29
https://wiki.ubuntu.com/SystemdForUpstartUsers
https://wiki.archlinux.org/index.php/Systemd
Comandos Capítulo 5
- Comandos para interactuar con los cargadores de arranque: GRUB y EFI
- Comandos para la administración de servicios y runlevels SysV
- Comando initctl: Administrando init en Upstart
- Comandos para la gestión de system
Curso LPIC-1 400 Capítulo 5 por nebul4ck se distribuye bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 4.0 Internacional.
-
LPIC
- Comandos deb y rpm para la administración de paquetes y dependencias.
- Capítulo 2 - Curso LPIC-1 400 - Administración de paquetes, deb y rpm: RPM y Debian
- Capítulo 2 - Curso GRATIS LPIC-1 400 - Herramientas de administración del software: RPM y Debian
- Capítulo 7 - Curso GRATIS LPIC-1 400 - Administrar el sistema 2/2
- Capítulo 7 - Curso GRATIS LPIC-1 400 - Administrar el sistema 1/2
- Capítulo 10 - Curso GRATIS LPIC-1 400 - Proteger el sistema 2/2
- Capítulo 10 - Curso GRATIS LPIC-1 400 - Proteger el sistema 1/2
- Capítulo 9 - Curso GRATIS LPIC-1 400 - El entorno de Consola, Shell Scripts, el Correo Electrónico y uso básico de SQL 2/2
- Capítulo 9 - Curso GRATIS LPIC-1 400 - El entorno de Consola, Shell Scripts, el Correo Electrónico y uso básico de SQL 1/2
- Capítulo 8 - Curso GRATIS LPIC-1 400 - Configuración básica de redes TCP/IP 1/2
- Capítulo 8 - Curso GRATIS LPIC-1 400 - Configuración básica de redes TCP/IP 2/2
- Capítulo 6 - Curso GRATIS LPIC-1 400 - COnfigurar el sistema de ventanas de X, localización y sistema de impresión
- Capítulo 5 - Curso GRATIS LPIC-1 400 - Inicializar sistemas Linux: SysV, Upstart y systemd
- Capítulo 4 - Curso GRATIS LPIC-1 400 - Filesystem y la Administración de archivos
- Capítulo 3 - Curso GRATIS LPIC-1 400 - Instalar, configurar y administrar el hardware del equipo