Race condition tra Upstart e Samba se nel pc è presente un interfaccia bridge

Vengo subito al dunque, dopo un recente aggiornamento del pacchetto samba ho cominciato ad avere problemi ad accedere alle mie cartelle condivise sul mio ubuntu server 10.04.
Nella mia macchina è presente un bridge di rete che collega la mia interfaccia ethernet su cavo (eth0) con quella wifi (wlan0):

router <= eth0 (0.0.0.0) => br0 (192.168.1.10) <= wlan0 (0.0.0.0) => altri pc.

Il problema si risolveva se, dopo l’avvio della macchina, riavviavo il servizio samba.

Per trovare l’origine del problema ho controllato i file di log di samba:

[2010/09/17 08:39:56, 0] lib/util_sock.c:938(open_socket_in)
bind failed on port 445 socket_addr = fe80::201:2eff:fe2f:d55%br0.
Error = Cannot assign requested address
[2010/09/17 08:39:56, 0] smbd/server.c:457(smbd_open_one_socket)
smbd_open_once_socket: open_socket_in: Cannot assign requested address
[2010/09/17 08:39:56, 0] lib/util_sock.c:938(open_socket_in)
bind failed on port 139 socket_addr = fe80::201:2eff:fe2f:d55%br0.
Error = Cannot assign requested address
[2010/09/17 08:39:56, 0] smbd/server.c:457(smbd_open_one_socket)
smbd_open_once_socket: open_socket_in: Cannot assign requested address

La mia configurazione di rete di samba è la seguente:

interfaces = 127.0.0.0/8 192.168.1.0/24 br0
bind interfaces only = yes

In pratica samba pubblica le sue sockets nell’interfaccia di rete br0 e loopback.

Il problema si presenta perché upstart non aspetta che il bridge di rete sia attivo prima di avviare il servizio samba. Il bridge impiega circa 15 secondi ad avviarsi, nel mentre samba pubblica le sue sockets solo nelle interfacce di rete attive  in quel momento, essendo l’interfaccia bridge ancora non attiva, samba fallisce la pubblicazione del servizio sul bridge impedendo così l’accesso da un computer remoto.
La conferma mi è stata data dal comando netstat -an.

Prima del riavvio del servizio samba:

tcp 0 0 127.0.0.1:139 0.0.0.0:* LISTEN
...
tcp 0 0 127.0.0.1:445 0.0.0.0:* LISTEN

Dopo il riavvio del servizio samba:

tcp 0 0 127.0.0.1:139 0.0.0.0:* LISTEN
tcp 0 0 192.168.1.10:139 0.0.0.0:* LISTEN
...
tcp 0 0 127.0.0.1:445 0.0.0.0:* LISTEN
tcp 0 0 192.168.1.10:445 0.0.0.0:* LISTEN

La soluzione al problema è modificare lo script di avvio di samba di upstart.
Ovvero:

sudo nano /etc/init/smbd.conf

e cambiare la linea:

start on local-filesystems

in

start on (local-filesystems and net-device-up IFACE=br0)

Ovviamente se la vostra interfaccia bridge ha un nome diverso da br0 cambiatelo opportunamente.

In questo modo obbligherete upstart ad aspettare che il bridge sia attivo prima di avviare il demone samba.

Errori simili posso verificarsi se sulla vostra macchina viene eseguito il demone dhcp3-server configurato per fornire indirizzi ip sull’interfaccia bridge.

Race condiction analogo per dhcpd

(!sic) Ho risolto il problema con il servizio dhcp3 editando il file:

sudo nano /etc/init/rc-sysinit.conf

e cambiando la linea

start on filesystem and net-device-up IFACE=lo

in

start on filesystem and net-device-up IFACE=br0

For more info about this problem see:
https://bugs.launchpad.net/ubuntu/+source/dhcp3/+bug/580319

tftpd-hpa

Problemi anche con lui. il più delle volte si avvia e pubblica le sue socket sull’interfaccia bridge correttamente, tuttavia, sporadicamente fallisce.
Quindi forziamo lo script di avvio, del servizio tftp-hpa, ad attendere la disponibilità del bridge prima di avviare il demone:

nano /etc/init/tftpd-hpa.conf

e cambiare la riga:

start on (filesystem and net-device-up IFACE!=lo)

in

start on (filesystem and net-device-up IFACE=br0)

La condizione IFACE!=lo è sicuramente più furba tra tutte la condizioni di avvio riscontrate nei precedenti file di configurazione (dhcpd e samba), tuttavia non è sufficiente se nella vostra macchina avete più di un interfaccia di rete (es. tunnel ipv6). Il bridge è un interfaccia lenta e il servizio in questione finisce col pubblicare le proprie socket sulle altre interfacce di rete attive ma non sul bridge.

Giacché sono in tema…
Dato che in internet non ho visto molti esempi corretti di configurazioni (per debian) di interfacce bridge, riporto la mia configurazione di rete:

/etc/network/interfaces

auto lo
iface lo inet loopback

iface eth0 inet manual

iface wlan0 inet manual

auto br0
iface br0 inet static
	bridge_ports eth0 wlan0
	address 192.168.1.10
	network 192.168.1.0
	netmask 255.255.255.0
	gateway 192.168.1.1
	broadcast 192.168.1.255

Per esempi di configurazione diversi e più completi vi rimando alla pagina, in inglese, della wiki di debian.