DTrace pour Oracle Linux

Depuis un peu plus de 2 mois, la version Oracle de DTrace ou « Dynamic Tracing Facility » pour Linux est GA. Les binaires associés font partie du support Premium d’OL6 x86_64 comme KSplice. Dans cette première version, vous pouvez tracer les appels système ; le support des programmes dans le user space est pour plus tard. Pour Java, MySQL ou Perl donc : un peu de patience.

Plusieurs questions accompagnent cette version et font l’objet de commentaires. Parmi elles, la compatibilité des licences GPLv2 et CDDL, la frustration d’une version limitée aux utilisateurs Oracle Linux ou la maturité et l’intérêt d’un projet évoqué depuis 2007.

La réponse à la première question est assez claire : pas de problème quant à la compatibilité des licences. Oracle a, en effet, pris le parti d’intégrer DTrace à Linux à l’aide de modules du kernel. Si vous en doutez, lisez ces 3 articles ici, ici et . En outre, le support Oracle complète le dispositif puisqu’il protège les clients contre d’éventuelles poursuites pour violation de la propriété intellectuelle. Pour ce qui est de la seconde question, c’est très dommage.

Le sujet de cet article est lié la 3ème question: « Qu’est-ce que vous pouvez faire avec DTrace pour Linux aujourd’hui ? »

Introduction

DTrace est sorti de l’imagination de Bryan M. Cantrill, Michael W. Shapiro et Adam H. Leventhal chez Sun. Le premier explique d’ailleurs dans cette video ce qu’est DTrace. Vous trouverez des centaines de ressources et scripts sur le web. Cherchez en particulier Brendan Gregg ou dtrace.conf 2012. Enfin et surtout, vous regarderez la documentation pour Linux dans la mesure ou la version actuelle est plutôt limitée.

Alors qu’est-ce que DTrace ?

Si on s’en tient à sa description, DTrace est un outil à utiliser en production. Il ne perturbe pas un système lorsqu’il n’est pas utilisé et la perturbation est limitée lorsqu’il est utilisé. Une très bonne illustration est le script ci-dessous que vous pouvez lancer sur un système supportant DTrace alors que top fonctionne et que ses appels système sont tracés par la commande « strace -c ». Ce script compte simplement les appels système de ces 3 programmes :

dtrace -n 
'syscall:::/execname=="top"||execname=="strace"||execname=="dtrace"/{ @[execname, probefunc] = count(); }'

strace exit_group 1
dtrace newfstat 2
dtrace rt_sigreturn 2
dtrace write 2
strace close 2
strace mmap 2
strace munmap 2
strace newfstat 2
strace open 2
strace read 2
strace rt_sigreturn 2
strace tgkill 4
dtrace mmap 8
dtrace rt_sigaction 8
top select 9
top access 24
strace write 36
top write 40
top getdents 48
top ioctl 48
dtrace ioctl 76
top lseek 120
top rt_sigaction 576
top fcntl 664
top alarm 864
dtrace futex 1134
top newstat 1894
top close 3788
top open 3788
top read 4172
strace getitimer 14622
strace setitimer 14622
strace wait4 58836
strace rt_sigprocmask 117666
strace ptrace 137330 137330

Si vous doutez encore de l’intérêt de DTrace, lancez le script ci-dessous qui compte l’ensemble des appels système pour tous les programmes de votre système :

dtrace -n 'syscall:::{ @[execname] = count(); }'
hald 71
bash 85
sshd 890
dtrace 1582
top 12083
strace 250959

Installation

DTrace est un Open Source et, à ce titre, les sources de la version Linux sont disponibles. Malheureusement, si le portage est disponible en CDDL sous la forme de modules et d’outils, quelques changements sont nécessaires et disponibles en GPL v2 avec le noyau Linux. Autrement dit, à moins que la communauté décide que ces changements puissent être intégrés dans la branche principale du noyau ou que quelqu’un de « bien barré » décide d’intégrer ces changements à d’autres noyaux que le noyau UEK, il y a peu de chance que vous puissiez un jour utiliser DTrace avec Debian, Redhat ou Suse.

Pour installer DTrace le plus simple est donc de partir d’un noyau et des binaires associés et de le faire depuis le repository ULN sur un serveur bénéficiant d’un support Premium. Et vive Oracle VM pour x86 ;-). Une fois le noyau et les outils DTrace installés, vous vous assurerez que vous pouvez charger les modules associés comme ci-dessous :

modprobe dtrace 
modprobe profile
modprobe sdt
modprobe systrace
modprobe dt_test

lsmod |grep dtrace
dtrace 117990 4 dt_test,sdt,profile,systrace
ctf 903 1 dtrace

Ce kernel est teinté comme le montre la commande ci-dessous :

cat /proc/sys/kernel/tainted
1

Outil et Langage

Expliquer le fonctionnement de DTrace est évidemment au delà de l’ambition de cet article. Retenez quelques grands principes :

  • L’utilitaire dtrace

Pour interagir avec DTrace, une fois le framework installé, vous utiliserez l’utilitaire dtrace qui permet de compiler et d’utiliser des directives mais aussi de collecter de l’information sur DTrace.

La première commande que vous utiliserez sera donc probablement dtrace -l qui liste l’ensemble des modules et fonctions disponibles avec DTrace. Malheureusement, DTrace pour Linux est encore loin de couvrir les fonctionnalités de la version Solaris pour votre plus grande frustration. Le résultat est que de nombreux scripts ne fonctionnent pas encore sur Linux.

  • Probes, predicats, built-in variables et actions

Un programme est développé avec un langage nommé « D ». DTrace est typiquement construit à p
artir de « probes », de « prédicats » et d' »actions ». Un exemple simple de ce principe est le script ci-dessous :

proc:::exec
/ execname=="bash" /
{
printf("%s -> %s(%d)n",execname,stringof(arg0),pid);
}

Ici proc:::exec fait le lien avec la ou les probes qui déclenchent l’action écrite entre accolade. Le prédicat est, quant à lui, optionnel, il est encapsulé entre deux slash (/) et indique une condition complémentaire à l’évènement. Grâce au prédicat, il est facile de ne tracer qu’un programme ou qu’un processus. Dans cet exemple, on ne déclenche l’action que si le programme qui démarre un autre processus est « bash ». Enfin l’action est constituée d’un ensemble de commandes proche du C. D restreint fortement les possibilités de programmation. Un des objectifs les plus importants est d’éviter les problèmes de pointeur. DTrace étant très proche du noyau, il s’agit absolument éviter de faire « oops ». Enfin, pour en terminer avec cet exemple, DTrace fournit un ensemble de variables dites « built-in ». Celles-ci permettent d’accéder à des informations complémentaires comme le nom d’un programme, d’un fichier ou les paramètres d’un appel. Dans ce script, on utilise les variables pré-définies execname, pid et arg0.

  • Mettre le tout en musique

Il existe littéralement des centaines de scripts pour DTrace pour vous aider à diagnostiquer/démontrer un problème ou mesurer n’importe quel fonctionnement de votre système. La communauté est très vivace notamment autour de Illumos et Delphix-OS.

Pour exécuter le programme précédent, vous pouvez au choix, le transformer en script ce qui donne :

echo >monitor_proc.d <<EOF
#!/usr/sbin/dtrace -s

#pragma D option quiet

proc:::exec
/ execname=="bash" /
{
printf("%s -> %s(%d)n",execname,stringof(arg0),pid);
}
EOF
chmod +x monitor_proc.d
./monitor_proc.d

Ou le lancer directement en ligne de commande :

dtrace -q -n 'proc:::exec{printf("%s -> %s(%d)n",execname,stringof(arg0),pid);}
  • Et bien plus encore

Evidemment, il ne s’agit là que d’une toute petite introduction, DTrace offre de nombreuses possibilités pour synthétiser les informations, s’intégrer à d’autres langages, collecter les informations dans le noyau ou les échanger entre probes et même générer un dump du kernel. Les applications sont sans limite. Lisez attentivement la documentation pour Linux et passez-y quelques heures, ou quelques jours, pour vous imprégner de ce nouvel outil pour les utilisateurs Oracle de Linux.

(SystemTap)

Le fait que DTrace soit limité aux seuls utilisateurs Oracle est une grande déception car cela signifie que l’adoption de la communauté Linux sera forcément limitée. Evidemment, il est toujours possible, puisqu’il s’agit d’un open-source, d’utiliser DTrace avec d’autres distributions mais l’effort ressemble à un petit défi (Qui cherche un sujet pour une thèse ?). Peu de gens s’y aventureront avant longtemps d’autant que même si elle est GA, la solution est loin d’être terminée.

De son côté, Redhat a développé SystemTap : autant dire qu’ils ne vont pas s’amuser à promouvoir DTrace… Pourtant, ça serait très drôle : ils rendraient à Oracle, en quelque sorte, la monnaie du clone de la distribution RHEL. Enfin, si ce n’est pas impossible c’est absolument improbable.

SystemTap, donc, d’après ses créateurs n’a rien à voir avec DTrace ! Si on peut en douter en regardant les syntaxes, ce framework est effectivement ancré bien plus profondément dans le noyau. Pour vous persuader de ce point, il suffit de dire que DTrace est largement incapable de réaliser quelque chose comme d’intercepter un SIGKILL et de l’annuler comme ce script. D’un autre côté, si être ancré plus profondément dans le noyau peut sembler intéressant, la question de l’impact d’appels synchrones à des modules incluant du code utilisateur sur un système en production est loin d’être négligeable… Autant dire qu’une étude comparative de SystemTap et de DTrace pour Linux serait d’un intérêt extrême (Qui cherche un sujet pour un mémoire ?). 

Oops

Pour finir, voici ma seconde déception ! La promesse de DTrace est que la solution peut être utilisée en production et notamment qu’elle respecte le premier principe d’un tel système qui est « don’t damage the system ». Après quelques heures de test, j’ai construit le script bogué ci-dessous :

dtrace -n syscall::write:entry'{ self->file = 0; }' 
-n syscall::write:return'{ trace(copyinstr(self->file)); }'

S’il ne fait rien de ce qu’on peut attendre, il génère en revanche de manière systématique dès que vous ayez un programme qui utilise ou on 2 fois la fonction fwrite(3) par exemple, un Oops du kernel. Autant dire que pour l’instant au moins, si vous manipulez DTrace, testez bien vos scripts avant sur un autre serveur que votre serveur de production et pensez-y à 2 fois :

Feb 22 23:05:26 dtrace kernel: Pid: 0, comm: swapper Tainted: P 2.6.39-201.0.2.el6uek.x86_64 #1
Feb 22 23:05:26 dtrace kernel: Call Trace:
Feb 22 23:05:26 dtrace kernel: <irq>[<ffffffff8106addf>] warn_slowpath_common+0x7f/0xc0
Feb 22 23:05:26 dtrace kernel: [<ffffffffa02dd040>] ? dtrace_getreg+0x130/0x130 [dtrace]
Feb 22 23:05:26 dtrace kernel: [<ffffffff8106ae3a>] warn_slowpath_null+0x1a/0x20
Feb 22 23:05:26 dtrace kernel: [<ffffffff810a585f>] smp_call_function_many+0xbf/0x260
Feb 22 23:05:26 dtrace kernel: [<ffffffff810a5a22>] smp_call_function+0x22/0x30
Feb 22 23:05:26 dtrace kernel: [<ffffffffa02dd345>] dtrace_xcall+0x35/0x40 [dtrace]
Feb 22 23:05:26 dtrace kernel: [<ffffffffa02dd36c>] dtrace_sync+0x1c/0x20 [dtrace]
Feb 22 23:05:26 dtrace kernel: [<ffffffffa02ee86c>] dtrace_state_clean+0xdc/0x150 [dtrace]
Feb 22 23:05:26 dtrace kernel: [<ffffffff8110cd50>] ? cyclic_add+0xf0/0xf0
Feb 22 23:05:26 dtrace kernel: [<ffffffff8110cd7c>] cyclic_fire_fn+0x2c/0x60
Feb 22 23:05:26 dtrace kernel: [<ffffffff81091e14>] __run_hrtimer+0x84/0x1e0
Feb 22 23:05:26 dtrace kernel: [<ffffffff81098516>] ? ktime_get_update_offsets+0x56/0xe0
Feb 22 23:05:26 dtrace kernel: [<ffffffff81092226>] hrtimer_interrupt+0xf6/0x250
Feb 22 23:05:26 dtrace kernel: [<ffffffff81511ab9>] smp_apic_timer_interrupt+0x69/0x99
Feb 22 23:05:26 dtrace kernel: [<ffffffff81510733>] apic_timer_interrupt+0x13/0x20
Feb 22 23:05:26 dtrace kernel: <eoi>[<ffffffff8101bfcd>] ? mwait_idle+0xad/0x1c0
Feb 22 23:05:26 dtrace kernel: [<ffffffff81013096>] cpu_idle+0xd6/0x120
Feb 22 23:05:26 dtrace kernel: [<ffffffff814ed035>] rest_init+0x75/0x80
Feb 22 23:05:26 dtrace kernel: [<ffffffff819eae64>] start_kernel+0x3ea/0x3f5
Feb 22 23:05:26 dtrace kernel: [<ffffffff819ea346>] x86_64_start_reservations+0x131/0x135
Feb 22 23:05:26 dtrace kernel: [<ffffffff819ea44d>] x86_64_start_kernel+0x103/0x112

Pour continuer…

Le fait qu’une première version de DTrace soit GA avec Oracle Linux est une énorme nouvelle même si elle n’est accessible qu’aux privilégiés et qu’elle est encore loin de la version Solaris ! A ce stade, personne ni dans la communauté DTrace ni dans la communauté Linux ne semble vraiment réagir. Le temps fera son œuvre.

Pour ce qui est de la suite, DTrace enrichit désormais l’éventail des outils systèmes disponibles sur Oracle Linux. Certaines situations difficiles à investiguer sont taillées pour lui comme quand, par exemple, votre base de données Oracle met du temps à s’ouvrir et que vous cherchez à comprendre ce qu’elle est en
train de faire. La suite vous appartient sans doute. En souhaitant que ce jalon soit une étape bien vite dépassées et que on puisse bénéficier de l’instrumentation des codes des infrastructures sur Linux comme sur Solaris…

2 réflexions sur “DTrace pour Oracle Linux”

Les commentaires sont fermés.