viernes, 13 de julio de 2012

7 ejemplos prácticos del comando Locate de Linux



Cuando se necesita buscar algún archivo, comunmente se utiliza el comando find. find es una buena utilidad de búsqueda, pero es lenta. locate puede buscar archivos de forma muy rápida. A continuación presento una traducción -libre- de este artículo, donde se detalla el funcionamiento de locate y se incluyen algunos prácticos ejemplos de uso.



Cómo funciona locate? - updatedb yh updatedb.conf


Cuando decimos que locate busca muy rápido, entonces la primera pregunta que viene a la mente es ¿qué lo hace tan rápido?

Bien, locate no busca los archivos en disco, sino que busca las rutas a los archivos en una base de datos.

La base de datos es un archivo que contiene información sobre los archivos y sus rutas en el sistema. La base de datos de locate se encuentra en /var/lib/mlocate/mlocate.db

La siguiente pregunta lógica es ¿qué mantiene a esta base de datos mlocate actualizada?

Bien, existe otra utilidad conocida como updatedb. Cuando se ejecuta updatedb, se escanea el sistema completo y se actualiza mlocate.db.

De tal manera que una de las limitaciones de locate es que depende de la base de datos, la cual es actualizada por updatedb. Por lo tanto, para obtener resultados actualizados y fiables, de locate, la base de datos debe ser actualizada frecuentemente.

También se puede configurar updatedb de acuerdo a nuestras necesidades. Esto se puede lograr actualizando el archivo updatedb.conf. Este es un archivo de configuración que lee updatedb antes de actualizar la base de datos. updatedb.con se encuentra dentro de /etc/:

# cat /etc/updatedb.conf
PRUNE_BIND_MOUNTS="yes"
PRUNENAMES=".git .bzr .hg .svn"
PRUNEPATHS="/tmp /var/spool /media"
PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs shfs sysfs cifs lustre_lite tmpfs usbfs udf fuse.glusterfs fuse.sshfs ecryptfs fusesmb devtmpfs"

updatedb.conf contiene data en la forma VARIABLE=VALOR. Estas variables pueden ser clasificadas en las siguientes categorías:

  • PRUNEFS: Una lista (separada por espacios en blanco) de tipos de sistemas de archivos (como se usan en /etc/mtab) que no deben ser escaneados por updatedb. La comparación de los tipos de archivos es insensible a mayúsculas y minúsculas. Por defecto, ningún sistema de archivo es omitido. Cuando se escanea y un sistema de archivo es omitido, todos los sistemas de archivos montados en su sub-árbol son también omitidos, inclusive si su tipo no coincide con alguna entrada en PRUNEFS.
  • PRUNENAMES: Una lista (separada por espacios en blanco) de nombres de directorio (sin rutas) que no deben ser escaneados por updatedb. Por defecto, ningún nombre de directorio es omitido. Note que sólo se pueden especificar directorios y no se pueden utilizar mecanismos de patrones (como globbing, por ejemplo).
  • PRUNEPATHS: Una lista (separa por espacios en blanco) de nombres de rutas de directorio que no deben ser escaneadas por updatedb. Cada nombre de ruta debe estar en la forma exacta en la cual el directorio sería reportado por locate. Por defecto, ninguna ruta es omitida.
  • PRUNE_BIND_MOUNTS: puede valer "0", "no", "1" o "yes". Si PRUNE_BIND_MOUNTS vale "1" o "yes", los bind mounts que tengamos en el sistema no serán escaneados por updatedb. Todos los sistemas de archivo montados en el sub-árbol de un bind mount también serán omitidos, inclusive si no son bind mounts. Por defecto, los bind mounts no son omitidos.

Tenga en cuenta que toda esta configuración se puede modificar a tavés de las opciones del comando updatedb.


Ejemplos prácticos del uso de locate

1. Buscar un archivo usando locate


Para buscar un archivo con locate, ejecutamos:

locate nombre_de_archivo

Si se especifica la opción -0 se muestra la salida en una sola línea.

locate -0 nombre_archivo


2. Mostrar sólo la cantidad de archivos encontrados

locate -c nombre_de_archivo


3. Usar updatedb para actualizar la base de datos mlocate

sudo updatedb #debe ser ejecutado como root


4. Cambiar la base de datos mlocate

La base de datos que locate utiliza por omisión es /var/lib/mlocate/mlocate.db, pero se puede especificar otra, se utiliza la opción -d:

locate -d ruta_otra_base_datos nombre_de_archivo

5. Verificar si un archivo existe

Si eliminamos un archivo del sistema, hasta que no se actualice la base de datos, seguirá apareciendo en los resultados de búsqueda de locate. Si especificamos la opción -e, locate verificará la existencia física de los archivos y no mostrará aquellos archivos que no se encuentren.

locate -e nombre_archivo

6. No tomar en cuenta mayúsculas y minúsculas

Siendo locate sensible a las mayúsculas y minúsculas, "new.txt" es distinto a "NEW.txt". Si queremos que esto no sea tomado en cuenta, utilizamos la opción -i:

locate -i nombre_De_ArchiVo


7. Filtrar las salidas

Si queremos ver sólo los primeros N resultados, utilizamos la opción -l:

locate -l N nombre_de_archivo

Fuente: TheGeekStuff

jueves, 12 de julio de 2012

Programación de Módulos para el Kernel de Linux (II)

En una entrada anterior realicé una introducción a la programación de módulos para el kernel del Linux: los comandos básicos para gestionarlos (lsmod, insmod, rmmod, etc), su estructura básica, compilación, alguno que otro detalle y por supuesto, el típico hola mundo.

Particularmente para la compilación, utilicé un Makefile sencillo para utilizarlo en cualquier directorio y contra la versión actual del kernel.

Ahora queremos compilar un kernel vanilla, con nuestros propios módulos. Esto es bastante parecido a lo que hicimos en la entrada anterior con algunas consideraciones adicionales.

Partimos del hecho de que tenemos el kernel vanilla sobre el que trabajaremos, y más importante aún, que sabemos compilarlo, así que no tocaremos detalles de la compilación per se.

Agregaremos el hola mundo que ya hemos hecho, al directorio del kernel en el que se almacena el Linux Virtual Server, que en la versión sobre la cual estoy trabajando (la 3.0.1), sería net/netfilter/ipvs/.

Bien, vamos al directorio net/netfilter/ipvs y agregamos nuestro módulo que llamaremos ip_vs_hola.c. Dentro de él, colocaremos el código tal cual como el ejemplo final de la entrada anterior:

#include <linux/module.h>  /* utilizada por todos los modulos */
#include <linux/init.h>    /* utilizada para poder usar macros */
#include <linux/kernel.h>  /* utilizada por printk */

int init_func()
{
    printk(KERN_INFO "holamundo: cargando...\n");
    return 0;
}

void exit_func()
{
    printk(KERN_INFO "holamundo: descargando...\n");
}

module_init(init_func);
modue_exit(exit_func);

Bien, si queremos que nuestro módulo aparezca entre las opciones cuando hacemos make menuconfig, por ejemplo, debemos agregarlo al archivo Kconfig del directorio en el cual se encuentra el módulo (net/netfilter/ipvs/Kconfig en este caso).

config CONFIG_IP_VS_HOLA
    tristate "Hola Mundo"
    help
      Modulo hola mundo para el ip_vs.

Acá le hemos puesto un nombre para ser usado en el ámbito de la configuración, hemos dicho que puede ser seleccionado como módulo, built-in o ninguno, y hemos especificado una ayuda corta. Para más detalles, revisar la documentación oficial de kconfig aquí.

El siguiente paso es modificar el Makefile (también del directorio donde se encuentra el módulo) con las reglas necesarias para su compilación. En este caso, dada la sencillez del problema, basta con agregar obj-$(CONFIG_IP_VS_HOLA) += ip_vs_hola.o en alguna parte del Makefile. Así estaríamos usando la variable con la cual identificamos a nuestro módulo, que al momento de compilar se transformará en "y" o "m" si configuramos para ser compilada buit-in o como módulo, respectivamente.

Finalmente nos queda completar los pasos normales para una instalación de un kernel a partir de sus fuentes (compilar el kernel, compilar los módulos, instalar los módulos e instalar el kernel).

Podemos hacer el ejercicio de seleccionar nuestra opción como built-in, en vez de módulo, y veremos como luego de instalado el kernel, cada vez que lo iniciemos, tendremos en el log el mensaje que imprimimos en la función de inicialización. Si por el contrario, seleccionamos como módulo, tendremos que hacer un modprobe para que se ejecute dicha función.


EXPORT_SYMBOL

Una de las múltiples razones por las cuales quisieramos agregar nuestros módulos a un kernel, es agregar funcionalidades de algún tipo. Eventualmente podríamos requerir utilizar en un módulo, una función que hemos definido en otro módulo.

Ahora vamos a agregar una función saludar() a nuestro módulo ip_vs_hola, que también imprima algo con printk(). Si quisieramos utilizar esta función dentro de otro módulo ip_vs_hola_2, utilizamos EXPORT_SYMBOL de la siguiente manera en ip_vs_hola:

#include <linux/module.h>  /* utilizada por todos los modulos */
#include <linux/init.h>    /* utilizada para poder usar macros */
#include <linux/kernel.h>  /* utilizada por printk */

int saludar()
{
 printk(KERN_INFO "la funcion saludar ha sido invocada \n");
 return 1;
}
EXPORT_SYMBOL(saludar);

int init_func()
{
    printk(KERN_INFO "holamundo: cargando...\n");
    return 0;
}

void exit_func()
{
    printk(KERN_INFO "holamundo: descargando...\n");
}

module_init(init_func);
modue_exit(exit_func);

Y luego, en ip_vs_hola_2 bastaría con una referencia extern a dicha función.
#include <linux/module.h>  /* utilizada por todos los modulos */
#include <linux/init.h>    /* utilizada para poder usar macros */
#include <linux/kernel.h>  /* utilizada por printk */

extern int saludar(void);

int init_func()
{
    saludar();
    return 0;
}

void exit_func()
{
    printk(KERN_INFO "holamundo: descargando...\n");
}

module_init(init_func);
modue_exit(exit_func);

Y eso es todo. No es nada del otro mundo, pero hay que tomar un par de cosillas adicionales en cuenta. 

lunes, 2 de julio de 2012

Descargar videos de youtube desde Ubuntu con youtube-dl

Existen infinidad de opciones para descargar videos de youtube. Una de las que más me gusta, es la que ofrece el site keepvid.com (valga la publicidad): simplemente introducimos la URL del video y obtenemos los enlaces de descarga en distintas calidades. Como keepvid existen muchos sitios, la mayoría de ellos plagados de publicidad, cosa molesta, de la que keepvid no tiene mucha.

Sin embargo, hoy me he encontrado con una aplicación para Linux que funciona por línea de comandos: youtube-dl. Es una maravilla, viene con muchas opciones y, repito, funciona en línea de comandos :)

En Ubuntu, la instalación es muy simple, ya que el paquete se encuentra en los repositorios oficiales, así que es cuestión de una línea:
sudo aptitude install youtube-dl

Luego de instalado, tecleamos:
youtube-dl http://www.youtube.com/watch?v=BUhZF9KghyI
y nos estaremos bajando, al directorio actual, un video con los 73 goles de Messi en la temporada 2011-2012 :)

Como dije, youtube-dl viene con una buena cantidad de opciones. Entre las más interesantes está el de la calidad. La especificamos con la opción -f. La lista de calidades la podemos ver aquí. Por ejemplo, para bajar el video anterior en format FLV a 480p, sería:
youtube-dl -f 35 http://www.youtube.com/watch?v=BUhZF9KghyI

Si vieron la lista, entenderán que 35 corresponde al itag de la calidad que dijimos. Hay que aclarar que en Youtube, no todas las calidades están disponibles para todos los videos. En este caso, youtube-dl nos avisará que no puede realizar la descarga.

Si queremos además ponerle un nombre, utilizamos la opción -o:
youtube-dl -f 35 -o golesDeMessi.flv http://www.youtube.com/watch?v=BUhZF9KghyI

También tenemos la posibilidad de descargar una playlist completa o parte de ella, para lo cual usamos opcionalmente --playlist-start=M para especificar el número de video desde el cual comenzar a descargar, y --playlist-end=N para especificar el último. Si no especificamos playlist-start se comienza con el video número 1 y sin playlist-end se termina con el último.

Si sólo queremos el audio del vídeo, podemos utilizar --extract-audio--audio-format=FORMAT (Siendo FORMAT: "best", "aac" o "mp3").

Existen unas cuantas opcions más, cuestión de hacer youtube-dl --help para revisarlas todas. Es importante destacar que además de youtube, youtube-dl también permite descargar videos de Dailymotion, Vimeo y algunos otros sitios.

Migrar Máquina Virtual KVM

Normalmente uso una PC de escritorio y una Laptop. En ambas necesito tener un cluster de máquinas virtuales con Ubuntu corriendo, algunas de ellas con kernels personalizados. He dedicado bastante tiempo para lograr cierta configuración, por lo que perderlas por alguna falla de disco, por ejemplo, sería catastrófico para mí.

Por ello, dediqué un tiempo a averiguar qué tan factible sería poder hacer un backup de mis VMs para luego poder llevarlas a otra máquina y no perder horas de trabajo para lograr una configuración como la que tenía. Afortunadamente, llegué a la conclusión de que sí es factible (y además fácil) :D

Para comenzar la migración, lo primero que debemos hacer es copiar la imagen de la Máquina Virtual que queremos migrar hacia el nuevo host. Si utilizamos libvirt, normalmente las VMs se almacenan en el directorio /var/lib/libvirt/images.

Luego, desde el nuevo host, abrir Virtual Machine Manager, y arrancar el asistente para crear una nueva Máquina Virtual y seleccionar la opción Import existing disk image.


En el siguiente paso del asistente nos pedirá especificar la ruta a nuestra imagen. No creo que sea estrictamente necesario, pero creo que es bueno, que la imagen se encuentre en /var/lib/libvirt/images y pertenezca al usuario root.



A partir de aquí el proceso es igual al que normalmente realizamos para crear VMs, es decir, seleccionamos la cantidad de CPUs, cantidad de memoria RAM, etc. Obviamente, el asistente no nos permitirá seleccionar el tamaño de disco, porque ya tenemos la imagen.

Al finalizar el asistente, la Máquina Virtual estará lista para usarse y arrancará inmediatamente. En mi caso, hice la migración de una imagen de 8GB y otra de 5.5GB, ambas con Ubuntu 11.10 y funcionó perfectamente en ambos casos. Sólo hay que tener en cuenta que la dirección de red local cambia (en el caso de que eso sea relevante).