Il s'agit de la commande guestfs-internals qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos multiples postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS
PROGRAMME:
Nom
guestfs-internals - architecture et composants internes de libguestfs
DESCRIPTION
Cette page de manuel est destinée aux pirates qui souhaitent comprendre le fonctionnement interne de libguestfs.
Ceci est juste une description de la façon dont libguestfs fonctionne maintenant, et cela peut changer à tout moment dans
l'avenir.
ARCHITECTURE
En interne, libguestfs est implémenté en exécutant une appliance (un type spécial de petit
machine virtuelle) en utilisant qemu(1). Qemu s'exécute en tant que processus enfant du programme principal.
??
programme principal │
│
│ │ processus enfant/appliance
│ ┌──────────────────────────┐
│ │ qemu │
RPC │ ┌─────────────────┐ │
libguestfs guestfsd │ │
│ │ ├─────────────────┤ │
└───────────────────┘ │ │ Noyau Linux │ │
└────────┬────────┘ │
??
│
virtio-scsi
??
│ Appareil ou │
image disque │
??
La bibliothèque, liée au programme principal, crée le processus fils et donc l'appliance
dans la fonction "guestfs_launch".
À l'intérieur de l'appliance se trouve un noyau Linux et une pile complète d'outils d'espace utilisateur (tels que
LVM et ext2) et un petit démon de contrôle appelé "guestfsd". La bibliothèque
parle à "guestfsd" à l'aide d'appels de procédure à distance (RPC). Il y a surtout un tête-à-tête
correspondance entre les appels API libguestfs et les appels RPC au démon. Enfin le disque
les images sont attachées au processus qemu qui traduit l'accès au périphérique par le
noyau Linux de l'appliance en accès à l'image.
Un malentendu courant est que l'appliance « est » la machine virtuelle. Bien que le
l'image disque à laquelle vous êtes attaché peut également être utilisée par une machine virtuelle, libguestfs
ne sait pas ou ne s'en soucie pas. (Mais vous vous soucierez si le processus qemu de libguestfs et
votre machine virtuelle essaie de mettre à jour l'image disque en même temps, car ces
entraîne généralement une corruption massive du disque).
ETAT APPRENTISSAGE
libguestfs utilise une machine à états pour modéliser le processus enfant :
|
invitéfs_create / invitéfs_create_flags
|
|
____V_____
/ \
| CONFIGURER |
\_________/
^ ^ \
| \ \ invitéfs_lancement
| __V______
| /\
| | LANCEMENT |
| \___________/
| /
| invitéfs_lancement
| /
_|____V
/ \
| PRÊT |
\________/
Les transitions normales sont (1) CONFIG (lorsque le handle est créé, mais il n'y a pas d'enfant
processus), (2) LANCEMENT (lorsque le processus fils démarre), (3) READY signifiant le
l'appliance est opérationnelle, des actions peuvent être envoyées au processus enfant et exécutées par celui-ci.
L'invité peut être tué par "guestfs_kill_subprocess", ou peut mourir de manière asynchrone à n'importe quel
temps (par exemple en raison d'une erreur interne), et qui provoque la transition de l'état à
CONFIG.
Les commandes de configuration pour qemu telles que "guestfs_set_path" ne peuvent être émises que dans le
état CONFIG.
L'API propose un appel qui va de CONFIG à LAUNCHING à READY.
"guestfs_launch" bloque jusqu'à ce que le processus enfant soit PRÊT à accepter des commandes (ou jusqu'à ce que certains
panne ou temporisation). "guestfs_launch" déplace en interne l'état de CONFIG à LAUNCHING
pendant qu'il est en marche.
Les actions d'API telles que "guestfs_mount" ne peuvent être émises que lorsqu'elles sont à l'état READY. Ces API
blocage des appels en attente de l'exécution de la commande. Il n'y a pas de non bloquant
versions, et aucun moyen d'émettre plus d'une commande par handle en même temps.
Enfin, le processus fils renvoie des messages asynchrones au programme principal, tels que
messages du journal du noyau. Vous pouvez enregistrer un rappel pour recevoir ces messages.
INTERNES
APPAREIL BOOT PROCESSUS
Ce processus a évolué et continue d'évoluer. La description ici correspond seulement
à la version actuelle de libguestfs et est fourni à titre d'information uniquement.
Afin de suivre les étapes impliquées ci-dessous, activez le débogage de libguestfs (définissez le
variable d'environnement "LIBGUESTFS_DEBUG=1").
Créer l'appliance
"supermin --build" est invoqué pour créer le noyau, un petit initrd et l'appliance.
L'appliance est mise en cache dans /var/tmp/.guestfs- (ou dans un autre répertoire si
"LIBGUESTFS_CACHEDIR" ou "TMPDIR" sont définis).
Pour une description complète de la façon dont l'appliance est créée et mise en cache, lisez le
supermine(1) page de manuel.
Démarrez qemu et démarrez le noyau
qemu est invoqué pour démarrer le noyau.
Exécuter l'initrd
"supermin --build" construit un petit initrd. L'initrd n'est pas l'appliance. Les
le but de l'initrd est de charger suffisamment de modules du noyau pour que l'appliance
lui-même peut être monté et démarré.
L'initrd est une archive cpio appelée /var/tmp/.guestfs- /appliance.d/initrd.
Lorsque l'initrd a démarré, vous verrez des messages indiquant que les modules du noyau sont
en cours de chargement, semblable à ceci :
supermin : démarrage du mini initrd ext2
supermin : montage / sys
supermin : insmod interne libcrc32c.ko
supermin : insmod interne crc32c-intel.ko
Trouver et monter l'appareil de l'appareil
L'appliance est un fichier fragmenté contenant un système de fichiers ext2 qui contient un fichier familier
(bien que de taille réduite) système d'exploitation Linux. Il s'appellerait normalement
/var/tmp/.guestfs- /appliance.d/root.
Les disques réguliers inspectés par libguestfs sont les premiers périphériques exposés par qemu
(par exemple comme /dev/vda).
Le dernier disque ajouté à qemu est l'appliance elle-même (par ex. /dev/vdb s'il n'y avait que
un disque normal).
Ainsi, la tâche finale de l'initrd consiste à localiser le disque de l'appliance, à le monter et à basculer
root dans l'appliance et exécutez /init de l'appareil.
Si cela fonctionne avec succès, vous verrez des messages tels que :
supermin : a choisi /sys/block/vdb/dev comme périphérique racine
supermin : création de /dev/root en tant que bloc spécial 252:16
supermin : montage d'une nouvelle racine sur / Root
supermin : chroot
Démarrage du script /init...
Notez que "Starting /init script ..." indique que le script d'initialisation de l'appliance est
maintenant en cours d'exécution.
Initialiser l'appliance
L'appliance elle-même s'initialise maintenant. Cela implique de démarrer certains processus
comme "udev", en imprimant éventuellement des informations de débogage, et enfin en exécutant le démon
("guestfsd").
Le démon
Enfin, le démon ("guestfsd") s'exécute à l'intérieur de l'appliance. S'il s'exécute, vous devriez voir :
démon verbeux activé
Le démon s'attend à voir un port virtio-série nommé exposé par qemu et connecté sur
l'autre extrémité à la bibliothèque.
Le démon se connecte à ce port (et donc à la bibliothèque) et envoie un quatre octets
message "GUESTFS_LAUNCH_FLAG", qui initie le protocole de communication (voir ci-dessous).
COMMUNICATION PROTOCOLE
Ne comptez pas sur l'utilisation directe de ce protocole. Cette section documente comment il est actuellement
fonctionne, mais il peut changer à tout moment.
Le protocole utilisé pour communiquer entre la bibliothèque et le démon exécuté à l'intérieur du qemu
la machine virtuelle est un mécanisme RPC simple construit sur XDR (RFC 1014, RFC 1832, RFC
4506).
Le format détaillé des structures est en src/guestfs_protocol.x (remarque : ce fichier est
généré automatiquement).
Il existe deux grands cas, des fonctions ordinaires qui n'ont pas de "FileIn" et "FileOut"
paramètres, qui sont traités avec des messages de demande/réponse très simples. Ensuite, il y a
fonctions qui ont des paramètres "FileIn" ou "FileOut", qui utilisent la même requête et
des messages de réponse, mais ils peuvent également être suivis de fichiers envoyés à l'aide d'un codage fragmenté.
ORDINAIRE FONCTIONS (Je n'ai pas FICHIER/FILEOUT PARAMÈTRES)
Pour les fonctions ordinaires, le message de requête est :
longueur totale (en-tête + arguments,
mais sans inclure la longueur du mot lui-même)
struct guestfs_message_header (encodé en XDR)
struct guestfs_ _args (encodé en XDR)
Le champ de longueur totale permet au démon d'allouer un tampon de taille fixe dans lequel il
avale le reste du message. Par conséquent, la longueur totale est limitée à
"GUESTFS_MESSAGE_MAX" octets (actuellement 4 Mo), ce qui signifie la taille effective de toute requête
est limité à quelque part en dessous de cette taille.
Notez également que de nombreuses fonctions ne prennent aucun argument, auquel cas le
"guestfs_foo_args" est complètement omis.
L'en-tête contient le numéro de procédure ("guestfs_proc") qui est la façon dont le récepteur sait
à quel type de structure args s'attendre, ou pas du tout.
Pour les fonctions qui prennent des arguments facultatifs, les arguments facultatifs sont codés dans le
"guestfs_foo_args" structure de la même manière que les arguments ordinaires. Un masque de bits dans le
l'en-tête indique quels arguments facultatifs sont significatifs. Le masque de bits est également vérifié pour
voir s'il contient des bits définis que le démon ne connaît pas (par exemple, si plus facultatif
arguments ont été ajoutés dans une version ultérieure de la bibliothèque), ce qui provoque l'appel à être
rejeté.
Le message de réponse pour les fonctions ordinaires est :
longueur totale (tête + ret,
mais sans inclure la longueur du mot lui-même)
struct guestfs_message_header (encodé en XDR)
struct guestfs_ _ret (encodé en XDR)
Comme ci-dessus le "guestfs_foo_ret" la structure peut être complètement omise pour les fonctions qui
ne renvoie aucune valeur de retour formelle.
Comme ci-dessus, la longueur totale de la réponse est limitée à "GUESTFS_MESSAGE_MAX".
En cas d'erreur, un indicateur est placé dans l'en-tête et le message de réponse est légèrement
modifié:
longueur totale (en-tête + erreur,
mais sans inclure la longueur du mot lui-même)
struct guestfs_message_header (encodé en XDR)
struct guestfs_message_error (encodé en XDR)
La structure "guestfs_message_error" contient le message d'erreur sous forme de chaîne.
FONCTIONS QUE " MUST HAVE " DOSSIER PARAMETRES
Un paramètre "FileIn" indique que nous transférons un fichier développement l'invité. La demande normale
message est envoyé (voir ci-dessus). Cependant, ceci est suivi d'une séquence de morceaux de fichiers.
longueur totale (en-tête + arguments,
mais sans compter la longueur du mot lui-même,
et sans compter les morceaux)
struct guestfs_message_header (encodé en XDR)
struct guestfs_ _args (encodé en XDR)
séquence de morceaux pour FileIn param #0
séquence de morceaux pour FileIn param #1 etc.
La « séquence de morceaux » est :
longueur du morceau (sans compter la longueur du mot lui-même)
struct guestfs_chunk (encodé en XDR)
longueur de morceau
struct guestfs_chunk (encodé en XDR)
longueur de morceau
struct guestfs_chunk (avec data.data_len == 0)
Le dernier morceau a le champ "data_len" mis à zéro. De plus, un indicateur est placé dans le
morceau final pour indiquer la réussite ou l'annulation anticipée.
Au moment de la rédaction de cet article, aucune fonction n'a plus d'un paramètre FileIn.
Cependant, cela est (théoriquement) pris en charge, en envoyant la séquence de morceaux pour chaque
FileIn paramètre l'un après l'autre (de gauche à droite).
Tant la bibliothèque (expéditeur) et le démon (récepteur) peut annuler le transfert. La bibliothèque
le fait en envoyant un morceau avec un indicateur spécial défini pour indiquer l'annulation. Quand le
le démon voit cela, il annule tout le RPC, ne pas envoyer une réponse, et retourne à
lecture de la demande suivante.
Le démon peut également annuler. Il le fait en écrivant un mot spécial "GUESTFS_CANCEL_FLAG"
à la prise. La bibliothèque écoute cela pendant le transfert, et si elle l'obtient, elle
annulera le transfert (il envoie un morceau d'annulation). Le mot spécial est choisi pour que
même si l'annulation intervient juste à la fin du transfert (après que la bibliothèque a
fini d'écrire et a commencé à écouter la réponse), le drapeau d'annulation "faux"
ne pas confondre avec le message de réponse.
Ce protocole permet le transfert de fichiers de taille arbitraire (pas de limite de 32 bits), et aussi
fichiers dont la taille n'est pas connue à l'avance (par exemple à partir de tuyaux ou de sockets). Cependant, le
les morceaux sont plutôt petits ("GUESTFS_MAX_CHUNK_SIZE"), de sorte que ni la bibliothèque ni le
démon doit garder beaucoup en mémoire.
FONCTIONS QUE " MUST HAVE " FILE-OUT PARAMETRES
Le protocole pour les paramètres FileOut est exactement le même que pour les paramètres FileIn, mais avec
les rôles du démon et de la bibliothèque sont inversés.
longueur totale (tête + ret,
mais sans compter la longueur du mot lui-même,
et sans compter les morceaux)
struct guestfs_message_header (encodé en XDR)
struct guestfs_ _ret (encodé en XDR)
séquence de morceaux pour le paramètre FileOut #0
séquence de morceaux pour le paramètre FileOut #1 etc.
INITIALE MESSAGE
Lorsque le démon se lance, il envoie un mot initial ("GUESTFS_LAUNCH_FLAG") qui indique
que l'invité et le démon sont vivants. C'est ce que "guestfs_launch" attend.
PROGRESS NOTIFICATION MESSAGES
Le démon peut envoyer des messages de notification de progression à tout moment. Ceux-ci se distinguent
par le mot de longueur normale remplacé par "GUESTFS_PROGRESS_FLAG", suivi d'un
message de progression de la taille.
La bibliothèque les transforme en rappels de progression (voir "GUESTFS_EVENT_PROGRESS") s'il y a
un rappel enregistré, ou les ignore si ce n'est pas le cas.
Le démon limite automatiquement la fréquence des messages de progression qu'il envoie (voir
"daemon/proto.c:notify_progress"). Tous les appels ne génèrent pas de messages de progression.
FIXE APPAREIL
Lorsque libguestfs (ou les outils libguestfs) sont exécutés, ils recherchent un chemin à la recherche d'un
appareil. Le chemin est intégré à libguestfs ou peut être défini à l'aide du "LIBGUESTFS_PATH"
variable d'environnement.
Normalement, un appareil supermin se trouve sur ce chemin (voir "APPAREIL SUPERMIN" dans
supermine(1)). libguestfs reconstruit cela en une appliance complète en exécutant "supermin
--construire".
Cependant, un « appareil fixe » plus simple peut également être utilisé. libguestfs détecte cela en regardant
pour un répertoire sur le chemin contenant tous les fichiers suivants :
· kernel
· initrd
· racine
· README.fixé (notez qu'il must être présent aussi)
Si l'appliance fixe est trouvée, libguestfs ignore complètement supermin et exécute simplement le
machine virtuelle (utilisant qemu ou le backend actuel, voir "BACKEND") avec le noyau, initrd
et le disque racine de l'appliance fixe.
Ainsi l'appliance fixe peut être utilisée lorsqu'une plate-forme ou une distribution Linux ne
supermin de soutien. Vous construisez l'appliance fixe sur une plate-forme qui prend en charge supermin
en utilisant libguestfs-make-fixed-appliance(1), copiez-le et utilisez-le pour exécuter libguestfs.
Utilisez guestfs-internals en ligne en utilisant les services onworks.net