programmer@work

robe da informatici

Mini guida su Xen e Debian

image Su questo post vedremo una mini guida su come installare una macchina virtuale con Xen in ambiente GNU/Linux Debian.

Xen è un monitor di macchine virtuali open source rilasciato sotto licenza GPL per piattaforma x86 e compatibili (al momento sono in corso dei port per x86-64 e per IA-64) sviluppato presso il Computer Laboratory dell'Università di Cambridge.

Per chiarezza ricordo che la macchina fisica di solito viene identificata con il nome dom0 (domain 0), mentre le macchine virtuali con il nome domU.

Detto ciò iniziamo.

dom0

Per prima cosa configuriamo alcune opzioni di rete per permettere alle varie domU di usare la rete di dom0. Nel file /etc/sysctl.conf aggiungiamo la linea:

net.ipv4.ip_forward=1

e applichiamo la configurazione con il comando:

sysctl -p

Fatto questo installiamo il necessario:

$ apt-get install xen-hypervisor xen-linux-system xen-tools xen-utils xenstore-utils xenwatch

A questo punto dovremmo aver installato anche un nuovo kernel per la nostra Debian in grado di gestire la virtualizzazione. Dovremmo fare una modifica alla conf di grub per dare priorità al kernel xen rispetto a quello standard: in pratica bisogna rinominare il file dentro la directory /etc/grub.d con nome xx_linux DOPO il file yy_linux_xen. Nel mio caso i file in questione sono 10_linux e 20_linux_xen. Spostiamo il primo dopo il secondo semplicemente rinominando il numero con cui inizia il file (10) in un numero maggiore:

$ cd /etc/grub.d/
$ mv 10_linux 50_linux

Fatto ciò rigeneriamo il file di configurazione di grub (il nostro bootloader preferito) con il comando:

$ update-grub2

e facciamo un reboot:

$ reboot

Controlliamo che sia partito il kernel giusto con il comando:

$ uname -a
Linux 2.6.32-5-xen-amd64 #1 SMP Sun May 6 08:57:29 UTC 2012 x86_64 GNU/Linux

(Eh si… Debian stable)

Ora abbiamo un paio di file di configurazione su cui mettere le mani

  • /etc/xen/xend-config.sxp
  • /etc/xen-tools/xen-tools.conf

Il primo file /etc/xen/xend-config.sxp gestisce la configurazione del demone xend. I valori di default vanno bene, anche se dobbiamo fare alcune modifiche per abilitare il network routing tra la la dom0 e le nostre domU commentando le seguenti righe:

##
# To bridge network traffic, like this:
#
# dom0: ----------------- bridge -> real eth0 -> the network
#                            |
# domU: fake eth0 -> vifN.0 -+
#
# use
#
#(network-script network-bridge)
#
...
#
# If you are using only one bridge, the vif-bridge script will discover that,
# so there is no need to specify it explicitly.
#
#(vif-script vif-bridge)

e decommentando

## Use the following if network traffic is routed, as an alternative to the
# settings for bridged networking given above.
(network-script network-route)
(vif-script     vif-route)

Le altre opzioni vanno bene così come sono, ma se volte approfondire c'è sempre la doc.

Il secondo file /etc/xen-tools/xen-tools.conf serve per gestire la configurazione con cui vengono create le macchine virtuali. Vediamo alcune opzioni:

##
#  Output directory for storing loopback images.
#
#  If you choose to use loopback images, which are simple to manage but
# slower than LVM partitions, then specify a directory here and uncomment
# the line.
#
#  New instances will be stored in subdirectories named after their
# hostnames.
#
##
dir = /var/xen

Specifica la directory dove verranno salvate le immagini delle macchine virtuali. In pratica i file che sono a tutti gli effetti gli HD delle vostre macchine virtuali. Infatti se volete fare un backup di un'intera macchina virtuale salvatevi il suo file immagine.

#
##
#
# If you don't wish to use loopback images then you may specify an
# LVM volume group here instead
#
##
# lvm = vg0

Se non volete usare le immagini, ma HD fisici allora dovrete usate un LVM (Logical Volume Manager).

#
##
#
#  Installation method.
#
#  There are four distinct methods which you may to install a new copy
# of Linux to use in your Xen guest domain:
#
#   - Installation via the debootstrap command.
#   - Installation via the rpmstrap command.
#   - Installation via the rinse command.
#   - Installation by copying a directory containing a previous installation.
#   - Installation by untarring a previously archived image.
#
#  NOTE That if you use the "untar", or "copy" options you should ensure
# that the image you're left with matches the 'dist' setting later in
# this file.
#
#
##
#
#
# install-method = [ debootstrap | rinse | rpmstrap | copy | tar ]
#
#
install-method = debootstrap

In questa sezione di decice in quale modo il sistema operativo delle vostre macchine virtuali verrà installato. Ci sono diversi modi, ma il più comune e semplice è quello di usare l'utility debootstrap che viene usato per creare un sistema Debian da zero, senza la necessità di dpkg o apt. Per fare questo, vengono scaricati i file .deb da un sito mirror e vengono spacchettati in una directory su cui è eventualmente possibile fare il chroot.

#
##
#  Disk and Sizing options.
##
#
size   = 4Gb      # Disk image size.
memory = 128Mb    # Memory size
swap   = 128Mb    # Swap size
# noswap = 1      # Don't use swap at all for the new system.
fs     = ext4     # use the EXT3 filesystem for the disk image.
dist   = `xt-guess-suite-and-mirror --suite` # Default distribution to install.
image  = sparse   # Specify sparse vs. full disk images.

Molto intuitivo, un commento solo alle ultime due opzioni: dist specifica se installare la versione stable, testing o unstable. Mentre image il tipo di immagine da usare come file system: possiamo scegliere tra un'immagine sparse oppure tra un'immagine full disk. Nel primo caso il file aumenta la sua dimensione dinamicamente, mentre nel secondo caso il file avrà la stessa grandezza del valore scelto qualche riga sopra (size).

#
# Uncomment the following line if you wish to interactively setup a
# new root password for images.
#
passwd = 1
#

Immettiamo noi quando creiamo le nostre macchine virtuali la password per l'utente root.

Per le altre opzioni vi rimando alla doc.

A questo punto creiamo la directory che conterrà i file immagini delle nostre macchine virtuali che deve essere quella specificata nella variabile dir del file /etc/xen-tools/xen-tools.conf:

$ mkdir -p /var/xen
$ chmod 755 /var/xen

Riavviamo xend:

$ /etc/init.d/xend restart

domU

Ora il nostro ambiente Debian/Xen dovrebbe essere pronto per la virtualizzazione. Andiamo a creare la nostra macchina virtuale. Per far ciò usiamo i tools che xen ci mette a disposizione, in questo caso xen-create-image. Questo comando necessita di un solo parametro fondamentale ovvero il nome della vostra macchina virtuale. Poi utilizzerà la configurazione salvata nel file /etc/xen-tools/xen-tools.conf (vi ricordate?) per il resto. Possiamo comunque ovverridare alcune opzioni con dei parametri da linea di comando:

$ xen-create-image --hostname=vm1 --size=200Gb --memory=32Gb --ip=www.xxx.yyy.zzz --netmask=255.255.255.248 --gateway=ip.di.dom.0

Questo comando non farà altro che create il file di configurazione specifico per la macchina virtuale “vm1” in /etc/xen/vm1.cfg. Comunque abbiamo creato una configurazione per una macchina virtuale di nome vm1 con HD di capacità 200Gb, memoria ram da 32Gb, ip statico www.xxx.yyy.zzz, netmask 255.255.255.248 e gateway ip.di.dom.0 (ovviamente dom0 deve avere un HD > di 200Gb e memoria RAM > di 32Gb).

Ok, adesso finalmente creiamo sta maledetta macchina:

$ xm create /etc/xen/vm1.cfg

La macchina virtuale si avvia, per vedere lo stato del sistema usate il comodo comando:

$ xm list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0  2353     8     r-----  24266.4
vm1                                          3 30720     8     -b---- 150851.7

I valori di State possono essere:

  • r - running: la macchina sta girando e usando una CPU.
  • b - blocked: la macchina è bloccata e non sta usando la CPU. Questo perchè sta aspettando per operazioni di IO oppure è in sleep perchè non ha niente da fare.
  • p - paused: la macchina è in pausa (xm pause).
  • s - shutdown: la macchina si sta spegnendo o riavviando o sospendendo.
  • c - crashed: la macchina è crashata.
  • d - dying.

Per accedere alla vostra macchina virtuale potete o connettervi via ssh oppure usare il comando:

$ xm console vm1

che vi apre una console alla vostra macchina. Per uscire dalla console usare la combinazione ctrl+].

Per spegnere la macchina:

$ xm shutdown vm1

Per mettere in pausa la macchina:

$ xm pause vm1

Per riattivarla:

$ xm restore vm1

Per eliminare la macchina:

$ xm delete vm1

Ora per abilitare la connessione sulla macchina virtuale domU vm1 dobbiamo editare il file /etc/network/interfaces nel seguente modo:

# The primary network interface
auto eth0
iface eth0 inet static
 address IP.DI.DOMU
 gateway IP.DI.DOM0
 netmask NETMASK.DI.DOM0
 broadcast BROADCAST.DI.DOM0
 pointopoint IP.DI.DOM0

Se volete che al boot di dom0 partano anche le vostre macchine virtuali allora dovete fare un link simbolico del file di configurazione delle vm nella cartella /etc/xen/auto

$ ln -s /etc/xen/vm1.cfg /etc/xen/auto

Infine se un dì avrete bisogno di aumentare lo spazio degli “HD” delle vostre macchine virtuali dovrete aumentare i file immagini. Ciò è possibile con i comandi dd e resize2fs:

$ dd if=/dev/zero bs=1M count=2000 >> /etc/xen/domains/vm1/disk.img
$ resize2fs -f /etc/xen/domains/vm1/disk.img

Con questo comando abbiamo aggiunto 2 Gigabyte all'“HD” della macchina virtuale vm1.

Gestire differenti versioni di gcc su OSX

Vediamo in questo post come gestire differenti versioni di gcc su Mac OS X con port.

La storia è molto semplice grazie all'utility gcc_select che installiamo nel seguente modo:

$ sudo port install gcc_select

A questo punto possiamo vedere le varie versioni di gcc che sono installate sul nostro sistema operativo con il comando:

$ port select --list gcc
Available versions for gcc:
    llvm-gcc42
    mp-gcc47 (active)
    none

In questo esempio il gcc che viene usato è il gcc 4.7 installato con port.

Per switchare versione possiamo dare il comando:

$ sudo port select --set gcc llvm-gcc42
Selecting 'llvm-gcc42' for 'gcc' succeeded. 'llvm-gcc42' is now active.

Chiamate ricorsive Ruby vs Python

Facciamo un piccolo test: calcoliamo Fibonacci ricorsivamente in Ruby (v2.0.0) e in Python (v2.7.2) e vediamo chi vince in termini di tempo

Ruby Fibonacci code (f.rb)

def fib(n)
  if n == 0 || n == 1
    n
  else
    fib(n-1) + fib(n-2)
  end
end

36.times { |i| fib(i) }

Python Fibonacci code (f.py)

def fib(n):
  if n == 0 or n == 1:
    return n
  else:
    return fib(n-1) + fib(n-2)

for i in range(36):
  fib(i)

Ora lanciamo i due programmi nel seguente modo:

$ time ruby f.rb && time python f.py
real  0m4.795s
user  0m4.787s
sys   0m0.007s

real  0m12.935s
user  0m12.849s
sys   0m0.049s

Ecco Ruby impiega 4.795 secondi mentre Python 12.935 secondi!

Ruby vince nettamente su Python!!

Oh beh provate però questo codice in C (f.c):

int
fib (int n)
{
  if (n == 0 || n == 1)
    return n;
  else
    return fib (n-1) + fib (n-2);
}

int
main ()
{
  int i;
  for (i = 0; i < 36; i++)
    fib (i);
}

Compiliamo:

 gcc f.c

Ed eseguiamo:

$ time ./a.out
real  0m0.232s
user  0m0.229s
sys   0m0.003s

0.232 secondi!

Colori nella shell

Per colorare una string nella shell possiamo usare questo template:

\033[CODE1;CODE2;CODE3mTESTO\033[0m

CODE1 possono essere una serie di valori che alterano lo stile del testo, di seguito una tabella:

  • 0 Normal Characters
  • 1 Bold Characters
  • 4 Underlined Characters
  • 5 Blinking Characters
  • 7 Reverse video Characters

CODE2 invece rappresenta il colore, di seguito una tabella:

  • 30 Black
  • 31 Red
  • 32 Green
  • 33 Yellow
  • 34 Blue
  • 35 Magenta
  • 36 Cyan
  • 37 White

CODE3 rappresenta il colore di sfondo del testo, di seguito una tabella:

  • 40 Black
  • 41 Red
  • 42 Green
  • 43 Yellow
  • 44 Blue
  • 45 Magenta
  • 46 Cyan
  • 47 White

Per resettare il testo allo stile di default usare il carattere \033[0m.

Alcuni esempi:

echo -e "\033[31mQUESTO TESTO SARA STAMPATO IN ROSSO\033[0m"
echo -e "\033[1;36mQUESTO TESTO SARA STAMPATO IN GROSSETTO E COLOR CIANO\033[0m"
echo -e "\033[1;35;47mQUESTO TESTO SARA STAMPATO IN GROSSETTO E COLOR MAGENTA SU SFONDO BIANCO\033[0m"

init.d script to run Apache SOLR

Copiate il seguente script in /etc/init.d/solr

#!/bin/sh

PATH=/opt/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=solr
DESC=apache-solr
VERSION=1.4.1
SOLR_PATH=/opt/solr-$VERSION
COMMAND=/usr/bin/java
OPTIONS="-Dsolr.solr.home=$SOLR_PATH/solr -Djetty.home=$SOLR_PATH -jar $SOLR_PATH/start.jar"    
PIDFILE=/var/run/$NAME.pid

test -x $COMMAND || exit 0
test -f $SOLR_PATH/start.jar || exit 0

set -e

case "$1" in
  start)
        if [ -f $PIDFILE ]; then
          echo "$PIDFILE exists. $NAME may be running."
        else
          echo -n "Starting $DESC: "
          start-stop-daemon -b -p$PIDFILE -d$SOLR_PATH --start --quiet --exec $COMMAND -- $OPTIONS
          sleep 3
          echo `ps -ef | grep -v grep | grep "$COMMAND $OPTIONS" | awk '{print $2}'` > $PIDFILE
          echo "$NAME."
        fi
        ;;
  stop)
        if [ -f $PIDFILE ]; then
          echo -n "Stopping $DESC: "
          kill `cat $PIDFILE`
          rm -f $PIDFILE
          echo "$NAME."
        else
          echo "$PIDFILE does not exist. $NAME may be not running."
        fi
        ;;
  restart)
        /etc/init.d/$NAME stop
        sleep 1
        /etc/init.d/$NAME start
        ;;
  *)
        echo "Usage: /etc/init.d/$NAME {start|stop|restart}" >&2
        exit 1
        ;;
esac

exit 0