Overblog
Suivre ce blog Administration + Créer mon blog
21 avril 2010 3 21 /04 /avril /2010 23:07

 

Lors de la création d'un snapshot, j'obtiens un message d'erreur EBUSY. Il s'agit d'un bug connu mais j'ai décidé de l'analyser. En voiture...

 

# zfs snapshot zone01/root@today
cannot create snapshot 'zone01/root@today': dataset is busy

 

Il s'agit d'un bug déjà connu mais j'ai eu envie de l'analyser un peu. Je commence par tracer le process :

 

# truss  zfs snapshot zone01/root@today
...
ioctl(3, ZFS_IOC_OBJEST_STATS, 0xFFBFCB90)
 = 0
ioctl(3, ZFS_IOC_SNAPSHOT, 0xFFBFE478)
 Err#16 EBUSY
...

 

L'ioctl passe la main au driver ZFS. On sait juste que le code retour de correspond à EBUSY (16). Je vais donc rechercher avec dtrace les fonctions ZFS lors de la création du snapshot.

 

# ./zfs.d
FCT Code Retour
... 
3
 <- dmu_objest_snapshot_one  16
3    <-
 dmu_objest_snapshot 16
3  <-
 zfsdev_ioctl 16

 

Ce petit script dtrace (script maison) permet de localiser facilement les fonctions ZFS appelées lors de l'exécution de la commande. On remarque les choses suivantes :

  • zfsdev_ioctl() transmet le code retour égal 16 à ioctl().
  • dmu_objest_snaphot() transmet le code retour égal 16 à zfsdev_ioctl()
  • dmu_objest_snaphot_one() transmet le code retour égale 16 à dmu_objest_snaphot()

 

Après lecture du code source de ZFS, je remarque que la fonction dmu_objest_snaphot_one() récupère le code d'erreur de zil_suspend(). Ci-joint l'extrait de la fonction :

 

int zil_suspend(zilog_t *zilog)
{
...
mutex_enter(&zilog->zl_lock);

if (zh->zh_claim_txg != 0) {
mutex_exit(&zilog->zl_lock);
return (EBUSY);

 

Lors de la création du snapshot, la zil doit être vide. Vérifions maintenant si je suis bien dans ce cas :

 

# zdb -ivv snapshot zone01/root
Dataset zone01/root@today [ZPL], ID 21, cr_txg 14, 370 Mo, 9556 objects

ZIL header : claim_txg 98167, seq 0

 

Il semble en effet que je sois dans ce cas. J'applique le workround afin de vérifier complètement ces hypothèses :

 

# zfs list zone01/root
NAME USED AVAIL REFER MOUNTPOINT
zone01/root@today 370 Mo 24.5 Go 370 Mo legacy

# mount | egrep -c zone01/root
0
# zfs set mountpoint=/test zone01/root
# zfs umount zone01/root
# zfs mount zone01/root
# zdb -ivv snapshot zone01/root

Dataset zone01/root@today [ZPL], ID 21, cr_txg 14, 370 Mo, 9556 objects

ZIL header : claim_txg 0, seq 0

 

Comme on peut le voir la zil est vide. J'essaye de créer mon snapshot :

 

# zfs snapshot zone01/root@today
# zfs list -t snapshot | egrep zone01/root@today
zone01/root@today
 0 - 370 Mo -

 

J'ai pu créer mon snapshot ce qui prouve que mon analyse semble correct. J'ai réussi à démontrer le bug 6462803 corrigé dans le patch kernel 141444-01 (à l'heure actuelle, la version de ce patch n'est plus dispo voir la version 141444-09).

 

Partager cet article