Ici, il est dit que vous pouvez réécrire un fichier exécutable et le processus se déroulera très bien - il sera relu au redémarrage d'un processus.
Cependant, lorsque j'essaie de remplacer un fichier binaire pendant que le processus est en cours (avec scp, du développeur au serveur de test), il dit «fichier occupé». Et si je remplace un fichier de bibliothèque partagée (* .so), tous les processus qui le lient se bloquent.
Pourquoi Suis-je en train de manquer quelque chose? Comment puis-je remplacer les fichiers binaires sans arrêter / planter un processus?
.so
fichier à l'aide deldd filename.so
pour vérifier les dépendancesstop app && create symlink of .so && start app
Réponses:
Comme mentionné dans Pourquoi un progiciel fonctionne-t-il très bien même lorsqu'il est mis à niveau? , le verrou est placé sur l'inode et non sur le nom de fichier. Lorsque vous chargez et exécutez un fichier binaire, le fichier est marqué comme occupé - c'est pourquoi vous obtenez une erreur ETXTBSY (fichier occupé) lorsque vous essayez d'écrire dessus.
Maintenant, pour les bibliothèques partagées, c'est légèrement différent: les bibliothèques obtiennent de la mémoire mappée dans l'espace d'adressage du processus avec
mmap()
. Bien que celaMAP_DENYWRITE
puisse être spécifié, au moins Glibc sur Linux l'ignore silencieusement (selon la page de manuel, n'hésitez pas à vérifier les sources) - vérifiez ce fil . Par conséquent, vous êtes réellement autorisé à écrire le fichier et, comme il est mappé en mémoire, toutes les modifications sont visibles presque immédiatement - ce qui signifie que si vous essayez assez fort, vous pouvez réussir à briquer votre machine en écrasant la bibliothèque.La bonne façon de mettre à jour est donc:
supprimer le fichier, ce qui supprime la référence aux données du système de fichiers, de sorte qu'il n'est pas accessible pour les applications nouvellement générées qui pourraient vouloir l'utiliser, tout en gardant les données accessibles pour toute personne qui les a déjà ouvertes (ou mappées) ;
créer un nouveau fichier avec un contenu mis à jour.
Les processus nouvellement créés utiliseront le contenu mis à jour, les applications en cours d'exécution accéderont à l'ancienne version. C'est ce que fait n'importe quel utilitaire de gestion de packages. Notez que ce n'est pas complètement sans danger - par exemple, les applications qui chargent dynamiquement du code (en utilisant
dlsym()
et amis) rencontreront des problèmes si l'API de la bibliothèque change silencieusement.Si vous voulez être vraiment sûr, arrêtez le système, montez le système de fichiers à partir d'une autre instance de système d'exploitation, mettez à jour et réactivez le système mis à jour.
la source
Une mise à niveau rpm fait de même - avec l'exécution de binaires et de bibliothèques alors que rien ne plante.
Alors, quelle est la difference:
Cela ne remplacera PAS le fichier sur place: l'inode faisant référence au binaire en cours d'utilisation est toujours "occupé" jusqu'à ce que le dernier objet le maintenant ouvert se termine. Le nouveau fichier sera créé avec un nouveau numéro d'inode.
Maintenant
scp
oucp
va essayer de remplacer le fichier sur place - ce qui changerait le contenu auquel l'inode fait référence. Cela ne fonctionne pas - comme vous l'avez décrit.la source