QEmu: Compilation et quelques notes

Compiler Qemu est très facile, voici néanmoins quelques notes qui peuvent servir, elles s’appliquent au moins sur la version 1.7.0. Vous pouvez télécharger les sources ici.

./configure affiche la configuration actuelle et vous pouvez voir les drapeaux à utiliser pour la modifier via ./configure –help. Voici ma configuration (support de Xen/Spice):

./configure --datadir=/usr/share --bindir=/usr/bin --enable-kvm --enable-sdl --enable-xen --enable-guest-agent --enable-virtfs --enable-docs --enable-curses --disable-bluez --target-list=x86_64-softmmu,x86_64-linux-user  --enable-spice  --enable-vhost-net --enable-xen --enable-vde --enable-glx

Je précise la version de python et désire installer qemu dans /usr/bin au lieu de /usr/local/bin parce que AppArmor bloque libvirtd quand celui-ci essayait de lancer Qemu. Et cela évite d’autres problèmes liés à Libvirt même qui a l’air un peu perdu si qemu n’est pas dans ces dossiers

Il faut alors disposer des bonnes bibliothèques (texinfo est nécessaire pour générer la documentation) autrement vous vous retrouvez avec ce type de message après le ./configure:

ERROR: User requested feature spice
configure was not able to find it 
apt-get install libvdeplug-dev libsdl1.2-dev texinfo  libspice-server-dev libspice-protocol-dev

Un make clean, make -j4 puis sudo make install devraient faire l’affaire (ajuster le -j4 selon votre nombre de coeurs).

Remarque: Quand on lance Qemu avec le paramètre -D <cheminVersLeLog>, il faut lui ajouter le paramètre -d correspondant sinon Qemu ne log aucune instruction. Cela peut surprendre :)

Convertir un domaine libvirt en son équivalent qemu

J’ai voulu tester la virtualisation à travers libvirt mais étant plus à l’aise avec qemu, il m’a fallu convertir un domaine libvirt en commande qemu. La réponse se trouve sur le site officiel mais j’ai voulu publier une version plus courte:

$ virsh domxml-to-native qemu-argv maVM.xml

Note: Il y a de grandes chances pour que vos domaines se situent dans /etc/libvirt/qemu .

La 12ième édition des Novendiales a commencé !

Bonjour à tous,

Les votes sont clos depuis vendredi soir et c’est le thème de notre nouvel adhérent Kick (une fois encore) qui a été retenu : « Old School ». Vous avez donc jusqu’à dimanche prochain (8 mars 2012) pour rendre votre jeu vidéo (réalisé seul ou en binôme). Pour plus de précisions, je vous invite à lire l’interview sur gamesphere accordée par Tof & moi-même qui résume assez bien les enjeux de ce concours de création de jeu vidéo.

Bout de code facilitant l’emploi de std::forward_list

Une fois n’est pas coutume, un article un peu technique qui vise à faciliter – pour peu que l’on ne l’utilise souvent – l’emploi du container std::forward_list du nouveau standard C++11. Ce container comble une lacune de la librairie standard, à savoir la mise à disposition d’une liste simplement chaînée limitant l’overhead et favorisant la rapidité d’exécution. On remarque ainsi que le container ne dispose pas de membres size()1.

Je ne vais présenter plus avant pourquoi utiliser ce type de container mais il peut être utile pour gérer beaucoup de munitions par exemple.

Une autre difficulté à l’utilisation est que pour supprimer un élément via sa position (et non sa valeur => linéaire) , il faut connaîre l’itérateur précédent celui qu’on veut supprimer. Outre ceci, il faut récupérer l’itérateur retourné par la fonction membre erase_after pour garder des itérateurs valides. Bref réécrire le même code à la longue devient rébarbatif d’où ce court exemple qui propose un exemple qui prend en paramètre une instance du container, une classe et une fonction membre qui retourne vrai si elle veut supprimer l’élément traité de la liste:

template<class T,class PARAM>
void loopThroughBatteries( std::forward_list<PARAM>& container, T* instance, bool (T::*fn)(PARAM) )
{

FUS_ASSERT( (instance != nullptr) && (fn != nullptr) && "You should pass a function and an instance");

 auto beginBattery( container.begin() );
 auto beforeCurrentBatteryIt( container.before_begin());
 auto lastBattery( container.end() );

 auto currentBatteryIt = beginBattery;

 while( currentBatteryIt != lastBattery )
 {
 //! quand retourne vraie on supprime
 if( (instance->*fn)( *currentBatteryIt ) ){

 currentBatteryIt = container.erase_after( beforeCurrentBatteryIt );
 }
 else {
 beforeCurrentBatteryIt = currentBatteryIt;
 currentBatteryIt++;
 }
}
}

Exemple d’utilisation:


loopThroughBatteries( _activeBatteries, this, &IFleetForwardListBased:: periodicBatteryCheck );

avec

bool
IFleetForwardListBased::periodicBatteryCheck( IStaticBattery* battery )
{

 bool stillOffscreen = getPlayState()->isEntityOufOfScreen(battery);
 battery->stillOutOfScreen( stillOffscreen );

 if( battery->getOffscreenCounter() > 3 )
 {

 battery->onTimeoutDisparition();
 _INFO << "time out death";
 return true;
 }

 return false;
}

Bon maintenant les bons diront qu’on peut faire exactement la même chose via :


_activeBatteries.remove_if( std::bind1st( std::mem_fun(&IFleetForwardListBased::periodicBatteryCheck),this) );

 

Malgré tout j’espère que cela vous aidera dans votre utilisation de std::forward_list.

 

Configuration du serveur DHCP sur IOS

Nous allons commencer par la configuration minimum avant de voir quelques astuces. Une fois connecté sur votre routeur, vous pouvez voir les associations en cours en tapant

# show ip dhcp binding

Parmi les commandes qui peuvent vous être   Le serveur DHCP fonctionne avec un système de pool. Vous allez donc devoir créer différentes « pools » selon vos besoins. Avant de commencer, il faut passer en mode configuration (via #conf t) puis entrer la commande

(config)# ip dhcp pool <nomDeMaPool>

. Si la pool n’existe pas alors le routeur en créera une nouvelle. Il faut ensuite remplir les données que le serveur DHCP va distribuer:

(dhcp-config)# default-router <IP_de_la_passerelle>
(dhcp-config)# dns-server <IP_ServeurDNS1> { <ip_des_autres_serveurs_dns> ...}
(dhcp-config)# network <IP_du_réseau> <masque>  

Je crois que les commandes sont  suffisamment explicites. Si vous voulez tester les nouveaux paramètres, vous pouvez supprimer les associations en cours:

# clear ip dhcp binding {<IP> }

Il est temps d’aborder quelques notions qui peuvent vous faciliter la vie.

Si vous avez par exemple besoin d’indiquer un serveur tftp (pour faire des démarrages PXE ou parce que vos téléphones IP ont besoin d’un serveur tftp pour télécharger leur configurations) : il suffit d’ajouter de configurer l’option DHCP correspondante dans la pool:

 (dhcp-config)# option 150 ip <IP_du_serveur_tftp>

Si vous voulez exclure une plage d’adresses IP ou même une simple adresse parce que certains de vos serveurs sont adressés statiquement, vous pouvez également le faire:

(config)# ip dhcp excluded-address <IP_basse> {<IP_Haute>}

Une astuce sympathique est également celle de pouvoir toujours attribuer la même adresse IP à un même ordinateur. Si vous êtes nomade (cad que vous vous connectez régulièrement à des réseaux différents), alors vous préférez sans doute rester en DHCP pour ne pas avoir à reconfigurer votre carte à chaque fois. Le revers de la médaille étant que vous devez vérifier via un ipconfig (ou ifconfig sous linux) quelle est votre IP à chaque fois que vous vous connecter sur le réseau. Avec l’astuce suivante, le DHCP vous attribuera toujours la même adresse. Comment fait-on ?

Vous devez créer une autre pool et ensuite associer votre MAC à une IP:

(config)# ip dhcp pool <nomDeMaNouvellePool>

(dhcp-config)# host <IPqueJeVeuxDonner>
(dhcp-config)# client-identifier <identifiant>

L’identifiant doit être donné sous la forme 01<mac> (le préfixe 01 indiquant que l’association se fait avec une MAC ethernet) avec des « . » tous les 4 caractères. Par exemple:

 (dhcp-config)# client-identifier 0100.0000.0000.01

Maintenant imaginons que l’on change de carte réseau : l’association devient invalide ! Pour y remédier, on peut choisir une « locally administered MAC » comme identifiant. Pour ce faire, il suffit d’allers dans les propriétés avancées de votre carte réseau et d’entrer la MAC que vous voulez. Idéalement le bit de « locally administered MAC » doit être mis à 1.

Quelques liens en vrac pour ceux qui aimeraient comprendre la différence entre Universally/Locally Administered MAC (tous en anglais):

Note: A noter que la plupart des <IP>  peuvent être remplacés par les noms d’hôte.