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).