martedì 19 luglio 2011

Continue riallocazioni delle VM

Risolti i problemi di cui al post precedente, adesso il cluster con RedHat Cluster Suite e libvirt funziona alla grande.
Così alla grande che ogni due minuti le VM vengono riallocate, quelle che erano sull'host1 finiscono nell'host2 e viceversa. E mi raccomando, non migrate, riallocate.

Nei log questo simpatico errorino:

Jul 19 17:25:21 rgmanager status on vm "prometeo" returned 127 (unspecified)
Jul 19 17:25:21 rgmanager No other nodes have seen vm:prometeo

Criptico come poche volte, no? Come si risolve un problema del genere?

Provo a testare con rg_test:

# rg_test test /etc/cluster/cluster.conf status vm prometeo
...
Hypervisor URI: qemu:///system
Migration URI format: qemu+ssh://target_host/system
Virtual machine prometeo is running
Status check of prometeo failed

Coerente, direi. Quindi c'è un errore nel check dello status. Lo script inciminato è /usr/share/cluster/vm.sh, che usa due funzioni per verificare lo status, virsh_status e do_status (ci sarebbe anche xm_status, ma in questo momento non ci interessa):

virsh_status()
{
        declare state pid

        if [ "$OCF_RESKEY_hypervisor" = "xen" ]; then
                service xend status &> /dev/null
                if [ $? -ne 0 ]; then 
                        echo indeterminate
                        return $OCF_APP_ERR_INDETERMINATE
                fi
        fi

        #
        # libvirtd is required when using virsh even though
        # not specifically when also using Xen.  This is because
        # libvirtd is required for migration.
        #
        pid=$(pidof libvirtd)
        if [ -z "$pid" ]; then 
                echo indeterminate
                return $OCF_APP_ERR_INDETERMINATE
        fi

        state=$(virsh domstate $OCF_RESKEY_name)

        echo $state

        if [ "$state" = "running" ] || [ "$state" = "paused" ] ||
           [ "$state" = "no state" ] || 
           [ "$state" = "idle" ]; then
                return 0
        fi

        if [ "$state" = "shut off" ]; then
                return $OCF_NOT_RUNNING
        fi

        return $OCF_ERR_GENERIC
}


#
# Simple status check: Find the VM in the list of running
# VMs
#
do_status()
{
        if [ "$OCF_RESKEY_use_virsh" = "1" ]; then
                virsh_status
                return $?
        fi

        xm_status
        return $?
}

Guardatele quanto volete, l'errore non è in nessuna delle due funzioni: se la VM è viva, virsh_status ritorna 0 e do_status pure (era dura visto che non fa altro che richiamare virsh_status).

Dov'è il problema? Si verifica più avanti, per la precisione nel case che decide quale azione è stata richiamata:

status|monitor)
                validate_all || exit $OCF_ERR_ARGS
                echo -n "Virtual machine $OCF_RESKEY_name is "
                do_status
                rv=$?
                if [ $rv -ne 0 ]; then
                        exit $rv
                fi
                [ -z "$OCF_RESKEY_status_program" ] && exit 0
                [ -z "$OCF_CHECK_LEVEL" ] && exit 0
                [ $OCF_CHECK_LEVEL -lt 10 ] && exit 0

                bash -c "$OCF_RESKEY_status_program" &> /dev/null
                exit $?
                ;;


Qual è il problema? Il valore di status_program (uno dei parametri di configurazione della risorsa vm) di default è 0. Non vuoto (cosa che gli farebbe passare indenne il test in rosso e quindi farebbe uscire vm.sh), ma 0.

<parameter name="status_program" reconfig="1">
    <longdesc lang="en">
        Ordinarily, only the presence/health of a virtual machine
        is checked.  If specified, the status_program value is
        executed during a depth 10 check.  The intent of this 
        program is to ascertain the status of critical services
        within a virtual machine.
    </longdesc>
    <shortdesc lang="en">
        Additional status check program
    </shortdesc>
    <content type="string" default="0"/>
</parameter> 

A questo punto, salutati i santi che uno ha tirato giù dal Paradiso, la soluzione è aggiungere l'ennesimo parametro alla configurazione della VM in /etc/cluster/cluster.conf:

<vm autostart="0" domain="domainseminole" exclusive="0" migrate="live" 
    status_program="" name="prometeo" 
    xmlfile="/etc/libvirt/qemu/prometeo.xml" recovery="relocate"/>

(libvirt) Timed out during operation: cannot acquire state change lock

Bell'errore di stamattina, durante un tentativo di migrazione di una VM da un host all'altro.
Sembra che il problema sia un non meglio identificato bug di libvirt versione 0.8, e sembra che sparisca dalla 0.9:

https://bugzilla.redhat.com/show_bug.cgi?id=676205

Ma per chi come me è su una Debian Squeeze e non ha voglia di iniziare la trafila del backport dei pacchetti a neanche due mesi dall'aggiornamento, non è che sia di molta consolazione.
Comunque a quello che ho visto è un qualcosa che manda a funghi libvirt. Il sintomo principale non è tanto il messaggio del titolo, quanto che libvirt non dà più la situazione corretta. Per verificarlo basta vedere la dissonanza tra:

# virsh --connect qemu:///system list --all

e

# ps -elf | grep qemu

Dei due, è il secondo che ha ragione.

La soluzione è stata riavviare libvirt, ma se in uno dei due server la cosa è andata liscia con
# /etc/init.d/libvirt-bin restart
l'altro non voleva saperne di morire. Quindi:
# kill -9 <piddilibvirt>
(sì, ok, andava bene anche pkill libvirt-bin).

Restano un processo nc (netcat, che si individua con ps -elf | grep libvirt), anche quello da killare, e due socket: /var/run/libvirt-sock e /var/run/libvirt-sock-ro, entrambi da cancellare.

A questo punto, riavviato libvirtd, la situazione è allineata e la migrazione funziona. Per la cronaca, via ssh con:
# virsh --connect qemu:///system migrate --live <vm> qemu+ssh://<altro>/system

lunedì 20 giugno 2011

Trasformare il proprio PC in access point wireless (router)

Diciamo che ho un iPod Touch dotato di WiFi e vorrei usare il portatile come router per connetterlo in rete.
La scheda WiFi è una Intel Corporation PRO/Wireless 2200BG. Sistema operativo Debian GNU/Linux Squeeze.

Diciamo che ci sono diverse cose che possono andare storte e il fatto che siano parecchi mesi che non uso il WiFi su questo portatile aiuta a fare un ripasso.

Il primo ostacolo è che questo è un portatile dotato di tasto per abilitare/disabilitare il WiFi (nel mio caso è Fn-F2, l'icona è un'antenna azzurrina). Quindi il primo check da fare se il WiFi non funziona è proprio questo tasto. Questo è quello che si vede quando il WiFi è disabilitato:

# iwconfig
...

eth0      no wireless extensions.

eth1      radio off  ...

Questo dopo aver premuto il tasto:

# iwconfig
...
eth0      no wireless extensions.

eth1      unassociated  ...

Se non cambia nulla, bisogna abilitare la scheda anche via ifconfig:

# ifconfig eth1 up

A questo punto bisogna configurare la eth1 in modalità ad-hoc, con tutti gli ammennicoli del caso. Attenzione al channel che finché è 0 la rete non va, e di default ovviamente è 0:

# iwconfig eth1 essid MyEssid mode ad-hoc key s:mypwd channel 1

Le cose da cambiare qui sono MyEssid, mypwd ed eventualmente 1 (con un altro numero a scelta).

Poi bisogna dare un ip a eth1:

# ifconfig eth1 up 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255

o una qualche configurazione desiderata.

Infine abilitare routing e nat:

# modprobe iptable_nat
# modprobe nf_conntrack_ipv4
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 10.0.0.1

Lato iPod in Impostazioni -> Wi-Fi compare la rete MyEssid, che richiede la password mypwd. Clickando sulla freccetta blu si cambiano le impostazioni della rete. Scegliere statico e impostare i parametri come fosse un normale PC:

indirizzo IP10.0.0.2
maschera sottorete255.255.255.0
router10.0.0.1
dnsa.b.c.d
domini di ricercadominio.it

ed eventuale proxy. I dati del dns si ricavano da /etc/resolv.conf del portatile linux.

martedì 14 giugno 2011

Debian Squeeze e cluster RedHat

Non c'è più da compilare il modulo, basta installare il pacchetto redhat-cluster-suite:

# aptitude install redhat-cluster-suite

Si prende senza problemi la configurazione di lenny.



clvmd could not create local socket

Bisogna creare la directory /var/run/lvm che lo script di installazione si dimentica.

clvmd could not connect to cluster manager

Bisogna installare dlm-pcmk e disinstallare libdlm2. Quindi riavviare cman e rgmanager.

Upgrade di Lenny: /boot/grub/device.map

Devo dire che è una situazione complicata. Sto facendo l'aggiornamento di un server Debian da lenny a squeeze e mi dà il seguente errore:

Running postinst hook script update-grub.
Searching for GRUB installation directory ... found: /boot/grub
warning: grub-probe can't find drive for /dev/sdu2.
grub-probe: error: Cannot find a GRUB drive for /dev/sdu2.  Check your device.map.

User postinst hook script [update-grub] exited with value 1
dpkg: error processing linux-image-2.6.26-2-amd64 (--configure):
 subprocess post-installation script returned error exit status 1
Errors were encountered while processing:
 linux-image-2.6.26-2-amd64
E: Sub-process /usr/bin/dpkg returned an error code (1)
A package failed to install.  Trying to recover:
Setting up linux-image-2.6.26-2-amd64 (2.6.26-26lenny2) ...


La cosa divertente è che di questo kernel non me ne faccio nulla, visto che non è nemmeno quello in uso. Ma il problema non è questo kernel, quanto update-grub:

seminole:/# update-grub
Searching for GRUB installation directory ... found: /boot/grub
warning: grub-probe can't find drive for /dev/sdu2.
grub-probe: error: Cannot find a GRUB drive for /dev/sdu2.  Check your device.map.


La soluzione temporanea (viene sovrascritta ogni volta che si aggiorna grub) è aggiungere il device incriminato (nel mio caso sdu) in /boot/grub/device.map, ad esempio con la riga:

(hd9) /dev/sdu

A questo punto update-grub non dà più errori:

seminole:/boot/grub# update-grub
Searching for GRUB installation directory ... found: /boot/grub
Searching for default file ... found: /boot/grub/default
Testing for an existing GRUB menu.lst file ... found: /boot/grub/menu.lst
Searching for splash image ... none found, skipping ...
Found Xen hypervisor 3.2-1-amd64,  kernel: /vmlinuz-2.6.26-2-xen-amd64
Found kernel: /vmlinuz-2.6.26-2-xen-amd64
Found kernel: /vmlinuz-2.6.26-2-amd64
Updating /boot/grub/menu.lst ... done


Le cose si sistemano una volta completato l'upgrade.

Adesso mi sono davvero decisa

Basta. Credo che il sistema che sto mettendo in piedi abbia bisogno di un serio esorcismo.

Aprire un blog sembra molto simile a un esorcismo. Almeno nella mia testa.