Il problema
Una partizione del disco non viene montata dopo l'avvio del sistema, indipendentemente dal fatto che il riavvio sia stato pianificato o meno. Prima del riavvio, la partizione del disco era montata e funzionava correttamente. Il disco è stato montato correttamente dopo il riavvio di altri sistemi, ma non funziona più.
Questo comportamento può verificarsi indipendentemente dal tipo di file system nella partizione e non è correlato al tipo di file system. Sono stati segnalati guasti dei dischi con file system EXT4 o OCFS2, ma possono verificarsi con qualsiasi tipo di file system.
Una voce tipica nel file /etc/fstab potrebbe essere simile a:
/dev/sda1 /mydir ext4 defaults 0 0 /dev/mapper/mpath2 /otherdir ocfs2 _netdev 0 0
o varie combinazioni di questi.
La soluzione
Le unità disco e le partizioni sono indirizzate geograficamente in Linux, in base alla posizione del bus e all'ordine di rilevamento. I dispositivi SAN sono particolarmente vulnerabili alle modifiche nell'ordine di rilevamento a causa dei tempi di riavvio variabili per la SAN o il client.
I nomi dei file su Linux, in genere nella directory /dev/, vengono assegnati dinamicamente a ogni avvio del sistema. All'avvio del kernel, ogni dispositivo disponibile viene rilevato e viene inviata una notifica al sottosistema UDEV (gestione dei dispositivi nello spazio utente). Confrontando le informazioni nell'identificazione del dispositivo del kernel con i set di regole UDEV nella directory /etc/udev/rules.d, UDEV assegna un nome al dispositivo e crea un nodo dispositivo come /dev/sda o /dev/mapper/mpath1 così che le applicazioni possono accedere al dispositivo. Se il dispositivo rilevato è un dispositivo strutturato a blocchi, spesso contiene partizioni contenenti file system che possono essere montati secondo le specifiche nel file /etc/fstab.
Sebbene Linux faccia ogni sforzo per mantenere lo stesso nome del dispositivo durante i riavvii del sistema, le modifiche nell'ambiente esterno possono influenzare le effettive scelte del nome. Ad esempio:la stessa partizione SAN potrebbe essere /dev/sda su un client, ma /dev/sdf su un altro nodo del cluster, a seconda dell'ordine in cui ciascun host ha rilevato il dispositivo o su quale collegamento multipath è online per primo. Un nodo rileva comunemente i suoi dispositivi nello stesso ordine ad ogni avvio, ma questo non è garantito. È necessario un metodo per garantire un'identificazione del dispositivo persistente e prevedibile.
Sebbene Linux tenti di riassegnare lo stesso nome di dispositivo a ogni riavvio, non esiste tale coordinamento tra i nodi del cluster. Una partizione che appare in modo affidabile come /dev/sda1 su un nodo del cluster potrebbe facilmente e legittimamente apparire costantemente come /dev/sdj su un altro nodo del cluster. Ciò può rendere l'amministrazione del sistema a livello di cluster più difficile del necessario. La soluzione fornita di seguito è applicabile anche ai cluster in cui non si verifica questo problema di riavvio.
Sono disponibili tecniche alternative per avere un nome dispositivo persistente e prevedibile. Sono presentati di seguito, in ordine di difficoltà.
Montaggio per etichetta
Molti tipi di file system supportano l'associazione di una stringa o etichetta arbitraria a ciascun file system. Il file system EXT3 è un esempio:
# /sbin/e2label /dev/sda5 /home
È comune vedere una voce /etc/fstab simile a questa:
LABEL=/HOME /home auto defaults 0 0
per individuare la partizione del disco denominata /HOME, indipendentemente dal dispositivo su cui appare.
I file system OCFS2 forniscono anche un'etichetta riconoscibile che può essere utilizzata in modo simile. Vedere l'esempio OCFS2 di seguito per come determinare l'etichetta OCFS2.
Montaggio tramite UUID
Molti tipi di file system assegnano un identificatore univoco universale, o UUID, a ciascuna partizione del disco formattata. I file system EXT3 e OCFS2 ne sono un esempio. L'UUID viene generalmente assegnato automaticamente e gli amministratori di sistema sono generalmente scoraggiati dal modificare manualmente il valore.
Su un file system EXT3 e di altro tipo, utilizzare l'utilità blkid fornita come parte del pacchetto RPM e2fsprogs. Per il nostro esempio, l'output è simile al seguente:
# /sbin/blkid /dev/sda5 /dev/sda5: LABEL="/home" UUID="0c960108-7649-4d8c-a28c-2f75e2f906d3" SEC_TYPE="ext2" TYPE="ext3"
Si noti che l'UUID è, in senso stretto, solo cifre esadecimali. I caratteri “-” sono semplicemente segni di punteggiatura da ignorare.
In un file system OCFS2, l'UUID viene sempre segnalato dall'utilità fsck.ocfs2. Questa utilità può essere utilizzata in sicurezza su una partizione del disco montata se l'opzione "-n" viene utilizzata per garantire un test di sola lettura:
# /sbin/fsck.ocfs2 -n /dev/hda1 Checking OCFS2 filesystem in /dev/hda1: label: OCFS2 uuid: bc d0 de d0 58 ea 43 11 bd a9 e0 66 e6 cb 37 b4 number of blocks: 209632 bytes per block: 1024 number of clusters: 52408 bytes per cluster: 4096 max slots: 4 /dev/hda1 is clean. It will be checked after 20 additional mounts.
Ancora una volta, nota che l'UUID corretto è una stringa di cifre esadecimali. Qui sono punteggiati da spazi, ma il vero UUID sono solo le cifre. Per ottenere solo l'UUID, è sufficiente un breve programma awk(1):
# /sbin/fsck.ocfs2 -n /dev/hda1 | /bin/awk '/uuid/ { $1 = ""; gsub( / /, "" ); print }' bcd0ded058ea4311bda9e066e6cb37b4
Ora che abbiamo l'UUID, una voce /etc/fstab come queste monterebbe le partizioni EXT3 o OCFS2:
UUID=bcd0ded058ea4311bda9e066e6cb37b4 /ocfs2 ocfs2 _netdev 0 2 UUID=0c96010876494d8ca28c2f75e2f906d3 /home ext3 defaults 0 2
Poiché l'UUID è archiviato nella partizione del disco stessa, non importa se il nome effettivo del dispositivo cambia, abbiamo un metodo garantito persistente e prevedibile per accedervi.
Utilizzo dei set di regole UDEV
Un altro metodo per avere nomi di dispositivo persistenti e prevedibili consiste nell'utilizzare lo stesso servizio UDEV utilizzato dal kernel per assegnare i nomi di dispositivo. Ciò comporta la creazione di una regola di corrispondenza UDEV che utilizza gli attributi del dispositivo per identificare il dispositivo e quindi per creare un nodo dispositivo per esso. Spesso la regola crea solo un collegamento simbolico all'effettivo nodo del dispositivo di basso livello assegnato dal kernel.
Questa è la tecnica utilizzata per implementare i dispositivi multipath del device mapper. Il kernel crea un dispositivo /dev/dm-X; quindi le regole UDEV e il demone multipathing creano il collegamento /dev/mpath/
Il tipo di nome del file /dev/mapper/ che viene creato è controllato dall'impostazione del file /etc/multipath.conf user_friendly_names. L'impostazione predefinita è:
default { user_friendly_names yes }
che, stranamente, crea i nomi /dev/mapper/mpathN totalmente privi di significato. Commentando questo, vengono utilizzati i nomi dei moduli /dev/mapper/
Di seguito è riportato un esempio di regola di corrispondenza UDEV. La riga inizia con una serie di predicati o espressioni corrispondenti; questi sono contrassegnati dagli operatori “==”. Se tutti i predicati corrispondono a quelli del dispositivo rilevato, vengono eseguite le azioni indicate dalle clausole "=".
SYSFS{vendor}=="iriver" SYSFS{model}=="T10" OWNER="user" MODE="0600" SYMLINK+="iriver%n"
Questo esempio crea il collegamento simbolico /dev/iriver0 quando il primo lettore IRiver T10 viene collegato a una porta USB. Il dispositivo sarà di proprietà dell'utente con autorizzazioni di accesso ai file 0600. Il sottosistema USB rileva che il dispositivo è stato collegato e notifica il kernel; anche gli attributi rilevati sul dispositivo vengono passati al kernel. Queste informazioni alla fine arrivano al sottosistema UDEV che inizia a leggere i set di regole in /etc/udev/rules.d e ad abbinare gli attributi del dispositivo ai predicati per ciascuna regola. Se tutti i predicati corrispondono per una regola, tutte le azioni specificate da tale regola vengono eseguite.
La documentazione sul sistema UDEV, inclusa la sintassi per scrivere una regola UDEV, è disponibile online tramite la pagina di manuale di udev.
La parte difficile della scrittura di una regola UDEV è sapere quali attributi sono disponibili in modo che il dispositivo possa essere identificato correttamente dalla regola. L'utilità udevinfo visualizzerà il nome del dispositivo e gli attributi disponibili per la regola. Per il nostro esempio, il controllo di /var/log/messages mostra che il dispositivo IRiver è stato rilevato come dispositivo a blocchi e il nome /dev/sdb è stato assegnato. Ora possiamo ottenere tutte le informazioni e gli attributi del dispositivo guardando sotto le informazioni di sistema /block/sdb:
# /usr/bin/udevinfo -q all -p /block/sdb P: /block/sdb N: sdb S: disk/by-id/usb-iriver_T10 S: disk/by-path/pci-0000:00:07.2-usb-0:1:1.0-scsi-0:0:0:0 E: ID_VENDOR=iriver E: ID_MODEL=T10 E: ID_REVISION=1.00 E: ID_SERIAL=iriver_T10 E: ID_TYPE=disk E: ID_BUS=usb E: ID_PATH=pci-0000:00:07.2-usb-0:1:1.0-scsi-0:0:0:0Nota che il percorso è relativo alla directory /sys/, non alla radice tradizionale. Il nome completo del file sarebbe /sys/block/sdb ma udevinfo presuppone la parte /sys.
La scelta dell'insieme minimo di attributi può essere difficile, ma evita la tentazione di specificare eccessivamente. La nostra scelta qui è di utilizzare il nome del fornitore e il nome del modello, ma è possibile utilizzare qualsiasi set di attributi che identifichi il dispositivo oggetto. Una volta scelti i predicati e le azioni, inserisci le tue regole nei loro file nella directory /etc/udev/rules.d. Non modificare un set di regole dalla distribuzione o le modifiche potrebbero andare perse quando il pacchetto viene aggiornato. Nel nostro esempio, abbiamo usato /etc/udev/rules.d/49-iriver.rules per il nome del file.
Con la tua regola UDEV in atto, usa l'utilità udevtest per simulare un'esecuzione UDEV e per mostrare cosa sarebbe stato fatto.