Inicio y cierre del sistema

De doc.ubuntu-es
(Diferencias entre revisiones)
Saltar a: navegación, buscar
m
 
(No se muestran 21 ediciones intermedias realizadas por 6 usuarios)
Línea 1: Línea 1:
==Inicio del sistema==
+
{{wikificar}}
El arranque de un sistema Linux consta de las siguientes fases:
+
* Ejecución del [[gestor de arranque]] (p.ej. lilo o grub)
+
* Carga y ejecución del [[kernel]]
+
* Ejecución de init (proceso número 1)* Ejecución de scripts de iniciación genéricos en /etc/rcS.d
+
* Entrada en el runlevel por defecto: ejecución de scripts del runlevel en /etc/rcX.d, donde X el el número del runlevel.
+
A grandes rasgos el proceso ocurre así: al conectar o reiniciar el ordenador, la BIOS busca en su configuración el dispositivo de arranque por defecto, el cual suele ser un disco duro, indicado generalmente en la configuración de la BIOS por C. Entonces carga en memoria el primer sector del dispositivo de arranque y le transfiere el control. Cuando se trata de un disco duro, este primer sector es el Master Boot Record (MBR) y contiene, además del código cargado por la BIOS, la tabla de particiones del disco. El código en el MBR, generalmente, lee en la tabla de particiones cuál es la partición activa y carga en memoria el primer sector de la misma, transfiriéndole el control.
+
En nuestro caso, este sector estará ocupado por un gestor de arranque que nos permitirá arrancar Linux u otro sistema operativo. Opcionalmente, puede instalarse el gestor en el MBR, tomando antes el control. Una vez cargado el gestor de arranque, éste se ejecuta, busca el kernel de Linux en una posición conocida del disco, carga el kernel en memoria y le cede el control. El kernel se almacena comprimido en disco, por lo que lo primero que hace el código del kernel que se ejecuta inicialmente es descomprimir el propio kernel y situarlo en memoria. Entonces se ejecuta realmente el kernel y empieza una lista de comprobaciones y activación de módulos internos  del
+
mismo
+
  
Una vez funcionando, el kernel monta el disco principal donde se almacena el sistema operativo (root filesystem y ejecuta el primer proceso: init. La misión de init es ejecutar el resto de procesos del sistema: comprobación de discos, detección/configuración de hardware adicional, apertura de terminales, servidores, etc.
+
== Inicio del sistema ==
  
Una vez que el kernel se ha cargado en memoria, ejecuta el programa init, que se convierte en el proceso número 1 y se encarga de ejecutar el resto de programas que hacen que el sistema funcione. La operación de init se configura en el fichero /etc/inittab. Empezando en este fichero se puede seguir
+
El arranque de un sistema GNU/Linux consta de las siguientes fases:
paso a paso el proceso de arranque (y parada) del sistema. Lo importante a saber aquí es que init no hace
+
* Ejecución del [[gestor de arranque]] (ej.: [[LILO]] o [[GRUB]]).
demasiado por si mismo, sino que se limita a ejecutar una serie de scripts que activan ordenadamente
+
* Carga y ejecución del [[kernel]].
los diferentes servicios que hacen funcionar el sistema.
+
* Ejecución de init (proceso número 1)* Ejecución de scripts de iniciación genéricos en <code>/etc/rcS.d</code>.
 +
* Entrada en el runlevel por defecto: ejecución de scripts del runlevel en <code>/etc/rcX.d</code>, donde X el el número del runlevel.
  
En primer lugar se ejecutan por orden alfabético todos los scripts que se encuentren bajo el directorio
+
A grandes rasgos el proceso ocurre así: al conectar o reiniciar el ordenador, la [[w:BIOS|w:BIOS]] busca en su configuración el dispositivo de arranque por defecto, el cual suele ser un disco duro, indicado generalmente en la configuración de la BIOS por C. Entonces carga en memoria el primer sector del dispositivo de arranque y le transfiere el control. Cuando se trata de un disco duro, este primer sector es el [[w:Master Boot Record|w:Master Boot Record]] (''MBR'') y contiene, además del código cargado por la BIOS, la tabla de particiones del disco. El código en el MBR, generalmente, lee en la tabla de particiones cuál es la partición activa y carga en memoria el primer sector de la misma, transfiriéndole el control.
/etc/rcS.d que comiencen por ’S’ con “start” como argumento. Por convenio estos scripts se nom-
+
bran comenzando por un número de dos cifras para establecer el orden adecuado. Cada script tiene una
+
función particular, por ejemplo:
+
                                                      • S10checkroot.sh comprueba el sistema de ficheros.
+
                                                      • S20adjtimex ajusta el reloj del sistema.
+
                                                      • S40networking activa los interfaces de red.
+
En realidad, y por convenio, estos scripts no se sitúan directamente en /etc/rcS.d, sino que se
+
guardan en el directorio /etc/init.d y desde ahí se hacen enlaces simbólicos a /etc/rcS.d. De
+
esta forma es más fácil añadir, eliminar y ordenar los componentes. Las tareas realizadas por los scripts en /etc/rcS.d son las básicas para arrancar el sistema. Luego
+
se ejecutan otra serie de scripts correspondientes a un runlevel.  
+
  
Los runlevels son un mecanismo para
+
En nuestro caso, este sector estará ocupado por un gestor de arranque que nos permitirá arrancar [[w:GNU|GNU]]/Linux u otro [[w:sistema operativo|sistema operativo]]. Opcionalmente, puede instalarse el gestor en el MBR, tomando antes el control. Una vez cargado el gestor de arranque, éste se ejecuta, busca el [[:w:kernel|kernel]] de Linux en una posición conocida del disco, carga el kernel en memoria y le cede el control. El kernel se almacena comprimido en disco, por lo que lo primero que hace el código del kernel que se ejecuta inicialmente es descomprimir el propio kernel y situarlo en memoria. Entonces se ejecuta realmente el kernel y empieza una lista de comprobaciones y activación de módulos internos  del mismo
permitir que el ordenador trabaje con diferentes configuraciones de arranque (diferentes servicios, etc.).
+
  
Los runlevels se numeran del 0 al 6. El 0 se ejecuta para parar el sistema (halt), el 6 para reiniciar
+
Una vez funcionando, el kernel monta el disco principal donde se almacena el sistema operativo (root filesystem y ejecuta el primer proceso: init. La misión de [[:w:init|init]] es ejecutar el resto de procesos del sistema: comprobación de discos, detección/configuración de hardware adicional, apertura de terminales, servidores, etc.
(reboot) y el 1 para arrancar en modo single user, que viene a ser una cofiguración mínima para realizar
+
tareas de administración.  
+
  
El resto de los runlevels son para funcionamiento normal. El runlevel por
+
Una vez que el kernel se ha cargado en memoria, ejecuta el programa init, que se convierte en el proceso número 1 y se encarga de ejecutar el resto de programas que hacen que el sistema funcione. La operación de init se configura en el fichero <code>/etc/inittab</code>. Empezando en este fichero se puede seguir
defecto es el 2 (se configura en /etc/inittab), empleando los otros sólo en situaciones especiales.
+
paso a paso el proceso de arranque (y parada) del sistema. Lo importante a saber aquí es que init no hace demasiado por si mismo, sino que se limita a ejecutar una serie de [[:w:guión (informática)|guiones o scripts]] que activan ordenadamente los diferentes servicios que hacen funcionar el sistema.
En Debian, los runlevels del 2 al 5 se configuran inicialmente de forma idéntica.
+
  
Así, el proceso de arranque suele continuar ejecutando los scripts del runlevel correspondiente situados
+
En primer lugar se ejecutan por orden alfabético todos los scripts que se encuentren bajo el directorio <code>/etc/rcS.d</code> que comiencen por ’S’ con “start” como argumento. Por convenio estos scripts se nombran comenzando por un número de dos cifras para establecer el orden adecuado. Cada script tiene una función particular, por ejemplo:
en /etc/rcX.d, donde X es el número del runlevel. La forma de ejecutar estos scripts es análoga al caso anterior, salvo que ahora se ejecutan primero los scripts que comiencen con ’K’ con argumento “stop” y luego los que comienzan con ’S’ con argumento “start”.  
+
* S10checkroot.sh comprueba el sistema de ficheros.
 +
* S20adjtimex ajusta el reloj del sistema.
 +
* S40networking activa los interfaces de red.
 +
En realidad, y por convenio, estos scripts no se sitúan directamente en <code>/etc/rcS.d</code>, sino que se guardan en el directorio <code>/etc/init.d</code> y desde ahí se hacen enlaces simbólicos a <code>/etc/rcS.d</code>. De esta forma es más fácil añadir, eliminar y ordenar los componentes. Las tareas realizadas por los scripts en <code>/etc/rcS.d</code> son las básicas para arrancar el sistema. Luego se ejecutan otra serie de scripts correspondientes a un [[:w:runlevel|runlevel o nivel de ejecución]].
  
La idea es que cada script gestione una
+
Los runlevels (niveles de ejecución) son un mecanismo para permitir que el ordenador trabaje con diferentes configuraciones de arranque (diferentes servicios, etc.).
tarea o servicio. Este servicion se inicia cuando el script se ejecuta con el argumento “start” y se detiene cuando se usa el argumento “stop”. De esta forma en cada runlevel puden detenerse los servicios que no se necesiten y activarse aquellos que interese. Este sistema también facilita el arranque y parada de servicios, ejecutando estos scripts manualmente con el argumento apropiado. En cualquier momento, el administrador puede hacer que el sistema cambie a otro runlevel ejecutando el comando telinit con un argumento numérico indicando el nuevo runlevel. Por ejemplo:
+
 
                                                                  # telinit 3
+
Los runlevels se numeran del 0 al 6. El 0 se ejecuta para parar el sistema (halt), el 6 para reiniciar (reboot) y el 1 para arrancar en modo single user, que viene a ser una cofiguración mínima para realizar tareas de administración.
En general, no hay que preocuparse por la configuración del arranque ya que el sistema de instalación se ocupa automáticamente de actualizar la configuración en función de los paquetes instalados.
+
 
 +
El resto de los runlevels son para funcionamiento normal. El runlevel por defecto es el 2 (se configura en <code>/etc/[[:w:inittab|inittab]]</code>), empleando los otros sólo en situaciones especiales. En Debian, los runlevels del 2 al 5 se configuran inicialmente de forma idéntica.
 +
 
 +
Así, el proceso de arranque suele continuar ejecutando los scripts del ''runlevel'' correspondiente situados en <code>/etc/rcX.d</code>, donde X es el número del ''runlevel''. La forma de ejecutar estos scripts es análoga al caso anterior, salvo que ahora se ejecutan primero los scripts que comiencen con ''’K’'' con argumento ''“stop”'' y luego los que comienzan con ''’S’'' con argumento ''“start”''.
 +
 
 +
La idea es que cada ''script'' gestione una tarea o servicio. Este servicio se inicia cuando el script se ejecuta con el argumento “start” y se detiene cuando se usa el argumento “stop”. De esta forma en cada runlevel puden detenerse los servicios que no se necesiten y activarse aquellos que interese. Este sistema también facilita el arranque y parada de servicios, ejecutando estos scripts manualmente con el argumento apropiado. En cualquier momento, el administrador puede hacer que el sistema cambie a otro runlevel ejecutando el comando <code>telinit</code> con un argumento numérico indicando el nuevo runlevel. Por ejemplo:
 +
# telinit 3
 +
En general, no hay que preocuparse por la configuración del [[:w:arranque|arranque]], ya que el sistema de instalación se ocupa automáticamente de actualizar la configuración en función de los paquetes instalados.
  
 
== Cierre del sistema ==  
 
== Cierre del sistema ==  
Para detener correctamente un sistema Unix hemos de situar el proceso INIT en un determinado runlevel, generalmente 0 o 6 (podemos comprobarlo simplemente echando un vistazo a /etc/inittab). Para ello, el sistema ofrece al superusuario varios mandatos que pueden ser invocados desde el shell, y que se suelen encontrar en el directorio /sbin/, como shutdown, halt o reboot. Tanto halt como reboot detienen el sistema; la diferencia entre ellos es que la segunda orden lo reinicializa.
 
  
En principio sólo vamos a poder invocar estas órdenes cuando nos encontremos en los runlevels 0 o 6; si nos encontramos en otro nivel de operación habremos de utilizar shutdown para poder asegurar la estabilidad del sistema. Sin embargo, en la mayorá de Unices no existen problemas por esta causa, ya que INIT detecta el estado actual del sistema, y si no es alguno de los anteriores, invoca de forma automática a shutdown con los parámetros adecuados  
+
Para detener correctamente un sistema [[:w:Unix|Unix]] hemos de situar el proceso <code>[[:w:init|INIT]]</code> en un determinado [[:w:runlevel|runlevel, generalmente 0 o 6 (podemos comprobarlo simplemente echando un vistazo a <code>/etc/inittab</code>). Para ello, el sistema ofrece al superusuario varios mandatos que pueden ser invocados desde el shell, y que se suelen encontrar en el directorio <code>/sbin/</code>, como <code>shutdown</code>, <code>halt</code> o <code>reboot</code>. Tanto <code>halt</code> como <code>reboot</code> detienen el sistema; la diferencia entre ellos es que la segunda orden lo reinicializa.
 +
 
 +
En principio sólo vamos a poder invocar estas órdenes cuando nos encontremos en los runlevels 0 o 6; si nos encontramos en otro nivel de operación habremos de utilizar shutdown para poder asegurar la estabilidad del sistema. Sin embargo, en la mayoría de Unices no existen problemas por esta causa, ya que [[:w:init|INIT]] detecta el estado actual del sistema, y si no es alguno de los anteriores, invoca de forma automática a shutdown con los parámetros adecuados  
 +
 
 +
''Shutdown'' (reinicio) va a detener la máquina de una forma ordenada, siguiendo unos pasos definidos. En primer lugar, notifica el hecho a todos los usuarios conectados (mediante wall) y bloquea el proceso de registro (login). Posteriormente invoca a ''INIT''' en un runlevel 0 (para simplemente detener el sistema), 6 (para reinicializarlo) o incluso 1 (monousuario, para realizar tareas administrativas). Entonces NIT ejecuta el script correspondiente (leído de <code>/etc/inittab</code>), que suele encargarse de eliminar todos los procesos de la máquina, notificar el evento en el fichero de log correspondiente, desmontar los sistemas de ficheros que existan, desactivar el área de swap (intercambio) y, según se haya invocado la orden, detener el sistema o reinicializarlo. La forma habitual (que se da en el 90% de los casos, y por supuesto es la que estudiaremos nosotros) de invocar a shutdown es:
 +
<code>shutdown -r/-h now</code>                                             
 +
Con el parámetro -r hacemos un reboot, y con -h un halt (simplemente detenemos el sistema, sin reinicializar).
 +
El parametro "now" puede ser substituido por una hora o puede indicarse el tiempo que deberá esperar el sistema para proceder al reinicio/parado del sistema. Algún ejemplo sobre el reinicio del sistema sería:
 +
<code>shutdown -h/-r 20:00</code>
 +
<code>shutdown -h/-r +10</code>
 +
 
 +
== Intérprete de órdenes ==
 +
 
 +
El proceso [[:w:login|login]] (de registro/ingreso) nos asigna un intérprete de mandatos, leído de nuestra entrada en <code>/etc/passwd</code>. Ya sabemos que un [[shell]] no es más que un programa del sistema que nos va a permitir relacionarnos con la máquina, introduciéndole órdenes desde el teclado; es la interfaz de usuario que nos ofrece cualquier sistema operativo.
  
Shutdown va a detener la máquina de una forma ordenada, siguiendo unos pasos definidos. En primer lugar, notifica el hecho a todos los usuarios conectados (mediante wall) y bloquea el proceso de login. Posteriormente invoca a INIT en un runlevel 0 (para simplemente detener el sistema), 6 (para reinicializarlo) o incluso 1 (monousuario, para realizar tareas administrativas). Entonces NIT ejecuta el script correspondiente (leído de /etc/inittab), que suele encargarse de eliminar todos los procesos de la máquina, notificar el evento en el fichero de log correspondiente, desmontar los sistemas de ficheros que existan, desactivar el área de swap y, según se haya invocado la orden, detener el sistema o reinicializarlo. La forma habitual (que se da en el 90% de los casos, y por supuesto es la que estudiaremos nosotros) de invocar a shutdown es:
+
En nuestro sistema [[:w:Unix|Unix]] podemos tener instalados diversos intérpretes de órdenes; en el archivo <code>/etc/shells</code> tenemos los disponibles para cada usuario, incluido el root. Por defecto se asigna el Bourne Again Shell (bash), el más cómodo, que incluye lo mejor de todos los anteriores intérpretes, como el C-Shell (csh) o el Korn Shell (ksh). El bash incluye rodillo de mandatos, histórico de órdenes (en el archivo <code>.bash_history</code> del directorio <code>$HOME</code> de cada usuario), uso de tabuladores para completar órdenes, etc. Cualquier intérprete de ''Unix ''nos ofrece un entorno de programación completo con herramientas similares a las de la mayoría de lenguajes de programación secuencial (if, for, while, ...). También nos va a ofrecer una serie de órdenes, denominadas órdenes internas, que no encontramos como archivos ejecutables en el sistema, y que por supuesto no va a ser necesario cargar en memoria para oder ejecutarlas; un ejemplo típico de este tipo de instrucciones es <code>exit</code>: no encontraremos ningún ejecutable en todos los sistemas de ficheros de Unix que se denomine así.
                                                            shutdown -r/-h now                                               
+
Con el parámetro -r hacemos un reboot, y con -h un halt (simplemente detenemos el sistema, sin reinicializar).
+
+
== El intérprete de órdenes ==
+
El proceso [[login]] nos asigna un intérprete de mandatos, leído de nuestra entrada en /etc/passwd. Ya sabemos que un [[shell]] no es más que un programa del sistema que nos va a permitir relacionarnos con la máquina, introduciéndole órdenes desde el teclado; es la interfaz de usuario que nos ofrece cualquier sistema operativo.  
+
  
En nuestro sistema Unix podemos tener instalados diversos intérpretes de órdenes; en el archivo /etc/shells tenemos los disponibles para cada usuario, incluido el root. Por defecto se asigna el Bourne Again Shell (bash), el más cómodo, que incluye lo mejor de todos los anteriores intérpretes, como el C-Shell (csh) o el Korn Shell (ksh). El bash incluye rodillo de mandatos, histórico de órdenes (en el archivo .bash history del directorio $HOME de cada usuario), uso de tabuladores para completar órdenes, etc. Cualquier intérprete de Unix nos ofrece un entorno de programación completo con herramientas similares a las de la mayoría de lenguajes de programación secuencial (if, for, while. . . ). También nos va a ofrecer una serie de órdenes, denominadas órdenes internas, que no encontramos como archivos ejecutables en el sistema, y que por supuesto no va a ser necesario cargar en memoria para oder ejecutarlas; un ejemplo típico de este tipo de instrucciones es exit: no encontraremos ningún ejecutable en todos los sistemas de ficheros de Unix que se denomine así.  
+
En [[:w:Unix|Unix]] existe el mandato <code>chsh</code>, que permite a cualquier usuario modificar el shell que el sistema le asigna por defecto (recordemos que este dato está grabado en <code>/etc/passwd</code>). En determinados clones, chsh no va a comprobar que el shell sea válido (esto es, que sea una entrada de /etc/shells). Esto puede suponer un problema: imaginemos que un usuario inexperto cambia su shell de entrada a <code>/bin/login</code>; será imposible para él volver a entrar al sistema mediante conexión remota hasta que el administrador modifique la información de <code>/etc/passwd</code>. Por tanto, desde hace algún tiempo la mayoría de Unix del mercado (y por supuesto también GNU/Linux) hacen la comprobación oportuna.  
  
En Unix existe el mandato chsh, que permite a cualquier usuario modificar el shell que el sistema le asigna por defecto (recordemos que este dato está grabado en /etc/passwd). En determinados clones, chsh no va a comprobar que el shell sea válido (esto es, que sea una entrada de /etc/shells). Esto puede suponer un problema: imaginemos que un usuario inexperto cambia su shell de entrada a /bin/login; será imposible para él volver a entrar al sistema mediante conexión remota hasta que el administrador modifique la información de /etc/passwd. Por tanto, desde hace algún tiempo la mayoría de Unices del mercado (y por supuesto también Linux) hacen la comprobación oportuna.
+
Analizando el funcionamiento de <code>chsh</code>, vemos que una de las cosas que realiza es modificar el fichero de contraseñas para cambiar el shell de entrada de un usuario; por tanto, el archivo está «setuidado». Puede ser interesante para nosotros resetear el bit setuid del archivo (<code>chmod -s</code>) para así conseguir un mayor nivel de seguridad del sistema, ya que, como veremos más adelante, es conveniente mantener al míınimo el número de archivos "setuidados" en la máquina. Si lo hacemos así y algún usuario quiere cambiar su intérprete de órdenes cada vez que entre al sistema puede incluir en su <code>.profile</code> una orden como:
 +
<code>exec <nuevoshell></code>
 +
De esta forma, sustituye el proceso que ejecuta <code>.profile</code> (el shell) por la orden <nuevoshell>, el nuevo intérprete que desea.
  
 +
== Fuente ==
  
Analizando el funcionamiento de chsh, vemos que una de las cosas que realiza es modificar el fichero de contraseñas para cambiar el shell de entrada de un usuario; por tanto, el archivo está "setuidado". Puede ser interesante para nosotros resetear el bit setuid del archivo (chmod -s) para así conseguir un mayor nivel de seguridad del sistema, ya que, como veremos más adelante, es conveniente mantener al míınimo el número de archivos "setuidados" en la máquina. Si lo hacemos así y algún usuario quiere cambiar su intérprete de órdenes cada vez que entre al sistema puede incluir en su .profile una orden como:
+
:"Guía de administración de Debian GNU/Linux" - Jorge Juan Chico <jjchico@imse.cnm.es>, Manuel J. Bellido Díaz <bellido@imse.cnm.es> [[Discusión:Inicio y cierre del sistema|sobre licencia]].
                                                              exec <nuevoshell>
+
De esta forma, sustituye el proceso que ejecuta .profile (el shell) por la orden <nuevoshell>, el nuevo intérprete que desea.
+
  
----
+
== Véase también ==
  
:'''Fuente''':
+
* [[GRUB]] - Gestor de arranque en Ubuntu.
:Guía de administración de Debian
+
* [[Pet Sis| Sys Req/Pet Sis]] - Cómo cerrar correctamente en caso de cuelgue del sistema.
:GNU/Linux
+
:Jorge Juan Chico <jjchico@imse.cnm.es>
+
:Manuel J. Bellido Díaz <bellido@imse.cnm.es>
+
  
<!-- Categorías --> [[Categoría:Administración del sistema]] [[Categoría: inicio y cierre del sistema]]
+
[[Categoría:Administración del sistema]]

Última revisión de 11:18 17 jul 2012


Eye.png Este artículo necesita ser wikificado en base al manual de estilo de este wiki. Por favor, colabora editándolo conforme a las normas de edición de este sitio. No elimines este aviso hasta que lo hayas hecho.



Contenido

[editar] Inicio del sistema

El arranque de un sistema GNU/Linux consta de las siguientes fases:

  • Ejecución del gestor de arranque (ej.: LILO o GRUB).
  • Carga y ejecución del kernel.
  • Ejecución de init (proceso número 1)* Ejecución de scripts de iniciación genéricos en /etc/rcS.d.
  • Entrada en el runlevel por defecto: ejecución de scripts del runlevel en /etc/rcX.d, donde X el el número del runlevel.

A grandes rasgos el proceso ocurre así: al conectar o reiniciar el ordenador, la w:BIOS busca en su configuración el dispositivo de arranque por defecto, el cual suele ser un disco duro, indicado generalmente en la configuración de la BIOS por C. Entonces carga en memoria el primer sector del dispositivo de arranque y le transfiere el control. Cuando se trata de un disco duro, este primer sector es el w:Master Boot Record (MBR) y contiene, además del código cargado por la BIOS, la tabla de particiones del disco. El código en el MBR, generalmente, lee en la tabla de particiones cuál es la partición activa y carga en memoria el primer sector de la misma, transfiriéndole el control.

En nuestro caso, este sector estará ocupado por un gestor de arranque que nos permitirá arrancar GNU/Linux u otro sistema operativo. Opcionalmente, puede instalarse el gestor en el MBR, tomando antes el control. Una vez cargado el gestor de arranque, éste se ejecuta, busca el kernel de Linux en una posición conocida del disco, carga el kernel en memoria y le cede el control. El kernel se almacena comprimido en disco, por lo que lo primero que hace el código del kernel que se ejecuta inicialmente es descomprimir el propio kernel y situarlo en memoria. Entonces se ejecuta realmente el kernel y empieza una lista de comprobaciones y activación de módulos internos del mismo

Una vez funcionando, el kernel monta el disco principal donde se almacena el sistema operativo (root filesystem y ejecuta el primer proceso: init. La misión de init es ejecutar el resto de procesos del sistema: comprobación de discos, detección/configuración de hardware adicional, apertura de terminales, servidores, etc.

Una vez que el kernel se ha cargado en memoria, ejecuta el programa init, que se convierte en el proceso número 1 y se encarga de ejecutar el resto de programas que hacen que el sistema funcione. La operación de init se configura en el fichero /etc/inittab. Empezando en este fichero se puede seguir paso a paso el proceso de arranque (y parada) del sistema. Lo importante a saber aquí es que init no hace demasiado por si mismo, sino que se limita a ejecutar una serie de guiones o scripts que activan ordenadamente los diferentes servicios que hacen funcionar el sistema.

En primer lugar se ejecutan por orden alfabético todos los scripts que se encuentren bajo el directorio /etc/rcS.d que comiencen por ’S’ con “start” como argumento. Por convenio estos scripts se nombran comenzando por un número de dos cifras para establecer el orden adecuado. Cada script tiene una función particular, por ejemplo:

  • S10checkroot.sh comprueba el sistema de ficheros.
  • S20adjtimex ajusta el reloj del sistema.
  • S40networking activa los interfaces de red.

En realidad, y por convenio, estos scripts no se sitúan directamente en /etc/rcS.d, sino que se guardan en el directorio /etc/init.d y desde ahí se hacen enlaces simbólicos a /etc/rcS.d. De esta forma es más fácil añadir, eliminar y ordenar los componentes. Las tareas realizadas por los scripts en /etc/rcS.d son las básicas para arrancar el sistema. Luego se ejecutan otra serie de scripts correspondientes a un runlevel o nivel de ejecución.

Los runlevels (niveles de ejecución) son un mecanismo para permitir que el ordenador trabaje con diferentes configuraciones de arranque (diferentes servicios, etc.).

Los runlevels se numeran del 0 al 6. El 0 se ejecuta para parar el sistema (halt), el 6 para reiniciar (reboot) y el 1 para arrancar en modo single user, que viene a ser una cofiguración mínima para realizar tareas de administración.

El resto de los runlevels son para funcionamiento normal. El runlevel por defecto es el 2 (se configura en /etc/inittab), empleando los otros sólo en situaciones especiales. En Debian, los runlevels del 2 al 5 se configuran inicialmente de forma idéntica.

Así, el proceso de arranque suele continuar ejecutando los scripts del runlevel correspondiente situados en /etc/rcX.d, donde X es el número del runlevel. La forma de ejecutar estos scripts es análoga al caso anterior, salvo que ahora se ejecutan primero los scripts que comiencen con ’K’ con argumento “stop” y luego los que comienzan con ’S’ con argumento “start”.

La idea es que cada script gestione una tarea o servicio. Este servicio se inicia cuando el script se ejecuta con el argumento “start” y se detiene cuando se usa el argumento “stop”. De esta forma en cada runlevel puden detenerse los servicios que no se necesiten y activarse aquellos que interese. Este sistema también facilita el arranque y parada de servicios, ejecutando estos scripts manualmente con el argumento apropiado. En cualquier momento, el administrador puede hacer que el sistema cambie a otro runlevel ejecutando el comando telinit con un argumento numérico indicando el nuevo runlevel. Por ejemplo:

# telinit 3

En general, no hay que preocuparse por la configuración del arranque, ya que el sistema de instalación se ocupa automáticamente de actualizar la configuración en función de los paquetes instalados.

[editar] Cierre del sistema

Para detener correctamente un sistema Unix hemos de situar el proceso INIT en un determinado [[w:runlevel|runlevel, generalmente 0 o 6 (podemos comprobarlo simplemente echando un vistazo a /etc/inittab). Para ello, el sistema ofrece al superusuario varios mandatos que pueden ser invocados desde el shell, y que se suelen encontrar en el directorio /sbin/, como shutdown, halt o reboot. Tanto halt como reboot detienen el sistema; la diferencia entre ellos es que la segunda orden lo reinicializa.

En principio sólo vamos a poder invocar estas órdenes cuando nos encontremos en los runlevels 0 o 6; si nos encontramos en otro nivel de operación habremos de utilizar shutdown para poder asegurar la estabilidad del sistema. Sin embargo, en la mayoría de Unices no existen problemas por esta causa, ya que INIT detecta el estado actual del sistema, y si no es alguno de los anteriores, invoca de forma automática a shutdown con los parámetros adecuados

Shutdown (reinicio) va a detener la máquina de una forma ordenada, siguiendo unos pasos definidos. En primer lugar, notifica el hecho a todos los usuarios conectados (mediante wall) y bloquea el proceso de registro (login). Posteriormente invoca a INIT' en un runlevel 0 (para simplemente detener el sistema), 6 (para reinicializarlo) o incluso 1 (monousuario, para realizar tareas administrativas). Entonces NIT ejecuta el script correspondiente (leído de /etc/inittab), que suele encargarse de eliminar todos los procesos de la máquina, notificar el evento en el fichero de log correspondiente, desmontar los sistemas de ficheros que existan, desactivar el área de swap (intercambio) y, según se haya invocado la orden, detener el sistema o reinicializarlo. La forma habitual (que se da en el 90% de los casos, y por supuesto es la que estudiaremos nosotros) de invocar a shutdown es:

shutdown -r/-h now                                               

Con el parámetro -r hacemos un reboot, y con -h un halt (simplemente detenemos el sistema, sin reinicializar). El parametro "now" puede ser substituido por una hora o puede indicarse el tiempo que deberá esperar el sistema para proceder al reinicio/parado del sistema. Algún ejemplo sobre el reinicio del sistema sería:

shutdown -h/-r 20:00
shutdown -h/-r +10

[editar] Intérprete de órdenes

El proceso login (de registro/ingreso) nos asigna un intérprete de mandatos, leído de nuestra entrada en /etc/passwd. Ya sabemos que un shell no es más que un programa del sistema que nos va a permitir relacionarnos con la máquina, introduciéndole órdenes desde el teclado; es la interfaz de usuario que nos ofrece cualquier sistema operativo.

En nuestro sistema Unix podemos tener instalados diversos intérpretes de órdenes; en el archivo /etc/shells tenemos los disponibles para cada usuario, incluido el root. Por defecto se asigna el Bourne Again Shell (bash), el más cómodo, que incluye lo mejor de todos los anteriores intérpretes, como el C-Shell (csh) o el Korn Shell (ksh). El bash incluye rodillo de mandatos, histórico de órdenes (en el archivo .bash_history del directorio $HOME de cada usuario), uso de tabuladores para completar órdenes, etc. Cualquier intérprete de Unix nos ofrece un entorno de programación completo con herramientas similares a las de la mayoría de lenguajes de programación secuencial (if, for, while, ...). También nos va a ofrecer una serie de órdenes, denominadas órdenes internas, que no encontramos como archivos ejecutables en el sistema, y que por supuesto no va a ser necesario cargar en memoria para oder ejecutarlas; un ejemplo típico de este tipo de instrucciones es exit: no encontraremos ningún ejecutable en todos los sistemas de ficheros de Unix que se denomine así.

En Unix existe el mandato chsh, que permite a cualquier usuario modificar el shell que el sistema le asigna por defecto (recordemos que este dato está grabado en /etc/passwd). En determinados clones, chsh no va a comprobar que el shell sea válido (esto es, que sea una entrada de /etc/shells). Esto puede suponer un problema: imaginemos que un usuario inexperto cambia su shell de entrada a /bin/login; será imposible para él volver a entrar al sistema mediante conexión remota hasta que el administrador modifique la información de /etc/passwd. Por tanto, desde hace algún tiempo la mayoría de Unix del mercado (y por supuesto también GNU/Linux) hacen la comprobación oportuna.

Analizando el funcionamiento de chsh, vemos que una de las cosas que realiza es modificar el fichero de contraseñas para cambiar el shell de entrada de un usuario; por tanto, el archivo está «setuidado». Puede ser interesante para nosotros resetear el bit setuid del archivo (chmod -s) para así conseguir un mayor nivel de seguridad del sistema, ya que, como veremos más adelante, es conveniente mantener al míınimo el número de archivos "setuidados" en la máquina. Si lo hacemos así y algún usuario quiere cambiar su intérprete de órdenes cada vez que entre al sistema puede incluir en su .profile una orden como:

exec <nuevoshell>

De esta forma, sustituye el proceso que ejecuta .profile (el shell) por la orden <nuevoshell>, el nuevo intérprete que desea.

[editar] Fuente

"Guía de administración de Debian GNU/Linux" - Jorge Juan Chico <jjchico@imse.cnm.es>, Manuel J. Bellido Díaz <bellido@imse.cnm.es> sobre licencia.

[editar] Véase también

  • GRUB - Gestor de arranque en Ubuntu.
  • Sys Req/Pet Sis - Cómo cerrar correctamente en caso de cuelgue del sistema.
Herramientas personales