martes, 13 de enero de 2015

Cluster MySQL con réplica circular


Resumen
El Centro Nacional de Sanidad Agropecuaria cuenta una red de datos, de más de 326 usuarios, los que contribuyen a la investigación en el tema de salud animal y sanidad vegetal, utilizando las tecnologías de la informática y las comunicaciones. El departamento de Informática, desarrolla software de alto valor agregado para el trabajo de la institución y durante este proceso, la elección del gestor de Base de Datos es un aspecto importante a tener en cuenta para el rendimiento de una aplicación informática. Desplegar soluciones informáticas en un entorno de producción, utilizando un único servidor de Base de Datos no es recomendable, porque se encuentra expuesto a fallas en el servicio debido a cortes eléctricos, problemas de hardware, mantenimiento, entre otros. La utilización de la tecnología de clúster en los servicios de redes a través de herramientas de software libre como son: Pacemaker, Corosync, OpenAIS y MySQL permite incrementar la disponibilidad del servicio. Este trabajo aborda la aplicación de esta tecnología en la institución, lo que ha permitido alcanzar una alta disponibilidad de los servicios de base de datos para las aplicaciones informáticas.

 
Introducción
El término clúster se aplica a los conjuntos o conglomerados de computadoras construidos mediante la utilización de hardware comunes y que se comportan como si fuesen una única computadora. Hoy en día desempeñan un papel importante en la solución de problemas de las ciencias, las ingenierías y del comercio moderno[1].
La tecnología clúster permite a las organizaciones incrementar su capacidad de procesamiento usando tecnología estándar, tanto en componentes de hardware como de software que pueden adquirirse a un costo relativamente bajo.
En un clúster de alta disponibilidad de aplicación si se produce un fallo del hardware o de las aplicaciones de alguna de las máquinas, el software de alta disponibilidad es capaz de arrancar automáticamente los servicios que han fallado en cualquiera de las otras. Cuando la máquina que ha fallado se recupera, los servicios son nuevamente migrados a la original. Esta capacidad de recuperación automática de servicios nos garantiza la integridad de la información, ya que no hay pérdida de datos, y evita molestias a los usuarios, que no tienen por qué notar que se ha producido un problema[2].

Desarrollo
Para la implementación y desarrollo de un clúster de base de datos MySQL, se utilizaron dos servidores profesionales Hewlett-Packard (HP), con microprocesador Intel Xeon y 16GB de memoria RAM y la distribución de Linux openSUSE versión 12,1. A continuación se explica brevemente las herramientas utilizadas para realizar el trabajo.
MySQL es un sistema de gestión de base de datos relacional, multihilo y multiusuario con más de seis millones de instalaciones. Este es muy utilizado en aplicaciones web como MediaWiki, Drupal o phpBB, en plataformas (Linux/Windows, Apache, MySQL, PHP/Perl/Python), y por herramientas de seguimiento de errores como Bugzilla. Su popularidad como aplicación web está muy ligada a PHP, que a menudo aparece en combinación con este gestor. MySQL es una base de datos muy rápida en la lectura cuando utiliza el motor no transaccional MyISAM, pero puede provocar problemas de integridad en entornos de alta concurrencia en la modificación. En aplicaciones web hay baja concurrencia en la modificación de datos y en cambio el entorno es intensivo en lectura de datos, lo que hace a MySQL ideal para este tipo de aplicaciones[3].
Pacemaker es un administrador de clúster. Este permite obtener el máximo rendimiento de los servicios, haciendo uso de los mensajes en la infraestructura del clúster, permite realizar cualquier tipo redundancia incluyendo Activo/Activo Activo/Pasivo, etc. Pacemaker esta compuesto por tres partes fundamentales, el núcleo del clúster que permite los mensajes y la pertenencia al clúster (OpenAIS), un conjunto de script para iniciar, detener y monitorear los recursos y un cerebro que procesa y reacciona a los eventos del clúster[4].



Para lograr un clúster completamente funcional con este tipo de características es necesario instalar los software Pacemaker y Corosync en las dos computadoras que se quieren clústerizar como se muestra a continuación: 

 
#zypper in corosync pacemaker
Obteniendo los datos del repositorio...
Leyendo los paquetes instalados...
mysql no se encontró como nombre de paquete, probando en prestaciones.
Resolviendo dependencias...
Los siguientes paquetes NUEVOS van a ser instalados:
clúster-glue corosync crmsh fence-agents libcorosync4 libdlm libdlm3 libesmtp libestr0 libfreebl3 libglue2 libgthread-2_0-0 libnet1 libpacemaker3 libqb0 libsensors4
libsnmp30 libsoftokn3 libXss1 mariadb mozilla-nss mozilla-nss-certs openhpi OpenIPMI pacemaker pacemaker-cli perl-TimeDate psmisc pssh python-dateutil python-pexpect
python-pssh python-pycurl python-tk resource-agents rsyslog snmp-mibs syslog-service tcl tk xhost
Los siguientes paquetes recomendados fueron seleccionados automáticamente:
  crmsh fence-agents libdlm
Se sugiere el siguiente paquete, pero no será instalado:
graphviz
41 nuevos paquetes a instalar.
Tamaño total a descargar: 18,2 MiB. Después de la operación, se utilizarán 105,6 MiB adicionales.
¿Desea continuar? [s/n/? mostrar todas las opciones] (s):s 
Si termina la instalación satisfactoriamente, el siguiente paso es verificar la conexión entre las dos maquinas, utilizando el comando ping. Para configurar OpenAIS es necesario establecer un puerto, una dirección multicas y la dirección de dominio del clúster. En este trabajo se utilizó 226.94.1.1 como dirección multicast y 4000 como puerto del servicio. Establecidos estos parámetros se puede iniciar el servicio de Corosync de la siguiente manera:

# rcopenais start
Starting OpenAIS/Corosync daemon (corosync): starting... OK 
Pacemaker tiene una herramienta que proporciona una interfaz de linea de comandos llamada crm, que permite la administración y configuración del clústeres de alta disponibilidad a partir de cero[5]. 
node hera \
attributes standby="off"
node zeus \
attributes standby="off"
primitive ClusterIP ocf:heartbeat:IPaddr2 \
params ip="172.16.0.200" cidr_netmask="32" \
op monitor interval="30s"
primitive MySQL ocf:heartbeat:mysql \
params binary="/usr/bin/mysqld_safe" user="mysql" pid="/var/run/mysql/mysqld.pid" socket="/var/run/mysql/mysql.sock" \
op start interval="0" timeout="120" \
op stop interval="0" timeout="120" \
op promote interval="0" timeout="120" \
op demote interval="0" timeout="120"
clone MysqlClone MySQL \
meta target-role="Started"
location cli-prefer-ClusterIP ClusterIP \
rule $id="cli-prefer-rule-ClusterIP" inf: #uname eq zeus
property $id="cib-bootstrap-options" \
dc-version="1.1.6-9971ebba4494012a93c03b40a2c58ec0eb60f50c" \
clúster-infrastructure="openais" \
expected-quorum-votes="2" \
stonith-enabled="false" \
no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" \
resource-stickiness="100"

Esta configuración muestra el estado funcional, donde todos los nodos comparten una misma dirección IP, se puede apreciar en la directiva primitive MySQL ocf:heartbeat:mysql que el servicio de MySQL se encuentra clusterizado. En la siguiente captura también se muestra el estado del clúster 
#crm_mon
Last updated: Thu Mar 13 15:40:16 2014
Last change: Thu Mar 13 09:10:39 2014 by root via crm_attribute on hera
Stack: openais
Current DC: hera - partition with quorum
Version: 1.1.6-9971ebba4494012a93c03b40a2c58ec0eb60f50c
2 Nodes configured, 2 expected votes
3 Resources configured.
============
Online: [ hera zeus ]
ClusterIP (ocf::heartbeat:IPaddr2): Started zeus
Clone Set: MysqlClone [MySQL]
Started: [ hera zeus ]
El clúster garantiza la disponibilidad del servicio, pero la integridad y la disponibilidad de la información hay que garantizarla con otro tipo de herramientas. En este caso, para que la información se mantenga en la misma base de datos, se utilizó el método de Réplica circular, que permite tener la misma información en las dos bases de datos. La replicación funciona de la siguiente forma: el servidor esclavo se inicia con una copia exacta de los datos del servidor principal, a continuación se activa el registro binario en el principal y el esclavo se conecta a este periódicamente y
comprueba los cambios efectuados en el registro binario desde la última vez que se conectó[6]. Para mas información de la plica circular se puede consultar el manual de referencia de MySQL5 en esta dirección http://dev.mysql.com/doc/refman/5.1/en/.
 
Conclusión
La tecnología clúster posee muchos beneficios para las aplicaciones de función crítica ya que permite un modelo de escalabilidad de alto impacto. En el centro de datos del CENSA se aplica esta tecnología obteniendo resultados satisfactorios. Las aplicaciones web que tienen una misión critica para el trabajo realizado en la institución, han logrado una alta disponibilidad utilizando este tipo de tecnología.
 
Bibliografía
1: , Escalabilidad, 2013, http://es.wikipedia.org/wiki/Escalabilidad
2: , Clúster (informática), 2013, http://es.wikipedia.org/wiki/Cl%C3%BAster_%28inform%C3%A1tica%29
3: , MySQL, 2013, http://es.wikipedia.org/wiki/Mysql
4: Andrew Beekhof, Clusters from Scratch, 2013, http://clusterlabs.org/doc/en-US/Pacemaker/1.1-plugin/html-single/Clusters_from_Scratch/
5: Kristoffer Gronlund, crm - Pacemaker command line interface for configuration and management, 2013, http://crmsh.nongnu.org/crm.8.html

lunes, 25 de mayo de 2009

Como hacer un memoria flash buteable con Syslinux

En este manual pretendemos hacer una memoria flash buteable, con el Gestor de Arranque (GDA) Syslinux. Primero haremos una breve referencia de que es Syslinux para que el usuario no se pierda al leer y luego explicaremos los pasos a seguir para que nuestra memoria arranque nuestro sistema operativo. En este articulo es valido decir que el sistema que vamos arrancar fue hecho con la herramienta buildroot, una aplicación para construir sistemas embebidos.

¿Que es Syslinux ?

SYSLINUX no se usa normalmente para arrancar instalaciones de Linux completas ya que Linux no suele instalarse en sistemas de archivos FAT. En cambio, se utiliza con frecuencia para discos flexibles de arranque o de rescate, LiveUSBs, u otros sistemas de arranque ligeros. ISOLINUX se utiliza generalmente para LiveCDs de Linux o CDs de arranque instalables.

Una complicación menor aparece en el arranque desde CD-ROM. El Torito (CD-ROM Standard) permite arrancar en dos modos diferentes;
modo de emulación floppy, donde la información del arranque es almacenada en un archivo de imagen de un disco flexible, que es cargado desde el CD, para luego comportarse como un disco virtual flexible. Este archivo de imagen es efectivamente un sistema de archivos FAT, por lo que SYSLINUX es el cargador de arranque necesario.
modo sin emulación, donde la información de arranque es almacenada directamente en el CD. En este modo se necesita ISOLINUX.

Sin embargo, tener la posibilidad de elegir es útil en ocasiones ya que ISOLINUX es vulnerable a errores de la BIOS, caso en el que es práctico poder arrancar utilizando SYSLINUX. Esto afecta sobre todo a ordenadores construidos aproximadamente antes de 1999, y, de hecho, para ordenadores modernos el modo sin emulación es generalmente el método más fiable.

PXELINUX

PXELINUX se utiliza en conjunción con una imagen adecuada para PXE en una tarjeta de red. El entorno PXE utiliza DHCP o BOOTP para habilitar una conexión TCP/IP básica, y luego descarga un programa de arranque por TFTP. Este programa de arranque carga y configura el kernel de acuerdo a directivas que son obtenidas también desde el servidor TFTP.
Típicamente, PXELINUX se usa para instalaciones de Linux desde un servidor de red central o para arrancar estaciones de trabajo sin disco.

EXTLINUX

EXTLINUX es usado normalmente como un cargador de arranque de propósito general, de forma similar a LILO o GRUB.
¿Como hacer nuestar memoria buteable ?
Para hacer nuestra memoria buteable es necesario saber cual es el sistema de archivos que tenemos instalado en ella, en este caso se utilizo extlinux por que nuestra memoria tiene como sistema de fichero ext2, explicaremos los pasos a seguir detalladamente para que el lector no se pierda.

#cfdisk /dev/sdb

marcar la memoria como buteable o iniciar marca de arranque en la partición donde queramos instalar el GDA.

#mkfs.ext2 /dev/sdb1

formatear ext2 .

#mount /dev/sdb1 /media/usb
#montar la flash
#mkdir /media/usb/boot
#mkdir /media/usb/boot/extlinux
#extlinux -zi /media/usb/boot/extlinux

este comando instala el GDA en el directorio extlinux, aqui se encuentra un archivo con toda la información de nuestra usb el archivo se llama extlinux.sys, para que este pueda arrancar nuestro kernel hace falta un archivo de configuración llamado extlinux.conf este es el encargado de llamar al kernel y el initrd veamos
nota: el archivo de configuración tiene que estar en el mismo directorio que que el archivo creado por extlinux extlinux.sys

#touch extlinux.conf
#nano extlinux.conf
DEFAULT Linux
LABEL Linux
KERNEL /boot/bzImage
APPED initrd=/boot/initramfs
TIMEOUT 100

ahora pasaremos a instalar el máster boot récord al inicio de nuestra usb

#cat /lib/extlinux/mbr.bin > /dev/sdb

listo si todo a esta en forma tenemos lista nuestra usb para ser arrancada por cualquier BIOS, a diferencia de GRUB Syslinux es mas fácil de usar.

miércoles, 13 de mayo de 2009

Como realizar una flash buteable con grub

La cuestión es sencilla en este manual vamos a explicar como hacer nuestra flash buteable para arrancar nuestro linux instalado en ella, lástima que windows no sea tan portable porque sino también lo instalaríamos. Ahora para que el lector no se pierda daremos una explicación de lo que es Master Boot Record (MBR) , los gestores de arranque en nuestro caso Grub y posteriormente los pasos para instalar Grub en nuestro dispositivo.

¿Que es el MBR ?

En la práctica, el MBR casi siempre se refiere al sector de arranque de 512 bytes, o el boot sector de una partición para ordenadores compatibles con IBM. Debido a la amplia implantación de ordenadores PC clónicos, este tipo de MBR se usa mucho, hasta el punto de ser incorporado en otros tipos de ordenador y en nuevos estándares multi-plataforma para el particionado y el arranque.
Algunas veces se emplea para el arranque del sistema operativo con bootstrap, otras veces es usado para almacenar una tabla de particiones y, en ocasiones, se usa sólo para identificar un dispositivo de disco individual, aunque en algunas máquinas esto último no se usa y es ignorado.
El MBR y el particionado de discos
Cuando un dispositivo de almacenamiento de datos se ha particionado con un esquema de tabla de particiones del MBR (por ejemplo el esquema convencional de particionado de IBM PC), el MBR contiene las entradas primarias en la tabla de particiones. Las entradas de particiones secundarias se almacenan en registros de particiones extendidas, etiquetas de disco BSD, y particiones de metadatos del Logical Disk Manager que son descritas por esas entradas de particiones primarias.
Por convención, hay exactamente cuatro entradas de particiones primarias en el esquema de la Tabla de Particiones, aunque en algunos sistemas (pocos) se ha extendido ese número a cinco u ocho.

Cuando un dispositivo de almacenamiento de datos se ha particionado con Tabla de Particiones GUID, el Master Boot Record no contiene la tabla de particiones (aunque contiene modelos de estructuras de datos, una protección del MBR frente a programas que sólo entienden el esquema de la Tabla de Particiones del MBR para que no creen particiones en el disco) y se usa poco debido a lo que puede afectar al particionado de disco.

¿Que es Grub?

En computación, el GRand Unified Bootloader (GRUB) es un gestor de arranque múltiple que se usa comúnmente para iniciar dos o más sistemas operativos instalados en un mismo ordenador.
Técnicamente, un gestor multiarranque es aquel que puede cargar cualquier archivo ejecutable y que contiene un archivo de cabecera multiarranque en los primeros 8 KB del archivo. Tal cabecera consiste en 32 bits de un número “mágico”, 32 de indicadores (flags), otros 32 de un número “mágico”, seguidos de información sobre la imagen ejecutable.
Una de las características más interesantes es que no es necesario instalar una partición nueva o un núcleo nuevo, pudiendo cambiar todos los parámetros en el arranque mediante la Consola de GRUB.
Mientras los gestores de arranque convencionales tienen una tabla de bloques en el disco duro, GRUB es capaz de examinar el sistema de archivos. Actualmente, soporta los siguientes sistemas de archivos:

ext2/ext3 usado por los sistemas UNIX y su variante GNU/Linux
ext4 en versiones de pruebas.
ReiserFS.
XFS de SGI (aunque puede provocar problemas).
UFS.
VFAT, como FAT16 y FAT32 usados por Windows 9.x
NTFS usado por los sistemas Windows NT (a partir de Windows NT v.3.51).
JFS de IBM.

HFS de Apple Inc.

Otros ejemplos de cargadores multiarranque son LILO y SYSLINUX.
GRUB soporta 14 colores de fondo, que normalmente es negro. Algunas distribuciones de sistemas operativos que incluyen GRUB frecuentemente utilizan fondos personalizados con el logotipo de dicha distribución. Los usuarios de GRUB pueden también hacer sus propios fondos.
Proceso de inicio de Grub
1.El BIOS busca un dispositivo de inicio (como el disco duro) y pasa el control al registro maestro de inicio (Master Boot Record, MBR, los primeros 512 bytes del disco duro).
2.El MBR contiene la fase 1 de GRUB. Como el MBR es pequeño (512 bytes), la fase 1 sólo carga la siguiente fase del GRUB (ubicado físicamente en cualquier parte del disco duro). La fase 1 puede cargar ya sea la fase 1.5 o directamente la 2
3.GRUB fase 1.5 está ubicada en los siguientes 30 kilobytes del disco duro. La fase 1.5 carga la fase 2.
4.GRUB fase 2 (cargada por las fases 1 o 1.5) recibe el control, y presenta al usuario el menú de inicio de GRUB.
5.GRUB carga el kernel seleccionado por el usuario en la memoria y le pasa el control.

Instalar Grub en nuestro dispositivo USB.

Para instalar grub en nuestro dispositivo flash, pendriver como le queramos llamar, tenemos que copiar el directorio boot para nuestro dispositivo.

#fdisk -l
Disco /dev/sda: 160.0 GB, 160041885696 bytes
255 heads, 63 sectors/track, 19457 cylinders
Units = cilindros of 16065 * 512 = 8225280 bytes
Disk identifier: 0xbee5bee5

Disposit. Inicio Comienzo Fin Bloques Id Sistema
/dev/sda1 1 122 979933+ 82 Linux swap / Solaris
/dev/sda2 * 123 2554 19535040 83 Linux
/dev/sda3 2555 4986 19535040 83 Linux
/dev/sda4 4987 19457 116238307+ 5 Extendida
/dev/sda5 4987 7418 19535008+ 83 Linux
/dev/sda6 7419 19457 96703236 83 Linux

Disco /dev/sdb: 512 MB, 512483328 bytes
64 heads, 32 sectors/track, 488 cylinders
Units = cilindros of 2048 * 512 = 1048576 bytes
Disk identifier: 0x00000000

Disposit. Inicio Comienzo Fin Bloques Id Sistema
/dev/sdb1 * 1 488 499696 83 Linux

Nuestra flash se encuentra en /dev/sdb1, montamos la flash en una carpeta en /mnt que se llame flash.

#mkfs.ext# /dev/sdb1 (#=1 o 3)
#mkdir /mnt/flash
#mount /dev/sdb1 /mnt/flash/
#cd /
#cp -r boot /mnt/flash/

Dentro del directorio /boot/grub se encuentra todas las faces de grub para los diferentes sistemas de ficheros y particiones, estas fases son importantes ya que permiten completar el ciclo de transición de control que tenia MBR al grub. Ahora es cuando vamos a hacer buteable la flash con el gestor de arranque grub, es decir instalar grub en el dispositivo.
Simplemente tenemos que asociar nuestro dispositivo en este caso sdb#, a uno que reconozca grub como es hd#

#grub
Tiene que salir la shell de comandos de grub y ejecutamos lo siguiente:

>device (hd2) /dev/sdb
>root (hd2,0)
>setup (hd2)
>quit

Editar el menu.lst y poner los parámetros de arranque para su sistema
#nano /mnt/flash/boot/grub/menu.lst

title linux
kernel /boot/bzImage
initrd /boot/initramfs

#umount /dev/sdb1

Ahora explicare como fue que realizamos nuestra pequeña distribucion con buildroot
simplemetente marcamos los siguentes paquetes busybox, Bash , module-init-tool, nano , udev y grub , ejucutar make para que nuestro cross-compile compile nuestros paquetes si todo ha marchado bien nuestro sistema se encontrara en /buildroot/project_build_arch/arch/root/* copiar todo esto para nuestro dispositivo USB

#cp -r /buildroot/project_build_arch/arch/root/* /mnt/flash/

si marcamos copiar los binarios para nuestro target no es nesesario copiar la imagen del kernel que se encuentra en binaries si no tenemos que copiarla

#cp -r /builroot/binaries/arch/bzImage /mnt/flash/boot/
#cp -r /builroot/binaries/arch/rootfs.arch.cpio.gz /mnt/flash/boot/

despues ejecutamos

#grub

>device (hd2) /dev/sdb
>root (hd2,0)
>setup (hd2)
>quit

Editar el menu.lst o copiamos el de nuestro sistema y lo modificamos

#nano /mnt/flash/boot/grub/menu.lst

title linux
kernel /boot/bzImage
initrd /boot/initramfs

Si todo ha salido bien reinicie su pc y tienes una flash buteando por grub, es válido aclarar que grub fue realizado para disco, puede ser que los BIOS de algunas máquinas no reconozcan el MBR de la flash y no te dejen butear, o simplemente grub de error 21 cargando la fase 1,5. El gestor de arranque que se usa para las memorias flash es syslinux, posteriormente explicaremos en un artículo.

martes, 31 de marzo de 2009

El compilador GCC

GCC es un compilador integrado del proyecto GNU para C, C++, Objective C y Fortran; es capaz de recibir un programa fuente en cualquiera de estos lenguajes y generar un programa ejecutable binario en el lenguaje de la máquina donde ha de correr.
La sigla GCC significa "GNU Compiler Collection". Originalmente significaba "GNU C Compiler"; todavía se usa GCC para designar una compilación en C. G++ refiere a una compilación en C++.
Sintaxis.
gcc [ opción | archivo ] ...
g++ [ opción | archivo ] ...

Las opciones van precedidas de un guión, como es habitual en UNIX, pero las opciones en sí pueden tener varias letras; no pueden agruparse varias opciones tras un mismo guión. Algunas opciones requieren después un nombre de archivo o directorio, otras no. Finalmente, pueden darse varios nombres de archivo a incluir en el proceso de compilación.
Ejemplos.
gcc hola.c
compila el programa en C hola.c, gener un archivo ejecutable a.out.
gcc -o hola hola.c
compila el programa en C hola.c, gener un archivo ejecutable hola.
g++ -o hola hola.cpp
compila el programa en C++ hola.c, gener un archivo ejecutable hola.
gcc -c hola.c
no genera el ejecutable, sino el código objeto, en el archivo hola.o. Si no s indica un nombre para el archivo objeto, usa el nombre del archivo en C y le cambia la extensión por .o.
gcc -c -o objeto.o hola.c
genera el código objeto indicando el nombre de archivo.
g++ -c hola.cpp
igual para un programa en C++.
g++ -o ~/bin/hola hola.cpp
genera el ejecutable hola en el subdirectorio bin del directorio propio del usuario.
g++ -L/lib -L/usr/lib hola.cpp
indica dos directorios donde han de buscarse bibliotecas. La opción -L debe repetirse para cada directorio de búsqueda de bibliotecas.
g++ -I/usr/include hola.cpp
indica un directorio para buscar archivos de encabezado (de extensión .h).
Sufijos en nombres de archivo.
Son habituales las siguientes extensiones o sufijos de los nombres de archivo:

.c fuente en C
.C .cc .cpp .c++ .cp .cxx fuente en C++; se recomienda .cpp
.m fuente en Objective-C
.i C preprocesado
.ii C++ preprocesdo
.s fuente en lenguaje ensamblador
.o código objeto
.h archivo para preprocesador (encabezados), no suele figurar en la linea de comando de gcc
Opciones.
- c
realiza preprocesamiento y compilación, obteniento el archivo en código objeto; no realiza el enlazado.
- E
realiza solamente el preprocesamiento, enviando el resultado a la salida estándar.
-o archivo
indica el nombre del archivo de salida, cualesquiera sean las etapas cumplidas.
-Iruta
especifica la ruta hacia el directorio donde se encuentran los archivos marcados para incluir en el programa fuente. No lleva espacio entre la I y la ruta, así: -I/usr/include
-L
especifica la ruta hacia el directorio donde se encuentran los archivos de biblioteca con el código objeto de las funciones referenciadas en el programa fuente. No lleva espacio entre la L y la ruta, así: -L/usr/lib
-Wall
muestra todos los mensajes de error y advertencia del compilador, incluso algunos cuestionables pero en definitiva fáciles de evitar escribiendo el código con cuidado.
-g
incluye en el ejecutable generado la información necesaria para poder rastrear los errores usando un depurador, tal como GDB (GNU Debugger).
-v
muestra los comandos ejecutados en cada etapa de compilación y la versión del compilador. Es un informe muy detallado.
Etapas de compilación.
El proceso de compilación involucra cuatro etapas sucesivas: preprocesamiento, compilación, ensamblado y enlazado. Para pasar de un programa fuente escrito por un humano a un archivo ejecutable es necesario realizar estas cuatro etapas en forma sucesiva. Los comandos gcc y g++ son capaces de realizar todo el proceso de una sola vez.
1. Preprocesado.
En esta etapa se interpretan las directivas al preprocesador. Entre otras cosas, las variables inicializadas con #define son sustituídas en el código por su valor en todos los lugares donde aparece su nombre.

Usaremos como ejemplo este sencillo programa de prueba, circulo.c decrito a continuacion:

/* Circulo.c: calcula el área de un círculo.
Ejemplo para mostrar etapas de compilación.
*/
#define PI 3.1416

main()
{
float area, radio;

radio = 10;
area = PI * (radio * radio);
printf("Circulo.\n");
printf("%s%f\n\n", "Area de circulo radio 10: ", area);

}

El preprocesado puede pedirse con cualquiera de los siguientes comandos; cpp alude específicamente al preprocesador.
$ gcc -E circulo.c > circulo.pp
$ cpp circulo.c > circulo.pp
Examinando circulo.pp
$ more circulo.pp
puede verse que la variable PI ha sido sustituída por su valor, 3.1416, tal como había sido fijado en la sentencia #define.
2. Compilación.
La compilación transforma el código C en el lenguaje ensamblador propio del procesador de nuestra máquina.

$ gcc -S circulo.c
realiza las dos primeras etapas creando el archivo circulo.s; examinándolo con
$ more circulo.s
puede verse el programa en lenguaje ensamblador.
3. Ensamblado.
El ensamblado transforma el programa escrito en lenguaje ensamblador a código objeto, un archivo binario en lenguaje de máquina ejecutable por el procesador.

El ensamblador se denomina as:
$ as -o circulo.o circulo.s
crea el archivo en código objeto circulo.o a partir del archivo en lenguaje ensamblador circulo.s. No es frecuente realizar sólo el ensamblado; lo usual es realizar todas las etapas anteriores hasta obtener el código objeto así:
$ gcc -c circulo.c
donde se crea el archivo circulo.o a partir de circulo.c. Puede verificarse el tipo de archivo usando el comando
$ file circulo.o
circulo.o: ELF 32-bit LSB relocatable, Intel 80386, version 1, not stripped

En los programas extensos, donde se escriben muchos archivos fuente en código C, es muy frecuente usar gcc o g++ con la opción -c para compilar cada archivo fuente por separado, y luego enlazar todos los módulos objeto creados. Estas operaciones se automatizan colocándolas en un archivo llamado makefile, interpretable por el comando make, quien se ocupa de realizar las actualizaciones mínimas necesarias toda vez que se modifica alguna porción de código en cualquiera de los archivos fuente.
4. Enlazado
Las funciones de C/C++ incluídas en nuestro código, tal como printf() en el ejemplo, se encuentran ya compiladas y ensambladas en bibliotecas existentes en el sistema. Es preciso incorporar de algún modo el código binario de estas funciones a nuestro ejecutable. En esto consiste la etapa de enlace, donde se reúnen uno o más módulos en código objeto con el código existente en las bibliotecas.

El enlazador se denomina ld. El comando para enlazar
$ ld -o circulo circulo.o -lc
ld: warning: cannot find entry symbol _start; defaulting to 08048184
da este error por falta de referencias. Es necesario escribir algo como
$ ld -o circulo /usr/lib/gcc-lib/i386-linux/2.95.2/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o circulo /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i386-linux/2.95.2/crtbegin.o -L/usr/lib/gcc-lib/i386-linux/2.95.2 circulo.o -lgcc -lc -lgcc /usr/lib/gcc-lib/i386-linux/2.95.2/crtend.o /usr/lib/crtn.o
para obtener un ejecutable.

El uso directo del enlazador ld es muy poco frecuente. En su lugar suele proveerse a gcc los códigos objeto directamente:
$ gcc -o circulo circulo.o
crea el ejecutable circulo, que invocado por su nombre
$ ./circulo
Circulo.
Area de circulo radio 10: 314.160004
da el resultado mostrado.
Todo en un solo paso.
En programa con un único archivo fuente todo el proceso anterior puede hacerse en un solo paso:
$ gcc -o circulo circulo.c
No se crea el archivo circulo.o; el código objeto intermedio se crea y destruye sin verlo el operador, pero el programa ejecutable aparece allí y funciona.

Es instructivo usar la opción -v de gcc para obtener un informe detallado de todos los pasos de compilación:
$ gcc -v -o circulo circulo.c
Enlace dinámico y estático.
Existen dos modos de realizar el enlace:
- estático: los binarios de las funciones se incorporan al código binario de nuestro ejecutable.
- dinámico: el código de las funciones permanece en la biblioteca; nuestro ejecutable cargará en memoria la biblioteca y ejecutará la parte de código correspondiente en el momento de correr el programa.
El enlazado dinámico permite crear un ejecutable más chico, pero requiere disponible el acceso a las bibliotecas en el momento de correr el programa. El enlazado estático crea un programa autónomo, pero al precio de agrandar el tamaño del ejecutable binario.

Ejemplo de enlazado estático:
$ gcc -static -o circulo circulo.c
$ ls -l circulo
-rwxr-xr-x 1 victor victor 237321 ago 4 11:24 circulo
Si no se especifica -static el enlazado es dinámico por defecto.

Ejemplo de enlazado dinámico:
$ gcc -o circulo circulo.c
$ ls -l circulo
-rwxr-xr-x 1 victor victor 4828 ago 4 11:26 circulo
Notar la diferencia en tamaño del ejecutable compilado estática o dinámicamente. Los valores pueden diferir en algo de los mostrados; dependen de la plataforma y la versión del compilador.

El comando ldd muestra las dependencias de bibliotecas compartidas que tiene un ejecutable:
$ gcc -o circulo circulo.c
$ ldd circulo
libc.so.6 => /lib/libc.so.6 (0x40017000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$ gcc -static -o circulo circulo.c
$ ldd circulo
statically linked (ELF)
La compilación estática no muestra ninguna dependencia de biblioteca.
Resumen.
Para producir un ejecutable con fuente de un solo archivo:
$ gcc -o circulo circulo.c
Para crear un módulo objeto, con el mismo nombre del fuente y extensión .o:
$ gcc -c circulo.c
Para enlazar un módulos objeto:
$ gcc -o circulo circulo.o
Para enlazar los módulos objeto verde.o, azul.o, rojo.o, ya compilados separadamente, en el archivo ejecutable colores:
$ gcc -o colores verde.o azul.o rojo.o
Información adicional.
Sobre GCC:
man gcc
info gcc
página info de GCC, más completa y actualizada que la página man.
Sobre el depurador:
man gdb
info gdb
página info de GDB, más completa y actualizada que la página man.
Sobre uso de info:
info info
ofrece un tutorial paso a paso.
GNU info
un resumen de operación de info.

lunes, 30 de marzo de 2009

Sobre el archivo /etc/passwd

El contenido del fichero /etc/passwd determina quien puede acceder al sistema de manera legitima y que se puede hacer una vez dentro del sistema. Este fichero es la primera linea de defensa del sistema contra accesos no deseados. Debe de mantenerse escrupulosamente y libre de errores y fallos de seguridad. En el tenemos registrados las cuentas de usuarios, asi como las claves de accesos y privilegios.

Una linea ejemplo en este fichero:

usuario1:FXWUuZ.vwXttg:500:501:usuario pepito:/home/usuario1:/bin/bash

Los diferentes campos(7) estan separados por dos puntos (:) y el significado de los mismos es el siguiente:


usuario1:
Nombre de la cuenta (Login)
FXWUuZ.vwXttg:
Clave de acceso encriptada (password)
500:
UID de esta cuenta
501:
GID del grupo principal al que pertenece la cuenta
usuario pepito:
Nombre del usuario
/home/usuario1:
Directorio de trabajo de usuario1
/bin/bash:
Interprete de comando (shell) de usuario pepito

Una serie de reglas a tener en cuenta sobre el contenido de este fichero:

* El UID de cuenta 0, pertenece al administrador (root), por debajo de UID 500 esta reservado para el sistema y por encima de UID 500 para los usuarios del sistema (Nota: la frontera del 500 puede variar dependiendo del sistema).

El GID del grupo principal esta definido en el archivo /etc/group y este sera el grupo por defecto cuando un usuario crea un fichero.

No hace falta decir que solo el administrador del sistema tiene que tener ID's 0 en estos dos campos. Lo contrario significaria estar dando permisos de administracion (root) a la cuenta en cuestion.

Lo unico que identifica a una cuenta root del resto es una identificacion UID igual a 0. Podemos tener por ejemplo una cuenta llamada "pepito" pero con UID igual a 0, esta cuenta tendria permisos de administrador (root) y muchos programas que hacen referencia al nombre de la cuenta (ej: who, w, etc) no nos darian informacion sobre que la cuenta "pepito" tiene permisos de root.

Esto es lo primero que un hacker suele hacer para instalar una puerta trasera en un sistema. Para averiguar cuentas con nombre diferente de root, pero permisos de root existen programas, pero a falta de uno podemos utilizar el siguiente comando:

awk -F: '{if ($3==0) print $1}' /etc/passwd

Lo mismo (con un pequeno cambio) se puede utilizar para ver cuentas con GID igual a 0:

awk -F: '{if ($4==0) print $1}' /etc/passwd


* Es muy importante verificar asiduamente que toda cuenta (login) tiene asignada una clave valida. Existen programas para comprobar que no existen problemas de seguridad en /etc/passwd, pero a falta de uno se puede utilizar el siguiente comando para averiguar si existen cuentas sin claves:

awk -F: '{if ($2=="") print $1}' /etc/passwd

Nunca dejar una cuenta con el campo de clave vacio, esto significa que no es necesario una clave para entrar en el sistema. Las cuentas de pseudo-usuarios (ej: daemon, lp, etc) y cuentas de usuarios cerradas temporalmente, tienen que tener un asterisco (*) en el campo de la clave.

Otro punto a tener en cuenta es la eleccion de una buena clave. No se deberian utilizar claves que sean palabras de diccionario, nombres, datos personales, matriculas, etc, existen programas que son capaces de descifrar este tipo de claves. Utilizar al menos 7 caracteres (8 recomendable) e interpolar numeros y letras, mayusculas y minusculas. Existen programas que sustituyen el clasico "passwd" para crear/cambiar claves, que comprueban que la clave es suficientemente buena.

La explicacion de porque no se deberian utilizar palabras de diccionario, nombres, etc como claves de acceso, es la siguiente:

Cuando una clave es generada, esta, es codificada con la funcion "crypt", esta funcion se puede definir como una funcion "hash" de una sola direccion, esto es, un algoritmo que es facil de computar en una direccion pero muy dificil de calcular en direccion opuesta. La funcion crypt utiliza un valor aleatorio llamado "salt" el cual esta formado por una cadena de dos caracteres [a-z A-Z 0-9 ./]. Este valor aleatorio permite codificar una misma clave de 4096 maneras distintas (Los dos primeros caracteres de una clave codificada, son los valores de "salt", el resto hasta un total de 13 caracteres ASCII es la clave codificada segun el valor de "salt").

Una vez que sabemos un poco de teoria de como las claves son codificadas, nos podemos imaginar como se podria descifrar un clave de cuenta que es un palabra de diccionario, nombre, matricula, etc. Existen programas que codifican sistematicamente diccionarios de palabras de las 4096 maneras posibles (segun el valor "salt") y comparan cada codificacion con los valores encriptados en /etc/passwd, si algun valor coincide, significaria que una clave ha sido descifrada. Este es uno de los metodos utilizados por hackers para descifrar claves y la razon de porque no se deben utilizar claves que sean palabras de diccionarios, nombres, etc.


* Nunca usar scripts/programas como interprete de comandos en cuentas sin clave. Un ejemplo que lei una vez en un grupo de noticias, hablaba sobre como apagar el ordenador sin necesidad de ser root. Una de las soluciones que daban era el tener la siguiente linea en el fichero /etc/passwd:

shutdown::0:0:shutdown:/sbin:/sbin/shutdown

Podeis ver que el campo de clave esta vacio, con esta linea en tu /etc/passwd cualquier usuario, local o no local, puede apagar tu ordenador haciendo un simple telnet a la maquina en cuestion y escribiendo shutdown como login. No hace falta explicar las consecuencias que esto puede tener para tu sistema. ;-)


* Los ficheros /etc/passwd y /etc/group deben tener permisos de lectura para todos para que muchos programas puedan funcionar y permisos de escritura solo para root.

-rw-r--r-- 1 root root 11594 Nov 9 12:53 /etc/passwd
-rw-r--r-- 1 root root 1024 Nov 9 12:53 /etc/group

Con estos permisos, cualquiera que tenga acceso al sistema puede leer el contenido de estos ficheros e intentar descifrar la clave encriptada de las cuentas. En pequenos sistemas, donde todos los usuarios se conocen y existe confianza entre ellos, esto no es un gran problema, pero en sistemas con un gran numero de usuarios, no es recomendable tener el sistema configurado de esta manera.

Para evitar esto se puede instalar "Shadow passwords". Con shadow passwords el fichero /etc/passwd puede ser leido por cualquier usuario con acceso, pero la informacion con las claves del sistema queda guardada en un fichero que solo puede ser leido por el administrador (root). Mas informacion sobre Shadow Password en el Howto correspondiente Shadow password HOWTO (ingles)

Esto es todo sobre este fichero tan especial en nuestro sistema. Comentarios y sugerencias al autor.

viernes, 20 de marzo de 2009

Cómo desplazarse por la consola como un experto

Empecemos por lo más sencillo y veamos que cd es un poco más complejo de lo que parece. Mucha gente sabe del autocompletado de bash, gracias al cual basta con escribir parte del nombre del directorio y pulsar Tab para que la consola complete el directorio (si no hay varias posibilidades, en caso contrario tendríamos que pulsar dos veces Tab para verlas). También es muy común el uso de rutas relativas: si estamos en /home/zootropo y queremos desplazarnos a /home/zootropo/videos no es necesario escribir la segunda ruta en su totalidad, sino que podemos escribir simplemente cd videos. Incluso es normal ver a novatos usando atajos como cd .. para desplazarse al directorio superior y cd ~ o cd para desplazarse al directorio de usuario.

Lo que es menos común, y muy útil para el tema que nos ocupa es el uso de cd -. Este flag tan útil no hace otra cosa que movernos al último directorio en el que estuvimos.

zootropo@genua:~$ cd /etc/X11/
zootropo@genua:/etc/X11$ cd
zootropo@genua:~$ cd -
/etc/X11
zootropo@genua:/etc/X11$ pwd
/etc/X11

De esta forma podemos movernos entre dos directorios rápidamente.

Por otro lado, si lo que necesitamos es desplazarnos a un directorio tan solo un momento para ejecutar un comando y luego seguir trabajando en el directorio actual, también podríamos usar &&, que ejecuta dos comandos, uno detrás de otro, de forma condicional (and con cortocircuito):

cd /etc/X11/ && cat xorg.conf

y rodearlo con paréntesis, que hace que los comandos se ejecuten en una subshell

(cd /etc/X11/ && cat xorg.conf)

de esta forma se ejecutará el comando en una subshell distinta, por lo que el cd no nos afectará, y será como si nunca nos hubiéramos desplazado.

Pero, ¿qué ocurre si queremos movernos entre varios directorios? ¿qué podemos hacer si queremos desplazarnos, por ejemplo, al penúltimo directorio que visitamos? la combinación pushd, popd y dirs, nos proporciona una alternativa válida.
pushd, popd y dirs

pushd funciona como un cd normal, moviéndonos al directorio especificado, pero además, como su nombre indica, introduce dicho directorio en una pila.

pushd /etc/X11/

popd también funciona como un cd, pero el directorio al que nos mueve es el que extrae de la pila, y dado que la pila es una estructura LIFO (Last In, First Out o lo que es lo mismo, el último en introducirse es el primero en extraerse) al escribir este comando nos moveremos al último directorio añadido a la pila.

popd

También es posible indicar qué elemento de la pila queremos utilizar mediante un índice. Por ejemplo:

popd +2

extraería el tercer elemento (el índice del primer elemento es 0). También podemos utilizar índices negativos, como -2, contando al revés.

Por último dirs nos sirve para imprimir el contenido de la pila:

zootropo@genua:/etc/X11$ dirs
/etc/X11 ~

Al comando dirs también se le puede pasar un índice para imprimir tan solo el directorio seleccionado por el índice.

La desventaja del uso de pushd y popd es que cada vez que hacemos un popd el directorio se borra de la pila, y si quisiéramos volver a utilizarlo tendríamos que volver a guardarlo en la pila, lo cual va en contra de la rapidez que buscamos y que nos impulsó a usarlos en primer lugar.

Existe una alternativa que consiste en aprovecharnos de la característica de la indexación de dirs. El comando

dirs +0

mostraría el primer elemento de la pila.

Basta con usar este directorio como argumento para cd para poder movernos a los directorios almacenados sin que se borren de la pila:

cd `dirs +0`

Sin embargo, por alguna extraña razón, cuando el directorio que seleccionamos con dirs es el directorio home, que se almacena como ~, este pequeño truco no funciona, sino que tendríamos que usar el flag -l para que dirs muestre la ruta completa del directorio home en lugar de ~.

cd `dirs -l +0`

Podríamos ahorrarnos tener que escribir el flag -l con un alias, e incluso crear alias como

alias cd="pushd"
alias cd1="cd `dirs -l +1`"

de forma que al escribir cd1 nos desplazáramos al penúltimo directorio introducido con nuestro cd-pushd.

Sin embargo, hay alternativas más sencillas, como CDargs.
CDargs

CDargs se encuentra en los repositorios de Ubuntu, así que instalarlo en esta distro es tan sencillo como escribir:

sudo aptitude install cdargs

También es conveniente añadir las funciones para bash ya creadas que vienen con la aplicación editando el .bashrc:

gedit ~/.bashrc

y añadiendo la siguiente línea, que hace un source del archivo correspondiente (asegúrate de que el archivo se instaló en esa ruta y modifica la línea adecuadamente si no es así)

source /usr/share/doc/cdargs/examples/cdargs-bash.sh

Reinicia la consola y podemos empezar a jugar.

Si escribimos el comando

cv

en la consola, se lanzará la interfaz gráfica en ncurses de CDargs, un pequeño explorador de archivos en modo consola.

CDargs

Primero seleccionamos el directorio que nos interesa con las flechas de arriba y abajo, con Avance página y Retroceso de página, con Inicio y Fin o pulsando el número asociado. Si solo queremos hacer un cd a ese directorio, pulsamos enter. Si queremos hacer un cd a un directorio que está contenido dentro del directorio seleccionado, pulsamos la flecha derecha para que CDargs muestre su contenido, y por último, si queremos movernos a un directorio superior, pulsamos la flecha izquierda. Para salir de la interfaz sin hacer nada, pulsamos la tecla 'q'. Si queremos ver archivos ocultos, pulsamos la tecla '.'.

CDargs también incluye un sistema de marcadores. Para utilizarlo nos desplazaremos al directorio que queramos añadir a nuestros favoritos y escribimos

ca etiqueta

Por ejemplo:

cd /home/zootropo/videos
ca vid

Después basta escribir

cv etiqueta

para desplazarnos al directorio que guardamos en marcadores con dicha etiqueta.

Podemos ver los marcadores que hemos creado desde la interfaz gráfica de CDargs, pulsando la tecla Tab para cambiar entre el modo de marcadores y el modo explorador.

Por último, quizás os interese echar un vistazo a los gestores de archivo de modo consola, como GNU Midnight Commander

sudo aptitude install mc debian o ubunto
zypper install mc opensuse o suse
emerge gentoo
rm -i paquete.rmp
dpkg -i paquete.deb

fuente:http://www.linux-es.org/

jueves, 19 de marzo de 2009

Recuperando ficheros borrados con un poco de suerte, lsof y /proc

¿Alguna vez habeis borrado un fichero por equivocacion desde consola, cuando estabais trabajando con el? Supongo que habeis echado mil maldiciones por la equivocacion y el tiempo perdido cuando esto os ha pasado.

En este articulo vamos a hablar de la utilidad 'lsof'. Con este programa, la informacion en /proc y un poco de suerte, probablemente podamos recuperar el fichero que por arte de magia desaparecio de vuestro sistema cuando lo borrasteis accidentalmente. La 'poca de suerte' de la que hablamos es que el fichero que habeis borrado estuviese siendo accedido por un programa en el momento de realizar la operacion de borrado. A continuacion vamos a ver un ejemplo de como podemos realizar esta recuperacion.

Primero vamos a ver un poco como podemos acceder a la informacion o estatus de un fichero. Para esto podemos utilizar el programa de sistema stat. Veamos como funciona:

Primero creamos un fichero de texto:

user@test# echo "ESTO ES UN FICHERO DE TEXTO DE PRUEBAS" > fichero_pruebas.txt

A continuacion podemos usar stat para obtener la informacion de este fichero:

user@test# stat fichero_pruebas.txt
File: `fichero_pruebas.txt'
Size: 39 Blocks: 8 IO Block: 4096 regular file
Device: 301h/769d Inode: 512495 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ user) Gid: ( 1000/ user)
Access: 2008-02-04 22:28:57.000000000 +0100
Modify: 2008-02-04 22:28:57.000000000 +0100
Change: 2008-02-04 22:28:57.000000000 +0100

Alguna de esta informacion tambien la podriamos haber obtenido usando el comando ls:

user@test# ls -li fichero_pruebas.txt
512495 -rw-r--r-- 1 root root 39 2008-02-04 22:28 fichero_pruebas.txt

De toda esta informacion, la que nos interesa en este articulo es la denominada Inode. Segun Wikipedia, un inodo (inode en ingles) se puede definir como:

"... una estructura de datos propia de los sistemas de archivos tradicionalmente empleados en los sistemas operativos tipo UNIX como es el caso de Linux. Un inodo contiene las características (permisos, fechas, ubicación, pero NO el nombre) de un archivo regular, directorio, o cualquier otro objeto que pueda contener el sistema de ficheros.

El término "inodo" refiere generalmente a inodos en discos (dispositivos en modo bloque) que almacenan archivos regulares, directorios, y enlaces simbólicos. El concepto es particularmente importante para la recuperación de los sistemas de archivos dañados.

Cada inodo queda identificado por un número entero, único dentro del sistema de ficheros, y los directorios recogen una lista de parejas formadas por un número de inodo y nombre identificativo que permite acceder al archivo en cuestión: cada archivo tiene un único inodo, pero puede tener más de un nombre en distintos o incluso en el mismo directorio para facilitar su localización."

En nuestro caso el inodo de nuestro fichero es 512495, este es el identificador de nuestro fichero en el sistema. Cuando borramos un fichero con el comando rm, lo que hacemos es borrar la referencia al inodo en cuestion, durante un tiempo dicho inodo seguira existiendo en nuestro sistema aunque no podamos verlo y parezca que el fichero borrado ha desaparecido de nuestro sistema.

Si algun programa esta accediendo el fichero que hemos borrado, estamos de suerte. El programa en cuestion tendra una referencia al inode del fichero borrado y siempre que no cerremos este programa podremos recuperar el contenido de dicho fichero. (Un caso practico que a muchos nos a pasado alguna vez es el borrar el fichero log de algun servicio del sistema (apache, postgresql, mysql. etc) mientras que el servicio esta funcionando)

A continuacion presentamos una session completa desde que borramos un fichero hasta que lo recuperamos:

Abrimos nuestro fichero ejemplo con less (por ejemplo)

user@test# less fichero_pruebas.txt

ESTO ES UN FICHERO DE TEXTO DE PRUEBAS
fichero_pruebas.txt (END)

Pulsamos Ctrl+z para suspender el programa less sin pararlo (el programa seguira abierto, accediendo nuestro fichero, pero suspendido)

user@test# less fichero_pruebas.txt

[1]+ Stopped less fichero_pruebas.txt

Comprobamos que nuestro fichero sigue intacto:

user@test# ls -li fichero_pruebas.txt
512495 -rw-r--r-- 1 root root 39 2008-02-04 22:28 fichero_pruebas.txt

Lo borramos ... accidentalmente ;-)

user@test# rm ficheros_de prueba.txt

Comprobamos que no existe en nuestro directorio

user@test# ls -li fichero_pruebas.txt
ls: fichero_pruebas.txt: No such file or directory

Como hemos comentado mas arriba, si tenemos un programa accediendo el fichero estamos de suerte. Utilizamos lsof para ver si algun programa esta accediendo el fichero que hemos borrado:

user@test# lsof |grep fichero_pruebas.txt
less 28410 user 4r REG 3,1 39 512495 /home/user/fichero_pruebas.txt (deleted)

No deberia de ser una sorpresa que nuestro programa less este accediendo nuestro fichero borrado. Las columnas que nos interesan de esta linea son la primera (PID del programa accediendo el fichero, 28410), y la cuarta, el 'file descriptor' (4r) con la referencia al inodo de nuestro fichero (512495).

Con esta informacion nos vamos al sistema de ficheros virtual /proc con informacion de nuestro sistema linux.

user@test# ls -l /proc/28410/fd/4
lr-x------ 1 user user 64 2008-02-04 22:38 /proc/28410/fd/4 -> /home/user/fichero_pruebas.txt (deleted)

Como era de esperar, una referencia al fichero borrado. Lo unico que tenemos que hacer ahora es copiar los datos a los que /proc/28410/fd/4 esta haciendo referencia. Para esto podemos utilizar simplemente el comando cp

user@test# cp /proc/28410/fd/4 fichero_pruebas.txt.restaurado

Ahora no importa que nuestro programa less termine de ejecutarse, porque nuestro fichero borrado ya esta recuperado.

user@test# cat fichero_pruebas.txt.restaurado
ESTO ES UN FICHERO DE TEXTO DE PRUEBAS

En este articulo hay que tener un poco de suerte para no perder nuestro fichero, pero en futuros articulos veremos otras tecnicas a usar cuando la suerte no esta de nuestro lado. Esto es todo por hoy, que lo disfruteis.

fuente:http://www.linux-es.org/node/834