I/O disque et I/O filesystem
Posted by Daniel on 06 Mar 2008 at 05:19 | Tagged as: solaris
Cet article présente l'empilement des différentes couches permettant à Solaris de réaliser une opération de lecture/écriture (un I/O) sur un disque.
Le disque physique
Un disque physique est découpé en cylindres, pistes et secteurs, dont la taille est visible via prtvtoc :
# prtvtoc /dev/rdsk/c1t1d0s2 | head * /dev/rdsk/c1t1d0s2 partition map * * Dimensions: * 512 bytes/sector * 107 sectors/track * 27 tracks/cylinder * 2889 sectors/cylinder * 24622 cylinders * 24620 accessible cylinders
La taille maximale d'un I/O physique sur un device (ie, la quantité maximale de données lues ou écrites en une seule opération) est définie par le paramètre maxphys dans le fichier /etc/system :
set maxphys=8388608
S'il n'est pas défini, la valeur par défaut pour Solaris 8 est 131072 (128k). L'état actuel du paramètre est défini dans le kernel :
# adb -k physmem f6da maxphys/D maxphys: maxphys: 131072 (ctrl-D pour sortir)
Le filesystem
Un filesystem est découpé en blocs. La taille de ces blocs peut être trouvée par différents moyens :
# df -g / / (/dev/vx/dsk/rootvol): 8192 block size 1024 frag size 35097262 total blocks 23131780 free blocks 22780808 available 2173952 total files 2064469 free files 52166656 filesys id ufs fstype 0x00000004 flag 255 filename length
ou
# fstyp -v /dev/vx/rdsk/rootvol | head ufs magic 11954 format dynamic time Thu Oct 14 11:14:21 2004 sblkno 16 cblkno 24 iblkno 32 dblkno 736 sbsize 5120 cgsize 8192 cgoffset 56 cgmask 0xffffffe0 ncg 386 size 17826574 blocks 17548631 bsize 8192 shift 13 mask 0xffffe000 fsize 1024 shift 10 mask 0xfffffc00 frag 8 shift 3 fsbtodb 1 minfree 1% maxbpg 2048 optim time maxcontig 16 rotdelay 0ms rps 167
Cache du filesystem
Par défaut, un filesystem lit les données bloc par bloc, mais il est capable de faire du read-ahead : s'il détecte la lecture séquentielle de deux blocs contigus, le filesystem va mettre en cache une série de blocs situés juste après le dernier bloc demandé. Sur UFS, cette série de blocs s'appelle un cluster, et le nombre de blocs ainsi lus est défini par le paramètre maxcontig du filesystem, visible par fstyp :
# fstyp -v /dev/vx/rdsk/rootvol | head ufs magic 11954 format dynamic time Thu Oct 14 11:14:21 2004 sblkno 16 cblkno 24 iblkno 32 dblkno 736 sbsize 5120 cgsize 8192 cgoffset 56 cgmask 0xffffffe0 ncg 386 size 17826574 blocks 17548631 bsize 8192 shift 13 mask 0xffffe000 fsize 1024 shift 10 mask 0xfffffc00 frag 8 shift 3 fsbtodb 1 minfree 1% maxbpg 2048 optim time maxcontig 16 rotdelay 0ms rps 167
Le paramètre maxcontig représente un nombre de blocs, et est donc à multiplier par le bsize pour avoir la taille en octets du read-ahead. Ce paramètre est également utilisé pour le write-behind, c'est-à-dire la quantité de données qui seront mises en cache par le filesystem avant d'être physiquement écrites sur le disque. Ce paramètre peut être modifié à la création du filesystem ou modifié par la suite :
# newfs -C 112 /dev/dsk/c0t0d0s0 # tunefs -a 112 /dev/dsk/c0t0d0s0
Il est à noter qu'UFS ne sait gérer le read-ahead sur un fichier que s'il n'y a qu'un seul accès. Dans le cas d'accès concurrents, les différents seek dans le fichier vont être perçus comme des accès non séquentiels au fichier venant de la même source, et il n'y aura donc pas de read-ahead. La valeur par défaut du maxcontig est de 16 blocs, soit 128ko.
Sur VxFS, la taille du read-ahead est définie au montage, par les paramètres read_pref_io et read_nstream. Le premier définit la taille d'un read-ahead, et le second le nombre de read-aheads parallèles qu'on peut avoir simultanément. Par défaut, la taille d'un read-ahead est de 64ko en VxFS.
I/O directs
En mode I/O direct (forcedirectio en UFS, convosync=direct en VxFS ou raw device), il n'y a ni read-ahead, ni write-behind, puisque ce sont des fonctionnalités apportées par le cache.