LINQ perd la mémoire

Il existe un cas d’usage où le comportement de LINQ to Entities n’est pas naturel et peut entraîner des erreurs peu faciles à détecter. La seule chose qu’on observe est que certaines conditions ne sont pas prises en compte, seule la dernière étant prise en considération.

Je vais notamment détailler le cas où l’on construit une requête LINQ (donc un SELECT en base de données) dynamiquement et surtout itérativement, c’est à dire où la requête LINQ doit être construite en utilisant une boucle. Ce genre de requête peut être très fréquente lorsqu’on réalise une recherche, ou un moteur de recherche assez souple ou à spectre large par exemple.

Voici en exemple le comportement bizazrre relatif à LINQ ; prenons le code suivant:

var myList = new int[] { 1, 2, 3, 4, 5, 6, 7 };
var query = myList.Select(l => l);
foreach (var el in new int[] { 1, 2, 3 })
{
	query = query.Where(q => q <= el);
}

En principe, on s’attend à ce que ce code soit identique à :

var myList = new int[] { 1, 2, 3, 4, 5, 6, 7 };
var query = myList.Select(l => l);
query = query.Where(q => q <= 1 && q <= 2 && q <= 3);

Or si l’on exécute les extraits de code, on observe que dans le premier extrait query renvoie un ensemble contenant 1, 2 et 3, alors qu’avec le second extrait, query renvoie un ensemble ne contenant que 1.
En réalité, le premier extrait de code est équivalent à ceci :

var myList = new int[] { 1, 2, 3, 4, 5, 6, 7 };
var query = myList.Select(l => l);
var query1 = query.Where(q => q <= 3 && q <= 3 && q <= 3);
// ce qui revient à
var query2 = query.Where(q => q <= 3);

Mais que s’est-t-il passé ?! On observe que lors de la construction d’une requête LINQ to Entities dans une boucle, la variable de boucle est considérée comme identique. C’est-à-dire que dans mon exemple, LINQ considère que el  est le même à chaque itération, ou plus exactement LINQ ajoute la condition telle quelle textuellement, et en associant à el  une valeur qui est la dernière valeur connue de el .
A la fin de la dernière itération, la requête LINQ contient donc 3 fois la même condition, (q <= el ), et y a associé pour el , sa dernière valeur, soit 3.

Ce comportement est logique lorsqu’on sait comment LINQ fonctionne en interne, mais paraît particulièrement anti-naturel la première fois qu’on rencontre ce comportement.

L’astuce pour contourner ce défaut (présent au moins dans la version 4 du .NET Framework), consiste à stocker el  dans une variable à portée locale, donc à définir une variable alpha  dans la boucle foreach  et à y affecter el . Dans ce cas, il n’y aura aucune ambiguïté sur la variable et chaque alpha  sera différent dans la requête.

Explication

Lorsqu’on construit la requête à coup d’appel successif à Where , la requête n’est pas exécutée et rien n’est évaluée, elle est construite tout comme on ferait une concaténation de chaîne.
A chaque itération, un appel à Where  génère l’expression q => q <= el (même si fonctionnellement on confond parfois les notions, cette lambda expression n’est pas un délégué ou une méthode, c’est une expression, un objet qui peut être parsé, au même titre qu’une formule mathématique peut être lu pour être interprété), où q  est une variable complètement définit puisque paramètre de l’expression, en revanche la question se pose pour el . Il faut considérer la variable comme une référence (au sens C++) vers la valeur, étant donné que el  est la variable de boucle, à chaque itération sa valeur change mais sa référence reste la même (c’est à dire que la la boite contenant la valeur ne change pas, mais la valeur dans la boite change à chaque tour de boucle).

A l’inverse, lorsqu’on déclare une variable alpha  à l’intérieur de la boucle, on s’assure que la référence de alpha  entre deux itérations est différente (puisqu’on la redéclare à chaque fois).

D’une itération à une autre, on peut alors se demander pourquoi lorsqu’on redéclare alpha , le runtime n’utilise jamais une référence précédemment affecté ? En effet on peut se dire que lorsqu’on passe à l’itération suivante, le alpha  d’avant n’est plus utilisé. C’est faux, les alpha  des itérations précédentes sont utilisés : la requête query  détient une référence vers chaque valeur prises par alpha . Du point de vue du runtime, les blocs mémoires sont donc non libre et le runtime affecte donc un autre bloc mémoire pour alpha  à chaque nouvelle itération.

Voir aussi

Réparer un ventilateur bruyant

Voici une petite astuce simple et peu chère pour donner une seconde vie aux ventilateurs asthmatiques. Il se peut même qu’il soit encore plus silencieux qu’à son tout premier ronronnement.

L’astuce n’est pas de moi, mais ça marche diablement bien ! Avant de devoir claquer 40€ dans un nouveau couple ventirad (et me retrouver avec un autre radiateur dans le placard), autant chercher au préalable si on peut le réparer, surtout si la taille du ventilateur est du genre exotique (12mm en hauteur, 100mm en largeur et longueur), donc le genre qu’on ne peut trouver en boutique, même chez le chinois.

Voici deux sources qui expliquent la manipulation :

Matériel requis

  • un ou plusieurs tournevis cruciformes pour ouvrir le PC et démonter le ventilateur
  • un tournevis plat
  • une bombe à huile ou lubrifiante, de préférence avec un prolongateur souple pour ne pas asperger tout le ventilateur, mais ce n’est pas obligatoire
  • 20 minutes maximum

ManipulationS

  1. Éteindre le PC (optionnel, mais recommandé, un court-circuit est si vite arrivé)
  2. Débrancher et démonter le ventilateur. Cela peut prendre plus ou moins de temps en fonction du ventilateur (ventilateur standard, de CPU ou de GPU). Je ne détaillerai pas ce point, ce n’est pas l’objet du billet.
  3. Prendre le ventilateur, en ayant le côté creux des pales, face à soit. On peut voir qu’un autocollant recouvre le centre du ventilateur (si ce n’est pas le cas, c’est que vous vous êtes trompé de côté)
  4. Enlever délicatement l’autocollant car il faudra le remettre, avec l’aide éventuelle d’un tournevis plat.
  5. Si le centre du ventilateur sous l’autocollant est barbouillé de colle, essayer de gratter avec le tournevis plat, ou utiliser de l’acétone en évitant d’arroser les circuits électroniques s’il y en a.
  6. Enlever le capuchon au centre du ventilateur (le capuchon peut être en caoutchouc ou transparent).
  7. Injecter au centre un peu d’huile.
  8. Nettoyer la surface qui est au contact de l’autocollant si elle a été aspergée d’huile (un jet suffit, il n’est pas nécessaire de noyer le moteur), sinon plus rien ne collera dessus.
  9. Remettre le capuchon, puis l’autocollant.
  10. Remonter puis rebrancher le ventilateur.
  11. done 😉

Retour d’expérience

L’astuce a bien fonctionné, j’ai retrouvé mes ventilateurs silencieux, en revanche cela n’a pas duré très longtemps, pas plus de 2 mois :/

Débugger un flux SSL

Aujourd’hui, ça fera quelques jours que je m’arrache les cheveux à connecter Outlook à Exchange, mais uniquement en ouvrant le port HTTP/HTTPS. Pas le port RPC (tcp 135) car il s’agit de l’interface publique du serveur Exchange, et qu’en plus d’éviter des tentatives de hack par ce port, je n’ai pas eu envie d’ouvrir non plus la tripoté de ports dynamiques qui va avec.

J’ai résolu enfin mon problème, mais durant ma recherche, je suis tombé sur une perle, vraiment, incluse dans Wireshark.
Pour rappel, Wireshark est un outil d’analyse de paquets ; ça capte tout packet réseau et l’affiche sous une forme intelligible, pourvu que le protocole soit dans sa liste, qui est très bien fournie.

L’un de ces protocols, c’est le SSL. Et en regardant sa configuration, on peut observer une boite de dialogue permettant de stocker une liste… de clés privés. Qui n’a jamais eu besoin, au moins une fois dans sa vie, de débugger un flux SSL ? Et bien c’est possible avec Wireshark, si l’on possède la clé privée du serveur SSL.

Typiquement débugger un flux SSL entre un client qu’on a pas développé, disons Outlook, et un serveur qu’on a pas développé non plus, disons Exchange, donc dans le cas  »très improbable » où il est impossible de logguer le flux avant qu’il soit crypté ou après qu’il soit décrypté.

rsa1 rsa2

 

Voir aussi

Construction d’une chaîne de compilation pour Android

Il existe plusieurs méthodes pour avoir une chaîne de compilation pour le système Android. Mais pourquoi une toolchain ? Android est un système d’exploitation basé sur le noyau Linux et dédié aux processeurs de type ARM (actuellement, c’est le cas). Il ne s’agit donc pas de processeurs « classiques » de type x86 ou ia64, et par conséquent, les chaînes de compilation fournies avec les distributions Linux ne sont pas adaptées, car elles ne peuvent générer que du code x86 ou ia64…

Avertissement : Pour l’instant, j’ai réussi à compiler un kernel qui boot, mais j’ai perdu la radio, j’ai seulement le wifi.
Cet article est donc présent surtout à des fins théoriques ou pour les plus persévérant à commencer les bidouilles de bas niveau :p.

Quelques chaînes de compilation pour architecture arm

  • Gentoo, avec son paquet crossdev. Actuellement non fonctionnel chez moi.
  • la chaîne de compilation pré-compilé fourni par le SDK d’Android. Actuellement non fonctionnel chez moi.
  • la chaîne de compilation fournie par crosstool-ng. La plus configurable, la plus chiante à mettre en place, mais la seule qui a marché.

Il est possible que les autres chaînes de compilation marchent parfaitement bien, j’ai juste du louper un truc sur les paramètres à passer… c’est dire que contrairement au monde x86, des architectures ARM, il y en a à la pelle et pas souvent compatibles entre elles (pas sans recompilation).

Cette article détaillera uniquement la dernière chaîne de compilation, qui a l’avantage d’avoir beaucoup de paramètres que l’on peut utiliser pour optimiser sa chaîne.

Les étapes décrites ci-dessous s’appliquent à Gentoo, mais peuvent s’appliquer à n’importe quel UNIX-like avec quelques modifications mineures.

# si ce n'est pas déjà fait, on installe git
emerge -v git

# récupération du kernel cyanogen
export KERNELDIR=/home/kernel-cyanogen
export CROSSTOOLDIR=/home/crosstool-ng
mkdir -p $KERNELDIR
cd $KERNELDIR
#git clone git://github.com/CyanogenMod/cm-kernel.git
# pour certains appareils htc dont le vision, un autre repo est utilisé
git clone git://github.com/CyanogenMod/htc-kernel-msm7x30.git
# aller boire un café, ça va prendre 10bonnes minutes...
#cd cm-kernel
cd htc-kernel-msm7x30
make headers_install ARCH=arm INSTALL_HDR_PATH=../kern_h/

# construction de la toolchain
echo 'sys-devel/ct-ng' >> /etc/portage/package.keywords
emerge -va ct-ng
eselect bashcomp enable ct-ng --global
mkdir -p $CROSSTOOLDIR
cd $CROSSTOOLDIR
# placez le fichier uClibc.config ici, depuis l'archive à télécharger
#mv XVilka-uClibc-msm7200a.config uClibc.config
ct-ng menuconfig

Ci-dessous les changements à effectuer pour le menuconfig de crosstool-ng

Paths and misc options --->
(1) Number of parallel jobs
Target options --->
Target Architecture (arm)
(armv7-a) Architecture level
(cortex-a8) Emit assembly for CPU
(vfpv3) Use specific FPU
(-O2) Target CFLAGS
Toolchain options --->
(android) Tuple's vendor string
Operating System --->
Target OS (linux)
Linux kernel version (2.6.37.6) // à adapter en fonction de la version du kernel du cyanogenmod
C compiler --->
[*] C++
[*] Java
C-library --->
C library (uClibc)
(uClibc.config) Configuration file
Threading implementation to use: (linuxthreads)

Et on retourne à la ligne de commande…

ct-ng build
# là on reprend une tasse de café

# récupération des sources du cyanogenmod
export CYANODIR=/home/cyanogen
cd $CYANODIR
repo sync
make adb
export PATH=/out/host/linux-x86/bin:$PATH

# compilation d'un nouveau kernel
export _XXCFLAGS=" -march=armv7-a -mtune=cortex-a8 -mfpu-abi=softfp -mfpu=vfpv3 -O2"
export PATH=~/x-tools/arm-android-linux-uclibcgnueabi/bin:$PATH
export CCOMPILER=~/x-tools/arm-android-linux-uclibcgnueabi/bin/arm-android-linux-uclibcgnueabi-
cd $KERNELDIR/htc-kernel-msm7x30
# branchez le téléphone au pc
adb pull /proc/config.gz .
zcat config.gz > .config
# menuconfig pour changer deux ou trois choses avant de compiler (à faire avec beaucoup de précautions)
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER menuconfig
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER oldconfig
CFLAGS=$_XXCFLAGS make ARCH=arm CROSS_COMPILE=$CCOMPILER -j`grep 'processor' /proc/cpuinfo | wc -l` all
cd $CYANODIR/device/htc/vision
mv kernel kernel.bak
mv modules/bcm4329.ko modules/bcm4329.ko.bak
ln -s $KERNELDIR/htc-kernel-msm7x30/arch/arm/boot/zImage kernel
ln -s $KERNELDIR/htc-kernel-msm7x30/drivers/net/wireless/bcm4329/bcm4329.ko modules/
cd $CYANODIR
. build/envsetup.sh && brunch cyanogen_vision-eng

Et voilà, plus qu’à flasher.

Tous les crédits vont à XVilka, pour avoir décrit sa méthode pour le milestone.

Voir aussi

Personnaliser le WebDeploy

WebDeploy est un outil dans Visual Studio permettant de compiler puis déployer un projet web sur un serveur IIS. Il est très simple d’usage mais… la personnalisation est inexistante.

Compte tenu de la complexité du processus de build des projets .NET et de la qualité de la documentation fournit, ça n’a pas été évident mais j’ai pu finalement cracher ce bout de XML. Il est à ajouter dans le fichier csproj du projet web à la fin.

Voici ce qu’il fait :

  1. On renseigne en paramètre l’exécutable signtool, qui permet de signer numériquement un fichier PE (ça correspond à l’onglet « Signatures numériques » dans les propriétés d’un fichier signé
  2. On renseigne le certificat à utiliser par sa somme de contrôle SHA1
  3. On indique avec un nom de variable particulier le fichier snk contenant les clés pour ajouter un nom fort aux assemblies. Les variables sont KeyOriginatorFile  et _FullKeyFile  et sont reconnus par le processus de compilation.
  4. Après la compilation normale du projet, on signe le fichier *.dll  et les fichiers *.ressources.dll généré par le projet web
  5. Après l’étape 4, on lance la cible MvcBuildViews qui va compiler toutes les vues dans une assembly qui se nomme {nom du projet web}.WebUI.dll. Une fois que c’est fait, on signe également la nouvelle assembly et ses ressources.
  6. Le processus normal reprend et pousser le résultat sur le serveur IIS
<PropertyGroup Condition="Exists('C:\Users\veovis')">
 <Sha1Thumbnail>6b30be2f5fd6cb22225191b803c9232755dc07b8</Sha1Thumbnail>
 <SignAssembly>true</SignAssembly>
 <SignToolLocation>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe</SignToolLocation>
 <AssemblyOriginatorKeyFile>C:\Users\sebastien\Documents\Security\euphor.snk</AssemblyOriginatorKeyFile>
 <_FullKeyFile>$(AssemblyOriginatorKeyFile)</_FullKeyFile>
 <KeyOriginatorFile>$(AssemblyOriginatorKeyFile)</KeyOriginatorFile>
 <DelaySign>false</DelaySign>
 <OnAfterCopyAllFilesToSingleFolderForPackage>
MvcBuildViews;
 </OnAfterCopyAllFilesToSingleFolderForPackage>
</PropertyGroup>
<Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release' And '$(SignToolLocation)' != ''">
 <ItemGroup>
 <OutputFiles Include="$(TargetPath)"/>
 <OutputFiles Include="$(TargetDir)\*\$(TargetFileName).resources.dll" />
 </ItemGroup>
 <Exec Command="&quot;$(SignToolLocation)&quot; sign /sha1 $(Sha1Thumbnail) /tr &quot;http://www.startssl.com/timestamp&quot; /ph &quot;%(OutputFiles.FullPath)&quot;" />
</Target>
<Target Name="MvcBuildViews">
 <RemoveDir Directories="$(_PackageTempDir)2" />
 <AspNetCompiler VirtualPath="temp" PhysicalPath="$(_PackageTempDir)" Force="true" Updateable="false" FixedNames="true" TargetPath="$(_PackageTempDir)2" />
 <AspNetMerge ExePath="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools" Nologo="true" SingleAssemblyName="$(TargetName).WebUI" ApplicationPath="$(_PackageTempDir)2" CopyAttributes="true" AssemblyInfo="$(TargetPath)" KeyFile="$(_FullKeyFile)" />
 <ItemGroup>
 <DllFiles Include="$(_PackageTempDir)2\bin\$(TargetName).WebUI.dll" />
 <DllFiles Include="$(_PackageTempDir)2\bin\*\$(TargetName).WebUI.resources.dll" />
 </ItemGroup>
 <Exec Command="&quot;$(SignToolLocation)&quot; sign /sha1 $(Sha1Thumbnail) /tr &quot;http://www.startssl.com/timestamp&quot; /ph &quot;%(DllFiles.FullPath)&quot;" />
 <RemoveDir Directories="$(_PackageTempDir)" />
 <Exec Command="rename &quot;$(_PackageTempDir)2&quot; &quot;PackageTmp&quot;" />
</Target>

Toutes ces étapes ne sont évidemment pas obligatoires et ce fichier DOIT être personnalisé en fonction de son environnement.

Configuration robuste d’un serveur SSL

En visitant le site cacert.org, notamment pour voir où en était leur intégration dans les différents systèmes d’exploitation et navigateurs, je suis tombé sur Qualys SSL Server Test un site permettant de scanner la partie SSL d’un site web.

Je passe le test pour mon blog, on va voir ce que ça donne…
Pour note, mon blog est desservi par nginx, lui-même linké à openssl pour tous se qui se rapport au chiffrage.
C’est long… et surprise, je décroche un F ! Bravo, je ne peux pas faire pire !

Analysons le résultat :

  • tout d’abord, mon certificat est trusted, mais il semble qu’il y ait un problème sur la chaîne de certification. Une petite vérification m’a permis de confirmer qu’effectivement le serveur ne contient que le certificat du site et le certificat racine, en oubliant le certificat intermédiaire (chaîne de 3 certificats). Qu’à cela ne tienne, une petite concaténation m’a permis de corriger ce soucis. Le problème que ça aurait pu engendrer est qu’un navigateur qui n’a jamais visité un site certifié par Start SSL (qui est l’entité émettrice de mon certificat) aurait jugé que le certificat n’est pas valide, puisqu’il n’arrive pas à remonter de mon certificat à un des certificats racines du navigateur, vu qu’il lui manque le fameux certificat intermédiaire que je n’ai pas présenté.
  • second problème, j’ai des algorithmes de chiffrages qui sont considéré insecure. oups ? J’avais pourtant bien restreint les algorithmes à HIGH:-DES pourtant ! Il se trouve après avoir trouvé le dénominateur commun aux algorithmes non secure que le coupable est anonymous DH, ou bien ADH. Je change donc dans nginx la liste des algorithmes autorisés à HIGH:-DES:ADH  et je repasse le test… avec succès 🙂 Dans les sources, j’ai pu trouver un lien expliquant de façon succincte pourquoi cette famille d’algorithmes n’est pas sûre : du fait que le Diffie-Hellman est effectué en clair (anonymous), l’échange de clé reste secret (cela est assuré par le procédé Diffie-Hellman), mais n’empêche pas une attaque du milieu, à savoir un agent positionné entre deux participants et qui intercepterait les échanges des deux participant pour proposer ses propres paramètres Diffie-Hellman ; le procédé Diffie-Hellman a été bien réalisé… mais pas avec la bonne personne !
  • dernier problème, mineur celui-là, l’incapacité à renégocier une session chiffrée. Une petite ligne de configuration à rajouter, plus difficile à trouver cependant. Corrigé, je repasse le test, et cette fois, tout est vert, j’ai un A 🙂

Pour résumer, voici à quoi ressemble la configuration SSL dans le fichier de configuration de nginx :

ssl_ciphers HIGH:-DES:-ADH;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 SSLv3;
ssl_session_cache shared:SSL:1m;

Pour comparer, j’ai balancé le test sur un serveur sous Windows Server 2003, et un autre sous Windows Server 2008 R2, tous deux avec les configurations par défaut.
L’un est catastrophique, l’autre est parfait, plus parfait même que mon nginx tuné, notamment par le support du protocol TLS 1.2.
Il est dommage toutefois de constater le faible choix disponible dans la liste des algorithmes proposés sous Windows Server 2003.
Je vais essayer de désactiver SSLv2 sous Windows Server 2003 et voir ce que cela donne…

Bien que les notes fournies par Qualys puissent paraître sévères en rapport avec le monde réel (qui utilise encore ADH parmi les navigateurs modernes ?), reconfigurer proprement la partie ssl d’un serveur ne mange pas de pain (mis à part le cas IIS où la configuration est on ne peut plus restreinte), alors go on !

Voir aussi

Impact de la virtualisation sur les performances brutes

Sur les serveurs dédiés sous ma responsabilité, il m’arrive d’y installer un client BOINC. C’est un logiciel qui rapatrie, pour divers projets scientifiques, du travail à effectuer par la machine, laquelle fait alors partie d’une grille de calcul. Bien entendu, BOINC ne travaille que lorsque le serveur ne fait rien, ou plutôt utilise les cœurs non utilisés des CPUs des serveurs. Il n’est pas question que les services en production souffrent de la présence de BOINC. Sous ces conditions, pourquoi pas, ça permet d’utiliser les ressources non utilisées pour une bonne cause, on évite le gâchis.
Ce programme m’a permis de comparer la puissance de calcul brute de plusieurs configuration, sachant que tous les clients BOINC sont configurés pour travailler sur le même projet. En particulier, il y avait deux machines identiques en RAM (non saturées) et en CPU, un Core i5.

L’une de ces machines était sous VMware ESXi avec une seule VM sous Windows Server 2003, l’autre était directement sous Windows Server 2008 R2.
La configuration CPU/RAM identique m’a permis de comparer quantitativement la perte de performance induite par la couche ESXi simplement en regardant le score de BOINC par client.
J’avais entendu parler au cours d’une conférence d’évangélisation que la perte induite par des outils de virtualisation comme VMware Workstation ou Hyper-V R1 était de 15%, tandis que celle de ESXi était seulement de 5%, grâce à son noyau super léger, mais qu’en est-il réellement ?
Pour ce qui est de Workstation, j’en ai aucune idée, je m’en sers que pour le développement donc pas en continue. En revanche on voit une différence de… 15% de entre l’utilisation ou non de VMware ESXi. Wow ! ce n’est pas rien !

On m’aurait menti ? J’ai attendu plusieurs jours pour que le score quotidien des clients BOINC se stabilise et on note toujours cette nette différence de 15%, quelque soit le travail effectué (mais toujours sur le même projet). Il est à noter également que concernant ces deux serveurs, ils ne faisaient quasiment que de l’idle, donc normalement pas perturbés par d’autres processus. C’est un test approximatif et il vaut ce qu’il vaut, mais a l’avantage de donner une assez bonne précision de ce qu’on perd en CPU brut avec cette couche de virtualisation.

Pour autant, la virtualisation n’est pas à jeter, ça dépend de l’utilisation de la machine. Pour mon cas où le CPU est loin d’être le goulet d’étranglement sur ces machines, surtout un Core i5, cette perte est significative, mais acceptable.

Copier/Coller avec vSphere ESXi

Ça fait quelques années maintenant que je suis adepte d’outils de virtualisation, que ça soit les solutions de VMware (Workstation et Server) ou VirtualBox, donc principalement à des fins de tests sur ma bécane de travail. Bref le but de ce billet n’est pas de les comparer, de toute manière je les ais tous utilisé et chacun ses avantages et défauts.

Depuis peu, je me suis dit, et pourquoi pas ESXi ? Il faut savoir que VMware Workstatation ou VirtualBox, il n’y a pas mieux pour tester un programme, avoir un autre OS etc… mais ça te flingue pas mal les ressources alors que dans le cas de ESXi, on parle non pas de logiciel mais de système d’exploitation, du coup la perte en ressources dû à la virtualisation est minime.

En langage technique, on dit que ESXi est un hyperviseur de type 1, alors que VMware Workstation et VirtualBox sont des hyperviseurs de type 2. Le type 1 EST un OS et a donc un accès direct au matériel, alors que le type 2 repose sur un OS et doit donc passer par lui pour avoir accès aux ressources matériel, d’où la perte de performance plus importante dans le cas de ces hyperviseurs.

J’ai pu donc mettre en œuvre ESXi sur un dédié pour un client. La livraison est nickel, ça marche plutôt bien, quoique je trouve le client vSphere un peu lent, comme s’il s’agissait d’une page web… C’est peut-être le cas, je n’en sais rien.
L’autre point négatif est que le serveur pris ne disposait pas de RAID hard (bah oui ça coûte plutôt cher), et que ESXi ne supporte pas le RAD-soft. Tant pis, mais de toute façon je savais dans quoi je m’engageais.

J’utilise donc la console de vSphere client pour installer l’OS client (au passage, c’est toujours très agréable de charger un DVD à la vitesse des 100Mbps garantis par l’hébergeur). Rien à signaler de ce côté, jusqu’à ce que j’aborde la configuration de l’OS invité. Tiens bizarre, le copier/coller ne marche pas…

Bah non il ne marche pas. Mon poste n’est pas en cause, c’est la faute à vSphere Client. En effet depuis la version 4.1, donc la dernière au moment où je rédige ce billet, cette fonctionnalité est désactivé par défaut, sécurité oblige. Zut alors !

Voici donc la manip à effectuer pour réactiver cette fonctionnalité très pratique :

  1. Éteindre la machine virtuelle concernée
  2. Éditer les paramètres de la machine virtuelle
  3. Aller à Options > Advanced > General puis cliquer sur Configuration Parameters (vu que l’interface graphique ne le permet pas)
  4. Cliquer sur Add Row et ajouter ces deux paramètres :
    1. isolation.tools.copy.disable  avec la valeur false
    2. isolation.tools.paste.disable  avec la valeur false
  5. Valider le tout. Voilà on peut redémarrer la VM, le copier/coller fonctionne à nouveau.

Il est possible de faire cette modification directement depuis le shell SSH en éditant le fichier vmx dans le datastore.
Vu que c’est beaucoup moins pratique et sale, je n’ai pas détaillé cette technique, le shell de ESXi n’étant pas extrêmement bien fourni.

Voir aussi

Importer des certificats d’autorité racine dans Android 2.x

Comme d’habitude comme tout ce qui concerne une manip sous Android nécéssitant l’accès root, je fourni ce tutoriel sans aucune garantie contre la casse ni la bêtise. A vos risques et périls donc.

Il peut arriver de se monter sa propre PKI (pourquoi pas), et de l’utiliser à tout va pour crypter les échanges entre son mobile et ses sites web (les urls qui commencent par https://), ou son serveur de mails perso (pour utiliser pleinement TLS ou le SSL implicite). Bref, pour tous ceux qui voudraient ajouter un certificat d’autorité racine dans leur téléphone Android pour valider tout ce qu’il y a à valider, voici la marche à suivre.

Tout d’abord le matériel requis pour la manipulation :

# on récupère le magasin de certificats depuis son téléphone vers son PC, c’est là que l’ADB devient utile :

adb root
# extract certificates store on the computer
adb pull /system/etc/security/cacerts.bks cacerts.bks
# import mon-ca.crt to the store
keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -importcert -trustcacerts -alias MON-CA -file mon-ca.crt
# type "yes" to confirm the import of the new ca cert
# remount android /system as read-write
adb shell mount -o remount,rw /system
# push the new store
adb push cacerts.bks /system/etc/security
# remoube android /system as read-only
adb shell mount -o remount,ro /system
# done ;)

Plus qu’à redémarrer le téléphone pour qu’il prenne le nouveau CA en compte.

GPU vs CPU

Ça fait un petit moment que je participe au programme BOINC. Pour résumer, ce programme permet de partager les ressources inutilisées de son PC pour divers projets scientifiques. Les scientifiques sont pauvres, c’est bien connu en France, et moi je n’éteins pas souvent mes PC (surtout les serveurs), alors autant qu’ils profitent de mes CPUs pour leurs besoins (pis c’est pas moi qui paye la facture EDF alors :-D).

Récemment, j’ai pu mettre BOINC sur un poste bénéficiant de CUDA, la technologie de GPGPU de nVidia. Ben ya pas à dire, les GPU sont clairement sous-utilisés en dehors des jeux !

Voici une capture d’écran montrant une note qualifiant la rapidité de calcul sur deux projets :

  • GPUGRID est un projet utilisant mon GPU, un nVidia 9800GT
  • Milkyway@home est un projet utilisant les deux cœurs de mon CPU, un Core 2 Duo E7300

boinc cpu vs gpu
Le GPU est plus que 10x plus rapide que les CPUs ! Reste plus qu’à ce que OpenCL se démocratise davantage, pour que tous puissent utiliser simplement la puissance GPU sans dépendre du matériel.